|
| 1 | +package embed |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "fmt" |
| 6 | + |
| 7 | + "github.com/rilldata/rill/cli/pkg/browser" |
| 8 | + "github.com/rilldata/rill/cli/pkg/cmdutil" |
| 9 | + adminv1 "github.com/rilldata/rill/proto/gen/rill/admin/v1" |
| 10 | + "github.com/spf13/cobra" |
| 11 | + "google.golang.org/protobuf/types/known/structpb" |
| 12 | +) |
| 13 | + |
| 14 | +func OpenCmd(ch *cmdutil.Helper) *cobra.Command { |
| 15 | + var branch string |
| 16 | + var ttlSeconds uint32 |
| 17 | + var userID string |
| 18 | + var userEmail string |
| 19 | + var userAttributes string |
| 20 | + var externalUserID string |
| 21 | + var resourceType string |
| 22 | + var resource string |
| 23 | + var theme string |
| 24 | + var themeMode string |
| 25 | + var navigation bool |
| 26 | + var query map[string]string |
| 27 | + var noOpen bool |
| 28 | + |
| 29 | + openCmd := &cobra.Command{ |
| 30 | + Use: "open <org> <project>", |
| 31 | + Args: cobra.ExactArgs(2), |
| 32 | + Short: "Open an embedded dashboard in the browser", |
| 33 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 34 | + org := args[0] |
| 35 | + project := args[1] |
| 36 | + |
| 37 | + req := &adminv1.GetIFrameRequest{ |
| 38 | + Org: org, |
| 39 | + Project: project, |
| 40 | + Branch: branch, |
| 41 | + TtlSeconds: ttlSeconds, |
| 42 | + ExternalUserId: externalUserID, |
| 43 | + Type: resourceType, |
| 44 | + Resource: resource, |
| 45 | + Theme: theme, |
| 46 | + ThemeMode: themeMode, |
| 47 | + Navigation: navigation, |
| 48 | + Query: query, |
| 49 | + SuperuserForceAccess: true, |
| 50 | + } |
| 51 | + |
| 52 | + // Set user identity: only one of user_id, user_email, or user_attributes can be specified. |
| 53 | + n := 0 |
| 54 | + if userID != "" { |
| 55 | + n++ |
| 56 | + req.For = &adminv1.GetIFrameRequest_UserId{UserId: userID} |
| 57 | + } |
| 58 | + if userEmail != "" { |
| 59 | + n++ |
| 60 | + req.For = &adminv1.GetIFrameRequest_UserEmail{UserEmail: userEmail} |
| 61 | + } |
| 62 | + if userAttributes != "" { |
| 63 | + n++ |
| 64 | + var attrs map[string]any |
| 65 | + if err := json.Unmarshal([]byte(userAttributes), &attrs); err != nil { |
| 66 | + return fmt.Errorf("invalid --user-attributes JSON: %w", err) |
| 67 | + } |
| 68 | + s, err := structpb.NewStruct(attrs) |
| 69 | + if err != nil { |
| 70 | + return fmt.Errorf("failed to parse --user-attributes: %w", err) |
| 71 | + } |
| 72 | + req.For = &adminv1.GetIFrameRequest_Attributes{Attributes: s} |
| 73 | + } |
| 74 | + if n > 1 { |
| 75 | + return fmt.Errorf("only one of --user-id, --user-email, or --user-attributes can be specified") |
| 76 | + } |
| 77 | + |
| 78 | + client, err := ch.Client() |
| 79 | + if err != nil { |
| 80 | + return err |
| 81 | + } |
| 82 | + |
| 83 | + res, err := client.GetIFrame(cmd.Context(), req) |
| 84 | + if err != nil { |
| 85 | + return err |
| 86 | + } |
| 87 | + |
| 88 | + if noOpen || !ch.Interactive { |
| 89 | + ch.Printf("Open browser at: %s\n", res.IframeSrc) |
| 90 | + } else { |
| 91 | + ch.Printf("Opening browser at: %s\n", res.IframeSrc) |
| 92 | + _ = browser.Open(res.IframeSrc) |
| 93 | + } |
| 94 | + |
| 95 | + return nil |
| 96 | + }, |
| 97 | + } |
| 98 | + |
| 99 | + openCmd.Flags().StringVar(&branch, "branch", "", "Branch to embed (defaults to the primary branch)") |
| 100 | + openCmd.Flags().Uint32Var(&ttlSeconds, "ttl-seconds", 0, "TTL for the access token in seconds") |
| 101 | + openCmd.Flags().StringVar(&userID, "user-id", "", "Rill user ID to assume") |
| 102 | + openCmd.Flags().StringVar(&userEmail, "user-email", "", "User email to assume") |
| 103 | + openCmd.Flags().StringVar(&userAttributes, "user-attributes", "", "User attributes as JSON (e.g. '{\"domain\":\"example.com\"}')") |
| 104 | + openCmd.Flags().StringVar(&externalUserID, "external-user-id", "", "External user ID for per-user state") |
| 105 | + openCmd.Flags().StringVar(&resourceType, "resource-type", "", "Type of resource to embed") |
| 106 | + openCmd.Flags().StringVar(&resource, "resource", "", "Name of the resource to embed") |
| 107 | + openCmd.Flags().StringVar(&theme, "theme", "", "Theme for the embedded resource") |
| 108 | + openCmd.Flags().StringVar(&themeMode, "theme-mode", "", "Theme mode") |
| 109 | + openCmd.Flags().BoolVar(&navigation, "navigation", false, "Enable navigation between resources") |
| 110 | + openCmd.Flags().StringToStringVar(&query, "query", nil, "Additional query parameters (key=value)") |
| 111 | + openCmd.Flags().BoolVar(&noOpen, "no-open", false, "Print the URL without opening the browser") |
| 112 | + |
| 113 | + return openCmd |
| 114 | +} |
0 commit comments