From d9187dd1fa79ea2bfbcb035491f4d00367345a27 Mon Sep 17 00:00:00 2001 From: Matias Frank Jensen Date: Sat, 23 Sep 2023 21:19:48 +0200 Subject: [PATCH] CLI: Refactor all Rig CLI to use Fx differently in conjunction with Cobra --- cmd/rig/cmd/auth/get.go | 9 +- cmd/rig/cmd/auth/get_auth_config.go | 14 +- cmd/rig/cmd/auth/login.go | 19 +- cmd/rig/cmd/auth/setup.go | 21 +- cmd/rig/cmd/base/auth.go | 3 +- cmd/rig/cmd/base/register.go | 77 ++-- cmd/rig/cmd/capsule/abort.go | 34 -- cmd/rig/cmd/capsule/build/setup.go | 68 ---- cmd/rig/cmd/capsule/builddeploy/common.go | 173 ++++++++ .../create.go => builddeploy/create_build.go} | 18 +- .../cmd/capsule/{ => builddeploy}/deploy.go | 226 ++--------- .../capsule/{ => builddeploy}/deploy_test.go | 2 +- .../get.go => builddeploy/get_build.go} | 9 +- cmd/rig/cmd/capsule/builddeploy/setup.go | 160 ++++++++ cmd/rig/cmd/capsule/common.go | 379 +----------------- cmd/rig/cmd/capsule/delete.go | 23 -- cmd/rig/cmd/capsule/env/get.go | 8 +- cmd/rig/cmd/capsule/env/remove.go | 10 +- cmd/rig/cmd/capsule/env/set.go | 10 +- cmd/rig/cmd/capsule/env/setup.go | 56 ++- cmd/rig/cmd/capsule/instance/get.go | 7 +- cmd/rig/cmd/capsule/instance/logs.go | 9 +- cmd/rig/cmd/capsule/instance/restart.go | 10 +- cmd/rig/cmd/capsule/instance/setup.go | 79 +++- cmd/rig/cmd/capsule/mount/get.go | 6 +- cmd/rig/cmd/capsule/mount/remove.go | 8 +- cmd/rig/cmd/capsule/mount/set.go | 7 +- cmd/rig/cmd/capsule/mount/setup.go | 72 +++- cmd/rig/cmd/capsule/network/configure.go | 7 +- cmd/rig/cmd/capsule/network/get.go | 7 +- cmd/rig/cmd/capsule/network/setup.go | 53 ++- cmd/rig/cmd/capsule/resource/get.go | 4 + cmd/rig/cmd/capsule/resource/scale.go | 4 + cmd/rig/cmd/capsule/resource/setup.go | 20 +- cmd/rig/cmd/capsule/rollout/events.go | 9 +- cmd/rig/cmd/capsule/rollout/get.go | 7 +- cmd/rig/cmd/capsule/rollout/setup.go | 65 ++- cmd/rig/cmd/capsule/root/abort.go | 33 ++ cmd/rig/cmd/capsule/{ => root}/config.go | 15 +- cmd/rig/cmd/capsule/{ => root}/create.go | 23 +- cmd/rig/cmd/capsule/root/delete.go | 22 + cmd/rig/cmd/capsule/{ => root}/get.go | 37 +- cmd/rig/cmd/capsule/root/setup.go | 203 ++++++++++ cmd/rig/cmd/capsule/setup.go | 140 ------- cmd/rig/cmd/cluster/getconfig.go | 7 +- cmd/rig/cmd/cluster/setup.go | 16 +- cmd/rig/cmd/config/init.go | 6 +- cmd/rig/cmd/config/setup.go | 19 +- cmd/rig/cmd/config/use_context.go | 7 +- cmd/rig/cmd/database/connect.go | 10 +- cmd/rig/cmd/database/create.go | 8 +- cmd/rig/cmd/database/create_credential.go | 10 +- cmd/rig/cmd/database/create_table.go | 10 +- cmd/rig/cmd/database/delete.go | 10 +- cmd/rig/cmd/database/delete_credential.go | 10 +- cmd/rig/cmd/database/delete_table.go | 10 +- cmd/rig/cmd/database/get.go | 8 +- cmd/rig/cmd/database/list.go | 7 +- cmd/rig/cmd/database/list_tables.go | 9 +- cmd/rig/cmd/database/setup.go | 35 +- cmd/rig/cmd/dev/kind/create.go | 28 +- cmd/rig/cmd/dev/kind/setup.go | 23 +- cmd/rig/cmd/dev/setup.go | 12 +- cmd/rig/cmd/group/create.go | 8 +- cmd/rig/cmd/group/delete.go | 10 +- cmd/rig/cmd/group/get.go | 8 +- cmd/rig/cmd/group/list.go | 7 +- cmd/rig/cmd/group/list_groups_for_user.go | 9 +- cmd/rig/cmd/group/list_members.go | 9 +- cmd/rig/cmd/group/setup.go | 28 +- cmd/rig/cmd/group/update.go | 9 +- cmd/rig/cmd/project/create.go | 17 +- cmd/rig/cmd/project/delete.go | 8 +- cmd/rig/cmd/project/get.go | 8 +- cmd/rig/cmd/project/get_settings.go | 8 +- cmd/rig/cmd/project/list.go | 8 +- cmd/rig/cmd/project/setup.go | 31 +- cmd/rig/cmd/project/update.go | 11 +- cmd/rig/cmd/project/update_settings.go | 11 +- cmd/rig/cmd/project/use_project.go | 26 +- cmd/rig/cmd/root.go | 80 ++-- cmd/rig/cmd/service_account/create.go | 8 +- cmd/rig/cmd/service_account/delete.go | 8 +- cmd/rig/cmd/service_account/list.go | 8 +- cmd/rig/cmd/service_account/setup.go | 20 +- cmd/rig/cmd/storage/copy.go | 42 +- cmd/rig/cmd/storage/create_bucket.go | 12 +- cmd/rig/cmd/storage/create_provider.go | 7 +- cmd/rig/cmd/storage/delete_bucket.go | 8 +- cmd/rig/cmd/storage/delete_object.go | 13 +- cmd/rig/cmd/storage/delete_provider.go | 10 +- cmd/rig/cmd/storage/get_bucket.go | 8 +- cmd/rig/cmd/storage/get_object.go | 8 +- cmd/rig/cmd/storage/get_provider.go | 8 +- cmd/rig/cmd/storage/list_providers.go | 7 +- cmd/rig/cmd/storage/ls.go | 9 +- cmd/rig/cmd/storage/setup.go | 38 +- cmd/rig/cmd/storage/unlink_bucket.go | 8 +- cmd/rig/cmd/user/add_member.go | 14 +- cmd/rig/cmd/user/create.go | 8 +- cmd/rig/cmd/user/delete.go | 10 +- cmd/rig/cmd/user/get.go | 8 +- cmd/rig/cmd/user/get_settings.go | 8 +- cmd/rig/cmd/user/list.go | 7 +- cmd/rig/cmd/user/list_sessions.go | 9 +- cmd/rig/cmd/user/migrate.go | 30 +- cmd/rig/cmd/user/remove_member.go | 14 +- cmd/rig/cmd/user/setup.go | 36 +- cmd/rig/cmd/user/update.go | 11 +- cmd/rig/cmd/user/update_settings.go | 14 +- cmd/rig/main.go | 14 +- 111 files changed, 1581 insertions(+), 1531 deletions(-) delete mode 100644 cmd/rig/cmd/capsule/abort.go delete mode 100644 cmd/rig/cmd/capsule/build/setup.go create mode 100644 cmd/rig/cmd/capsule/builddeploy/common.go rename cmd/rig/cmd/capsule/{build/create.go => builddeploy/create_build.go} (50%) rename cmd/rig/cmd/capsule/{ => builddeploy}/deploy.go (57%) rename cmd/rig/cmd/capsule/{ => builddeploy}/deploy_test.go (99%) rename cmd/rig/cmd/capsule/{build/get.go => builddeploy/get_build.go} (83%) create mode 100644 cmd/rig/cmd/capsule/builddeploy/setup.go delete mode 100644 cmd/rig/cmd/capsule/delete.go create mode 100644 cmd/rig/cmd/capsule/root/abort.go rename cmd/rig/cmd/capsule/{ => root}/config.go (77%) rename cmd/rig/cmd/capsule/{ => root}/create.go (89%) create mode 100644 cmd/rig/cmd/capsule/root/delete.go rename cmd/rig/cmd/capsule/{ => root}/get.go (63%) create mode 100644 cmd/rig/cmd/capsule/root/setup.go delete mode 100644 cmd/rig/cmd/capsule/setup.go diff --git a/cmd/rig/cmd/auth/get.go b/cmd/rig/cmd/auth/get.go index 482117b33..25e447688 100644 --- a/cmd/rig/cmd/auth/get.go +++ b/cmd/rig/cmd/auth/get.go @@ -1,21 +1,18 @@ package auth import ( - "context" "time" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/authentication" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" - "go.uber.org/zap" ) -func AuthGet(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client, cfg *cmd_config.Config, logger *zap.Logger) error { - res, err := nc.Authentication().Get(ctx, &connect.Request[authentication.GetRequest]{ +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + res, err := c.Rig.Authentication().Get(ctx, &connect.Request[authentication.GetRequest]{ Msg: &authentication.GetRequest{}, }) if err != nil { diff --git a/cmd/rig/cmd/auth/get_auth_config.go b/cmd/rig/cmd/auth/get_auth_config.go index 127c52d16..7c2d479b0 100644 --- a/cmd/rig/cmd/auth/get_auth_config.go +++ b/cmd/rig/cmd/auth/get_auth_config.go @@ -1,27 +1,23 @@ package auth import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/authentication" "github.com/rigdev/rig-go-api/api/v1/project" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/rigdev/rig/pkg/auth" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" - "go.uber.org/zap" ) -func AuthGetAuthConfig(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client, cfg *cmd_config.Config, logger *zap.Logger) error { +func (c Cmd) getAuthConfig(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var projectID uuid.UUID var err error if len(args) != 1 { - res, err := nc.Project().List(ctx, &connect.Request[project.ListRequest]{}) + res, err := c.Rig.Project().List(ctx, &connect.Request[project.ListRequest]{}) if err != nil { return err } @@ -46,7 +42,7 @@ func AuthGetAuthConfig(ctx context.Context, cmd *cobra.Command, args []string, n if id, err := uuid.Parse(args[0]); err == nil { projectID = id } else { - res, err := nc.Project().List(ctx, &connect.Request[project.ListRequest]{}) + res, err := c.Rig.Project().List(ctx, &connect.Request[project.ListRequest]{}) if err != nil { return err } @@ -74,7 +70,7 @@ func AuthGetAuthConfig(ctx context.Context, cmd *cobra.Command, args []string, n } } - res, err := nc.Authentication().GetAuthConfig(ctx, &connect.Request[authentication.GetAuthConfigRequest]{ + res, err := c.Rig.Authentication().GetAuthConfig(ctx, &connect.Request[authentication.GetAuthConfigRequest]{ Msg: &authentication.GetAuthConfigRequest{ RedirectAddr: redirectAddr, ProjectId: projectID.String(), diff --git a/cmd/rig/cmd/auth/login.go b/cmd/rig/cmd/auth/login.go index 36305d3c6..6f6daff49 100644 --- a/cmd/rig/cmd/auth/login.go +++ b/cmd/rig/cmd/auth/login.go @@ -7,17 +7,16 @@ import ( "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/authentication" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/rigdev/rig/pkg/auth" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" ) -func AuthLogin(ctx context.Context, cmd *cobra.Command, client rig.Client, cfg *cmd_config.Config) error { - res, err := loginWithRetry(ctx, client, authUserIdentifier, authPassword, auth.RigProjectID.String()) +func (c Cmd) login(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + res, err := c.loginWithRetry(ctx, authUserIdentifier, authPassword, auth.RigProjectID.String()) if err != nil { return err } @@ -27,10 +26,10 @@ func AuthLogin(ctx context.Context, cmd *cobra.Command, client rig.Client, cfg * return err } - cfg.GetCurrentAuth().UserID = uid - cfg.GetCurrentAuth().AccessToken = res.Msg.GetToken().GetAccessToken() - cfg.GetCurrentAuth().RefreshToken = res.Msg.GetToken().GetRefreshToken() - if err := cfg.Save(); err != nil { + c.Cfg.GetCurrentAuth().UserID = uid + c.Cfg.GetCurrentAuth().AccessToken = res.Msg.GetToken().GetAccessToken() + c.Cfg.GetCurrentAuth().RefreshToken = res.Msg.GetToken().GetRefreshToken() + if err := c.Cfg.Save(); err != nil { return err } @@ -39,7 +38,7 @@ func AuthLogin(ctx context.Context, cmd *cobra.Command, client rig.Client, cfg * return nil } -func loginWithRetry(ctx context.Context, client rig.Client, identifierStr, password, project string) (*connect.Response[authentication.LoginResponse], error) { +func (c Cmd) loginWithRetry(ctx context.Context, identifierStr, password, project string) (*connect.Response[authentication.LoginResponse], error) { shouldPromptIdentifier := identifierStr == "" shouldPromptPassword := password == "" var identifier *model.UserIdentifier @@ -61,7 +60,7 @@ func loginWithRetry(ctx context.Context, client rig.Client, identifierStr, passw } } - res, err := client.Authentication().Login(ctx, &connect.Request[authentication.LoginRequest]{ + res, err := c.Rig.Authentication().Login(ctx, &connect.Request[authentication.LoginRequest]{ Msg: &authentication.LoginRequest{ Method: &authentication.LoginRequest_UserPassword{ UserPassword: &authentication.UserPassword{ diff --git a/cmd/rig/cmd/auth/setup.go b/cmd/rig/cmd/auth/setup.go index cbd217d51..676f4e9e7 100644 --- a/cmd/rig/cmd/auth/setup.go +++ b/cmd/rig/cmd/auth/setup.go @@ -1,8 +1,13 @@ package auth import ( + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -13,7 +18,15 @@ var ( var outputJSON bool -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { auth := &cobra.Command{ Use: "auth", Short: "Manage authentication for the current user", @@ -27,7 +40,7 @@ func Setup(parent *cobra.Command) { base.OmitUser: "", base.OmitProject: "", }, - RunE: base.Register(AuthLogin), + RunE: c.login, } login.Flags().StringVarP(&authUserIdentifier, "user", "u", "", "useridentifier [username | email | phone number]") login.Flags().StringVarP(&authPassword, "password", "p", "", "password of the user") @@ -37,7 +50,7 @@ func Setup(parent *cobra.Command) { Use: "get", Short: "Get user information associated with the current user", Args: cobra.NoArgs, - RunE: base.Register(AuthGet), + RunE: c.get, Annotations: map[string]string{ base.OmitProject: "", }, @@ -49,7 +62,7 @@ func Setup(parent *cobra.Command) { Use: "get-auth-config {project-id | project-name}", Short: "Get the authorization config with allowed login methods and configurations", Args: cobra.MaximumNArgs(1), - RunE: base.Register(AuthGetAuthConfig), + RunE: c.getAuthConfig, Annotations: map[string]string{ base.OmitProject: "", }, diff --git a/cmd/rig/cmd/base/auth.go b/cmd/rig/cmd/base/auth.go index dda15b48b..7aade5671 100644 --- a/cmd/rig/cmd/base/auth.go +++ b/cmd/rig/cmd/base/auth.go @@ -16,7 +16,6 @@ import ( "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" - "go.uber.org/zap" ) var ( @@ -24,7 +23,7 @@ var ( OmitProject = "OMIT_PROJECT" ) -func CheckAuth(cmd *cobra.Command, rc rig.Client, cfg *cmd_config.Config, logger *zap.Logger) error { +func CheckAuth(cmd *cobra.Command, rc rig.Client, cfg *cmd_config.Config) error { ctx := context.Background() if _, ok := cmd.Annotations[OmitUser]; ok { return nil diff --git a/cmd/rig/cmd/base/register.go b/cmd/rig/cmd/base/register.go index a6d686cd5..15e0cb296 100644 --- a/cmd/rig/cmd/base/register.go +++ b/cmd/rig/cmd/base/register.go @@ -6,70 +6,43 @@ import ( "github.com/docker/docker/client" "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" - "github.com/spf13/cobra" - "go.uber.org/dig" "go.uber.org/fx" "go.uber.org/zap" ) -var _options []fx.Option - -func AddOptions(opts ...fx.Option) { - _options = append(_options, opts...) -} - -func Register(f interface{}) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - cfg, err := cmd_config.NewConfig("") - if err != nil { - return err - } - - f := fx.New( - clientModule, - fx.Supply(cfg), - fx.Supply(cmd), - fx.Supply(args), - fx.Provide(zap.NewDevelopment), - fx.Provide(getContext), - fx.Provide(func(c *cmd_config.Context) *cmd_config.Auth { - return c.GetAuth() - }), - fx.Provide(func(c *cmd_config.Context) *cmd_config.Service { - return c.GetService() - }), - fx.Provide(func() context.Context { return context.Background() }), - fx.Options(_options...), - fx.Provide(func() (*client.Client, error) { - return client.NewClientWithOpts( - client.WithHostFromEnv(), - client.WithAPIVersionNegotiation(), - ) - }), - fx.Invoke(CheckAuth), - fx.Invoke(f), - fx.NopLogger, +var Module = fx.Module( + "rig-cli", + fx.NopLogger, + clientModule, + fx.Provide(func() (*cmd_config.Config, error) { + return cmd_config.NewConfig("") + }), + fx.Provide(zap.NewDevelopment), + fx.Provide(getContext), + fx.Provide(func(c *cmd_config.Context) *cmd_config.Auth { + return c.GetAuth() + }), + fx.Provide(func(c *cmd_config.Context) *cmd_config.Service { + return c.GetService() + }), + fx.Provide(func() context.Context { return context.Background() }), + fx.Provide(func() (*client.Client, error) { + return client.NewClientWithOpts( + client.WithHostFromEnv(), + client.WithAPIVersionNegotiation(), ) + }), +) - if err := f.Start(context.Background()); err != nil { - return dig.RootCause(err) - } - if err := f.Stop(context.Background()); err != nil { - return dig.RootCause(err) - } - return dig.RootCause(f.Err()) - } -} - -func getContext(cfg *cmd_config.Config, cmd *cobra.Command) (*cmd_config.Context, error) { +func getContext(cfg *cmd_config.Config) (*cmd_config.Context, error) { if cfg.CurrentContextName == "" { if len(cfg.Contexts) > 0 { - cmd.Println("No context selected, please select one") + fmt.Println("No context selected, please select one") if err := cmd_config.SelectContext(cfg); err != nil { return nil, err } } else { - cmd.Println("No context available, please create one") + fmt.Println("No context available, please create one") if err := cmd_config.CreateDefaultContext(cfg); err != nil { return nil, err } diff --git a/cmd/rig/cmd/capsule/abort.go b/cmd/rig/cmd/capsule/abort.go deleted file mode 100644 index 54604b971..000000000 --- a/cmd/rig/cmd/capsule/abort.go +++ /dev/null @@ -1,34 +0,0 @@ -package capsule - -import ( - "context" - - "github.com/bufbuild/connect-go" - "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" - "github.com/spf13/cobra" -) - -func abort(ctx context.Context, cmd *cobra.Command, nc rig.Client) error { - c, err := nc.Capsule().Get(ctx, &connect.Request[capsule.GetRequest]{ - Msg: &capsule.GetRequest{ - CapsuleId: CapsuleID, - }, - }) - if err != nil { - return err - } - - if _, err := nc.Capsule().AbortRollout(ctx, &connect.Request[capsule.AbortRolloutRequest]{ - Msg: &capsule.AbortRolloutRequest{ - CapsuleId: CapsuleID, - RolloutId: c.Msg.GetCapsule().GetCurrentRollout(), - }, - }); err != nil { - return err - } - - cmd.Println("Current rollout aborted") - - return nil -} diff --git a/cmd/rig/cmd/capsule/build/setup.go b/cmd/rig/cmd/capsule/build/setup.go deleted file mode 100644 index 97693f47a..000000000 --- a/cmd/rig/cmd/capsule/build/setup.go +++ /dev/null @@ -1,68 +0,0 @@ -package build - -import ( - "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" - "github.com/rigdev/rig/cmd/rig/cmd/capsule" - "github.com/spf13/cobra" -) - -var ( - offset int - limit int -) - -var ( - outputJSON bool - deploy bool - skipImageCheck bool - remote bool -) - -var ( - image string -) - -func Setup(parent *cobra.Command) *cobra.Command { - build := &cobra.Command{ - Use: "build", - Short: "Manage builds of the capsule", - } - - buildCreate := &cobra.Command{ - Use: "create", - Short: "Create a new build with the given image", - Args: cobra.NoArgs, - RunE: base.Register(create), - ValidArgsFunction: common.NoCompletions, - } - buildCreate.Flags().StringVarP(&image, "image", "i", "", "image to use for the build") - buildCreate.Flags().BoolVarP(&deploy, "deploy", "d", false, "deploy build after successful creation") - buildCreate.Flags().BoolVarP(&skipImageCheck, "skip-image-check", "s", false, "skip validating that the docker image exists") - buildCreate.Flags().BoolVarP(&remote, "remote", "r", false, "Rig will not look for the image locally but assumes it from a remote registry. If not set, Rig will search locally and then remotely") - - buildCreate.RegisterFlagCompletionFunc("image", common.NoCompletions) - buildCreate.RegisterFlagCompletionFunc("deploy", common.BoolCompletions) - buildCreate.RegisterFlagCompletionFunc("skip-image-check", common.BoolCompletions) - buildCreate.RegisterFlagCompletionFunc("remote", common.BoolCompletions) - build.AddCommand(buildCreate) - - buildGet := &cobra.Command{ - Use: "get [build-id]", - Short: "Get one or multiple builds", - Args: cobra.MaximumNArgs(1), - RunE: base.Register(get), - ValidArgsFunction: common.Complete(capsule.BuildCompletions, common.MaxArgsCompletionFilter(1)), - } - buildGet.Flags().IntVarP(&offset, "offset", "o", 0, "offset") - buildGet.Flags().IntVarP(&limit, "limit", "l", 10, "limit") - buildGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") - buildGet.RegisterFlagCompletionFunc("json", common.BoolCompletions) - buildGet.RegisterFlagCompletionFunc("offset", common.NoCompletions) - buildGet.RegisterFlagCompletionFunc("limit", common.NoCompletions) - build.AddCommand(buildGet) - - parent.AddCommand(build) - - return build -} diff --git a/cmd/rig/cmd/capsule/builddeploy/common.go b/cmd/rig/cmd/capsule/builddeploy/common.go new file mode 100644 index 000000000..bbfccbf33 --- /dev/null +++ b/cmd/rig/cmd/capsule/builddeploy/common.go @@ -0,0 +1,173 @@ +package builddeploy + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/bufbuild/connect-go" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/rigdev/rig-go-api/api/v1/capsule" + "github.com/rigdev/rig/cmd/common" + "github.com/rigdev/rig/pkg/errors" + "github.com/rigdev/rig/pkg/ptr" + "github.com/rigdev/rig/pkg/utils" + "golang.org/x/exp/slices" +) + +type imageRef struct { + Image string + // &true: we know it's local + // &false: we know it's remote + // nil: we don't know + IsKnownLocal *bool +} + +func imageRefFromFlags() imageRef { + imageRef := imageRef{ + Image: image, + IsKnownLocal: nil, + } + if remote { + imageRef.IsKnownLocal = ptr.New(false) + } + return imageRef +} + +func (c Cmd) promptForImage(ctx context.Context) (imageRef, error) { + var empty imageRef + + ok, err := common.PromptConfirm("Use a local image?", true) + if err != nil { + return empty, err + } + + if ok { + img, err := c.getDaemonImage(ctx) + if err != nil { + return empty, err + } + return imageRef{ + Image: img.tag, + IsKnownLocal: ptr.New(true), + }, nil + } + + image, err = common.PromptInput("Enter image:", common.ValidateImageOpt) + if err != nil { + return empty, nil + } + return imageRef{ + Image: image, + IsKnownLocal: ptr.New(false), + }, nil +} + +func (c Cmd) getDaemonImage(ctx context.Context) (*imageInfo, error) { + images, prompts, err := c.getImagePrompts(ctx, "") + if err != nil { + return nil, err + } + + if len(images) == 0 { + return nil, errors.New("no local docker images found") + } + idx, err := common.PromptTableSelect("Select image:", prompts, []string{"Image name", "Age"}, common.SelectEnableFilterOpt) + if err != nil { + return nil, err + } + return &images[idx], nil +} + +func (c Cmd) getImagePrompts(ctx context.Context, filter string) ([]imageInfo, [][]string, error) { + res, err := c.DockerClient.ImageList(ctx, types.ImageListOptions{ + Filters: filters.NewArgs(filters.Arg("dangling", "false")), + }) + if err != nil { + return nil, nil, err + } + + var images []imageInfo + var prompts [][]string + + for _, image := range res { + for _, tag := range image.RepoTags { + t := time.Unix(image.Created, 0) + ii, _, err := c.DockerClient.ImageInspectWithRaw(ctx, tag) + if err != nil { + return nil, nil, err + } + if !ii.Metadata.LastTagTime.IsZero() { + t = ii.Metadata.LastTagTime + } + images = append(images, imageInfo{ + tag: tag, + created: t, + }) + } + } + + slices.SortFunc(images, func(i, j imageInfo) bool { + return i.created.After(j.created) + }) + + for idx, image := range images { + if idx >= 50 { + break + } + t := time.Since(image.created) + prompts = append(prompts, []string{image.tag, common.FormatDuration(t)}) + } + return images, prompts, nil +} + +type imageInfo struct { + tag string + created time.Time +} + +func (c Cmd) createBuildInner(ctx context.Context, capsuleID string, imageRef imageRef) (string, error) { + if strings.Contains(imageRef.Image, "@") { + return "", errors.UnimplementedErrorf("referencing images by digest is not yet supported") + } + + var err error + var isLocalImage bool + if imageRef.IsKnownLocal == nil { + isLocalImage, _, err = utils.ImageExistsNatively(ctx, c.DockerClient, imageRef.Image) + if err != nil { + return "", err + } + } else { + isLocalImage = *imageRef.IsKnownLocal + } + + var digest string + if isLocalImage { + imageRef.Image, digest, err = c.pushLocalImageToDevRegistry(ctx, imageRef.Image) + if err != nil { + return "", err + } + } + + res, err := c.Rig.Capsule().CreateBuild(ctx, &connect.Request[capsule.CreateBuildRequest]{ + Msg: &capsule.CreateBuildRequest{ + CapsuleId: capsuleID, + Image: imageRef.Image, + Digest: digest, + }, + }) + if err != nil { + return "", err + } + + if res.Msg.GetCreatedNewBuild() { + fmt.Println("Created new build:", res.Msg.GetBuildId()) + } else { + fmt.Println("Build already exists, using existing build") + } + + return res.Msg.GetBuildId(), nil +} diff --git a/cmd/rig/cmd/capsule/build/create.go b/cmd/rig/cmd/capsule/builddeploy/create_build.go similarity index 50% rename from cmd/rig/cmd/capsule/build/create.go rename to cmd/rig/cmd/capsule/builddeploy/create_build.go index 55ab377cf..245730508 100644 --- a/cmd/rig/cmd/capsule/build/create.go +++ b/cmd/rig/cmd/capsule/builddeploy/create_build.go @@ -1,29 +1,25 @@ -package build +package builddeploy import ( - "context" - "github.com/bufbuild/connect-go" - "github.com/docker/docker/client" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" cmd_capsule "github.com/rigdev/rig/cmd/rig/cmd/capsule" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" ) -func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client, cfg *cmd_config.Config, dockerClient *client.Client) error { +func (c Cmd) createBuild(cmd *cobra.Command, args []string) error { var err error + ctx := c.Ctx - imageRef := cmd_capsule.ImageRefFromFlags() + imageRef := imageRefFromFlags() if image == "" { - imageRef, err = cmd_capsule.PromptForImage(ctx, dockerClient) + imageRef, err = c.promptForImage(ctx) if err != nil { return err } } - buildID, err := cmd_capsule.CreateBuild(ctx, nc, cmd_capsule.CapsuleID, dockerClient, imageRef) + buildID, err := c.createBuildInner(ctx, cmd_capsule.CapsuleID, imageRef) if err != nil { return err } @@ -32,7 +28,7 @@ func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clien return nil } - if _, err := nc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: cmd_capsule.CapsuleID, Changes: []*capsule.Change{{ diff --git a/cmd/rig/cmd/capsule/deploy.go b/cmd/rig/cmd/capsule/builddeploy/deploy.go similarity index 57% rename from cmd/rig/cmd/capsule/deploy.go rename to cmd/rig/cmd/capsule/builddeploy/deploy.go index 3fe14622c..79fe4a6a9 100644 --- a/cmd/rig/cmd/capsule/deploy.go +++ b/cmd/rig/cmd/capsule/builddeploy/deploy.go @@ -1,4 +1,4 @@ -package capsule +package builddeploy import ( "context" @@ -10,37 +10,29 @@ import ( "github.com/bufbuild/connect-go" "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/client" container_name "github.com/google/go-containerregistry/pkg/name" "github.com/jedib0t/go-pretty/v6/progress" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/api/v1/cluster" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/cmd/rig/cmd/base" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" - "github.com/rigdev/rig/pkg/ptr" - "github.com/rigdev/rig/pkg/utils" "github.com/spf13/cobra" "golang.org/x/exp/slices" ) -type imageInfo struct { - tag string - created time.Time -} - -func deploy(ctx context.Context, cmd *cobra.Command, args []string, rc rig.Client, dc *client.Client) error { - buildID, err := getBuildID(ctx, CapsuleID, rc, dc) +func (c Cmd) deploy(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + buildID, err := c.getBuildID(ctx, capsule_cmd.CapsuleID) if err != nil { return err } - res, err := rc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + res, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ - CapsuleId: CapsuleID, + CapsuleId: capsule_cmd.CapsuleID, Changes: []*capsule.Change{{ Field: &capsule.Change_BuildId{BuildId: buildID}, }}, @@ -50,17 +42,17 @@ func deploy(ctx context.Context, cmd *cobra.Command, args []string, rc rig.Clien return err } cmd.Printf("Deploying build %v in rollout %v \n", buildID, res.Msg.GetRolloutId()) - return listenForEvents(ctx, res.Msg.GetRolloutId(), rc, CapsuleID, cmd) + return c.listenForEvents(ctx, res.Msg.GetRolloutId(), capsule_cmd.CapsuleID) } -func getBuildID(ctx context.Context, capsuleID string, rc rig.Client, dc *client.Client) (string, error) { +func (c Cmd) getBuildID(ctx context.Context, capsuleID string) (string, error) { if buildID != "" && image != "" { return "", errors.New("not both --build-id and --image can be given") } if buildID != "" { // TODO Figure out pagination - resp, err := rc.Capsule().ListBuilds(ctx, connect.NewRequest(&capsule.ListBuildsRequest{ + resp, err := c.Rig.Capsule().ListBuilds(ctx, connect.NewRequest(&capsule.ListBuildsRequest{ CapsuleId: capsuleID, Pagination: &model.Pagination{ Offset: 0, @@ -76,10 +68,10 @@ func getBuildID(ctx context.Context, capsuleID string, rc rig.Client, dc *client } if image != "" { - return CreateBuild(ctx, rc, capsuleID, dc, ImageRefFromFlags()) + return c.createBuildInner(ctx, capsuleID, imageRefFromFlags()) } - return promptForImageOrBuild(ctx, capsuleID, rc, dc) + return c.promptForImageOrBuild(ctx, capsuleID) } func expandBuildID(ctx context.Context, builds []*capsule.Build, buildID string) (string, error) { @@ -171,177 +163,27 @@ func isHexString(s string) bool { return true } -type ImageRef struct { - image string - // &true: we know it's local - // &false: we know it's remote - // nil: we don't know - isKnownLocal *bool -} - -func ImageRefFromFlags() ImageRef { - imageRef := ImageRef{ - image: image, - isKnownLocal: nil, - } - if remote { - imageRef.isKnownLocal = ptr.New(false) - } - return imageRef -} - -func CreateBuild(ctx context.Context, rc rig.Client, capsuleID string, dc *client.Client, imageRef ImageRef) (string, error) { - if strings.Contains(imageRef.image, "@") { - return "", errors.UnimplementedErrorf("referencing images by digest is not yet supported") - } - - var err error - var isLocalImage bool - if imageRef.isKnownLocal == nil { - isLocalImage, _, err = utils.ImageExistsNatively(ctx, dc, imageRef.image) - if err != nil { - return "", err - } - } else { - isLocalImage = *imageRef.isKnownLocal - } - - var digest string - if isLocalImage { - imageRef.image, digest, err = pushLocalImageToDevRegistry(ctx, imageRef.image, rc, dc) - if err != nil { - return "", err - } - } - - res, err := rc.Capsule().CreateBuild(ctx, &connect.Request[capsule.CreateBuildRequest]{ - Msg: &capsule.CreateBuildRequest{ - CapsuleId: capsuleID, - Image: imageRef.image, - Digest: digest, - }, - }) - if err != nil { - return "", err - } - - if res.Msg.GetCreatedNewBuild() { - fmt.Println("Created new build:", res.Msg.GetBuildId()) - } else { - fmt.Println("Build already exists, using existing build") - } - - return res.Msg.GetBuildId(), nil -} - -func promptForImageOrBuild(ctx context.Context, capsuleID string, rc rig.Client, dc *client.Client) (string, error) { +func (c Cmd) promptForImageOrBuild(ctx context.Context, capsuleID string) (string, error) { i, _, err := common.PromptSelect("Deploy from docker image or existing rig build?", []string{"Image", "Build"}) if err != nil { return "", err } switch i { case 0: - imgRef, err := PromptForImage(ctx, dc) + imgRef, err := c.promptForImage(ctx) if err != nil { return "", err } - return CreateBuild(ctx, rc, capsuleID, dc, imgRef) + return c.createBuildInner(ctx, capsuleID, imgRef) case 1: - return promptForExistingBuild(ctx, capsuleID, rc) + return c.promptForExistingBuild(ctx, capsuleID) default: return "", errors.New("something went wrong") } } -func PromptForImage(ctx context.Context, dc *client.Client) (ImageRef, error) { - var empty ImageRef - - ok, err := common.PromptConfirm("Use a local image?", true) - if err != nil { - return empty, err - } - - if ok { - img, err := getDaemonImage(ctx, dc) - if err != nil { - return empty, err - } - return ImageRef{ - image: img.tag, - isKnownLocal: ptr.New(true), - }, nil - } - - image, err = common.PromptInput("Enter image:", common.ValidateImageOpt) - if err != nil { - return empty, nil - } - return ImageRef{ - image: image, - isKnownLocal: ptr.New(false), - }, nil -} - -func getDaemonImage(ctx context.Context, dc *client.Client) (*imageInfo, error) { - images, prompts, err := getImagePrompts(ctx, dc, "") - if err != nil { - return nil, err - } - - if len(images) == 0 { - return nil, errors.New("no local docker images found") - } - idx, err := common.PromptTableSelect("Select image:", prompts, []string{"Image name", "Age"}, common.SelectEnableFilterOpt) - if err != nil { - return nil, err - } - return &images[idx], nil -} - -func getImagePrompts(ctx context.Context, dc *client.Client, filter string) ([]imageInfo, [][]string, error) { - res, err := dc.ImageList(ctx, types.ImageListOptions{ - Filters: filters.NewArgs(filters.Arg("dangling", "false")), - }) - if err != nil { - return nil, nil, err - } - - var images []imageInfo - var prompts [][]string - - for _, image := range res { - for _, tag := range image.RepoTags { - t := time.Unix(image.Created, 0) - ii, _, err := dc.ImageInspectWithRaw(ctx, tag) - if err != nil { - return nil, nil, err - } - if !ii.Metadata.LastTagTime.IsZero() { - t = ii.Metadata.LastTagTime - } - images = append(images, imageInfo{ - tag: tag, - created: t, - }) - } - } - - slices.SortFunc(images, func(i, j imageInfo) bool { - return i.created.After(j.created) - }) - - for idx, image := range images { - if idx >= 50 { - break - } - t := time.Since(image.created) - prompts = append(prompts, []string{image.tag, common.FormatDuration(t)}) - } - return images, prompts, nil -} - -func promptForExistingBuild(ctx context.Context, capsuleID string, rc rig.Client) (string, error) { - resp, err := rc.Capsule().ListBuilds(ctx, connect.NewRequest(&capsule.ListBuildsRequest{ +func (c Cmd) promptForExistingBuild(ctx context.Context, capsuleID string) (string, error) { + resp, err := c.Rig.Capsule().ListBuilds(ctx, connect.NewRequest(&capsule.ListBuildsRequest{ CapsuleId: capsuleID, Pagination: &model.Pagination{}, })) @@ -353,11 +195,15 @@ func promptForExistingBuild(ctx context.Context, capsuleID string, rc rig.Client return b1.CreatedAt.AsTime().After(b2.CreatedAt.AsTime()) }) + if len(builds) == 0 { + return "", errors.New("capsule has no builds") + } + var rows [][]string for _, b := range builds { rows = append(rows, []string{ fmt.Sprint(b.GetRepository(), ":", b.GetTag()), - TruncatedFixed(b.GetDigest(), 19), + capsule_cmd.TruncatedFixed(b.GetDigest(), 19), common.FormatDuration(time.Since(b.GetCreatedAt().AsTime())), }) } @@ -375,10 +221,10 @@ func promptForExistingBuild(ctx context.Context, capsuleID string, rc rig.Client return builds[idx].GetBuildId(), nil } -func listenForEvents(ctx context.Context, rolloutID uint64, rc rig.Client, capsuleID string, cmd *cobra.Command) error { +func (c Cmd) listenForEvents(ctx context.Context, rolloutID uint64, capsuleID string) error { eventCount := 0 for { - res, err := rc.Capsule().GetRollout(ctx, &connect.Request[capsule.GetRolloutRequest]{ + res, err := c.Rig.Capsule().GetRollout(ctx, &connect.Request[capsule.GetRolloutRequest]{ Msg: &capsule.GetRolloutRequest{ CapsuleId: capsuleID, RolloutId: rolloutID, @@ -388,7 +234,7 @@ func listenForEvents(ctx context.Context, rolloutID uint64, rc rig.Client, capsu return err } - eventRes, err := rc.Capsule().ListEvents(ctx, &connect.Request[capsule.ListEventsRequest]{ + eventRes, err := c.Rig.Capsule().ListEvents(ctx, &connect.Request[capsule.ListEventsRequest]{ Msg: &capsule.ListEventsRequest{ CapsuleId: capsuleID, RolloutId: rolloutID, @@ -401,19 +247,19 @@ func listenForEvents(ctx context.Context, rolloutID uint64, rc rig.Client, capsu return err } for _, event := range eventRes.Msg.GetEvents() { - cmd.Printf("[%v] %v\n", event.GetCreatedAt().AsTime().Format(base.RFC3339MilliFixed), event.GetMessage()) + fmt.Printf("[%v] %v\n", event.GetCreatedAt().AsTime().Format(base.RFC3339MilliFixed), event.GetMessage()) } eventCount += len(eventRes.Msg.GetEvents()) switch res.Msg.GetRollout().GetStatus().GetState() { case capsule.RolloutState_ROLLOUT_STATE_DONE: - cmd.Printf("[%v] %v\n", time.Now().UTC().Format(time.RFC822), "Deployment complete") + fmt.Printf("[%v] %v\n", time.Now().UTC().Format(time.RFC822), "Deployment complete") return nil case capsule.RolloutState_ROLLOUT_STATE_FAILED: - cmd.Printf("[%v] %v\n", time.Now().UTC().Format(time.RFC822), "Deployment failed") + fmt.Printf("[%v] %v\n", time.Now().UTC().Format(time.RFC822), "Deployment failed") return nil case capsule.RolloutState_ROLLOUT_STATE_ABORTED: - cmd.Printf("[%v] %v\n", time.Now().UTC().Format(time.RFC822), "Deployment aborted") + fmt.Printf("[%v] %v\n", time.Now().UTC().Format(time.RFC822), "Deployment aborted") return nil } @@ -421,8 +267,8 @@ func listenForEvents(ctx context.Context, rolloutID uint64, rc rig.Client, capsu } } -func pushLocalImageToDevRegistry(ctx context.Context, image string, client rig.Client, dc *client.Client) (string, string, error) { - resp, err := client.Cluster().GetConfig(ctx, connect.NewRequest(&cluster.GetConfigRequest{})) +func (c Cmd) pushLocalImageToDevRegistry(ctx context.Context, image string) (string, string, error) { + resp, err := c.Rig.Cluster().GetConfig(ctx, connect.NewRequest(&cluster.GetConfigRequest{})) if err != nil { return "", "", err } @@ -444,11 +290,11 @@ func pushLocalImageToDevRegistry(ctx context.Context, image string, client rig.C fmt.Printf("Pushing the image to the dev docker registry under the new name %q\n", newImageName) - if err := dc.ImageTag(ctx, image, newImageName); err != nil { + if err := c.DockerClient.ImageTag(ctx, image, newImageName); err != nil { return "", "", err } - digest, err := pushToDevRegistry(ctx, dc, newImageName, devRegistry.Host) + digest, err := c.pushToDevRegistry(ctx, newImageName, devRegistry.Host) if err != nil { return "", "", err } @@ -470,7 +316,7 @@ func makeDevRegistryImageName(image string, devRegistryHost string) (string, err return tag.String(), nil } -func pushToDevRegistry(ctx context.Context, dc *client.Client, image string, host string) (string, error) { +func (c Cmd) pushToDevRegistry(ctx context.Context, image string, host string) (string, error) { ac := registry.AuthConfig{ ServerAddress: host, } @@ -479,7 +325,7 @@ func pushToDevRegistry(ctx context.Context, dc *client.Client, image string, hos return "", err } - rc, err := dc.ImagePush(ctx, image, types.ImagePushOptions{ + rc, err := c.DockerClient.ImagePush(ctx, image, types.ImagePushOptions{ RegistryAuth: base64.StdEncoding.EncodeToString(secret), }) if err != nil { diff --git a/cmd/rig/cmd/capsule/deploy_test.go b/cmd/rig/cmd/capsule/builddeploy/deploy_test.go similarity index 99% rename from cmd/rig/cmd/capsule/deploy_test.go rename to cmd/rig/cmd/capsule/builddeploy/deploy_test.go index 6ee5a8a00..3efbc3814 100644 --- a/cmd/rig/cmd/capsule/deploy_test.go +++ b/cmd/rig/cmd/capsule/builddeploy/deploy_test.go @@ -1,4 +1,4 @@ -package capsule +package builddeploy import ( "context" diff --git a/cmd/rig/cmd/capsule/build/get.go b/cmd/rig/cmd/capsule/builddeploy/get_build.go similarity index 83% rename from cmd/rig/cmd/capsule/build/get.go rename to cmd/rig/cmd/capsule/builddeploy/get_build.go index 125a858ac..e1fe78a5c 100644 --- a/cmd/rig/cmd/capsule/build/get.go +++ b/cmd/rig/cmd/capsule/builddeploy/get_build.go @@ -1,7 +1,6 @@ -package build +package builddeploy import ( - "context" "fmt" "time" @@ -9,14 +8,14 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func get(ctx context.Context, cmd *cobra.Command, nc rig.Client) error { - resp, err := nc.Capsule().ListBuilds(ctx, &connect.Request[capsule.ListBuildsRequest]{ +func (c Cmd) getBuild(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.Capsule().ListBuilds(ctx, &connect.Request[capsule.ListBuildsRequest]{ Msg: &capsule.ListBuildsRequest{ CapsuleId: capsule_cmd.CapsuleID, Pagination: &model.Pagination{ diff --git a/cmd/rig/cmd/capsule/builddeploy/setup.go b/cmd/rig/cmd/capsule/builddeploy/setup.go new file mode 100644 index 000000000..c14d36e58 --- /dev/null +++ b/cmd/rig/cmd/capsule/builddeploy/setup.go @@ -0,0 +1,160 @@ +package builddeploy + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/bufbuild/connect-go" + "github.com/docker/docker/client" + capsule_api "github.com/rigdev/rig-go-api/api/v1/capsule" + "github.com/rigdev/rig-go-sdk" + "github.com/rigdev/rig/cmd/common" + "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" + "github.com/spf13/cobra" + "go.uber.org/fx" +) + +var ( + offset int + limit int +) + +var ( + outputJSON bool + deploy bool + skipImageCheck bool + remote bool +) + +var ( + image string + buildID string +) + +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config + DockerClient *client.Client +} + +func (c Cmd) Setup(parent *cobra.Command) { + c.setupBuild(parent) + c.setupDeploy(parent) +} + +func (c Cmd) setupBuild(parent *cobra.Command) { + build := &cobra.Command{ + Use: "build", + Short: "Manage builds of the capsule", + } + + buildCreate := &cobra.Command{ + Use: "create", + Short: "Create a new build with the given image", + Args: cobra.NoArgs, + RunE: c.createBuild, + ValidArgsFunction: common.NoCompletions, + } + buildCreate.Flags().StringVarP(&image, "image", "i", "", "image to use for the build") + buildCreate.Flags().BoolVarP(&deploy, "deploy", "d", false, "deploy build after successful creation") + buildCreate.Flags().BoolVarP(&skipImageCheck, "skip-image-check", "s", false, "skip validating that the docker image exists") + buildCreate.Flags().BoolVarP(&remote, "remote", "r", false, "Rig will not look for the image locally but assumes it from a remote registry. If not set, Rig will search locally and then remotely") + + buildCreate.RegisterFlagCompletionFunc("image", common.NoCompletions) + buildCreate.RegisterFlagCompletionFunc("deploy", common.BoolCompletions) + buildCreate.RegisterFlagCompletionFunc("skip-image-check", common.BoolCompletions) + buildCreate.RegisterFlagCompletionFunc("remote", common.BoolCompletions) + build.AddCommand(buildCreate) + + buildGet := &cobra.Command{ + Use: "get [build-id]", + Short: "Get one or multiple builds", + Args: cobra.MaximumNArgs(1), + RunE: c.getBuild, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), + } + buildGet.Flags().IntVarP(&offset, "offset", "o", 0, "offset") + buildGet.Flags().IntVarP(&limit, "limit", "l", 10, "limit") + buildGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") + buildGet.RegisterFlagCompletionFunc("json", common.BoolCompletions) + buildGet.RegisterFlagCompletionFunc("offset", common.NoCompletions) + buildGet.RegisterFlagCompletionFunc("limit", common.NoCompletions) + build.AddCommand(buildGet) + + parent.AddCommand(build) +} + +func (c Cmd) setupDeploy(parent *cobra.Command) { + capsuleDeploy := &cobra.Command{ + Use: "deploy", + Short: "Deploy the given build to a capsule", + Args: cobra.NoArgs, + RunE: c.deploy, + Long: `Deploy either the given rig-build or docker image to a capsule. +If --build-id is given rig tries to find a matching existing rig-build to deploy. +If --image is given rig tries to create a new rig-build from the docker image (if it doesn't already exist) +Not both --build-id and --image can be given`, + } + capsuleDeploy.Flags().StringVarP(&buildID, "build-id", "b", "", "rig build id to deploy") + capsuleDeploy.Flags().StringVarP(&image, "image", "i", "", "docker image to deploy. Will create a new rig-build from the image if it doesn't exist") + capsuleDeploy.Flags().BoolVarP(&remote, "remote", "r", false, "if --image is also given, Rig will assume the image is from a remote registry. If not set, Rig will search locally and then remotely") + capsuleDeploy.RegisterFlagCompletionFunc("build-id", c.completions) + capsuleDeploy.RegisterFlagCompletionFunc("image", common.NoCompletions) + capsuleDeploy.RegisterFlagCompletionFunc("remote", common.BoolCompletions) + + parent.AddCommand(capsuleDeploy) +} + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveError + } + + if capsule.CapsuleID == "" { + return nil, cobra.ShellCompDirectiveError + } + + var buildIds []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + resp, err := c.Rig.Capsule().ListBuilds(c.Ctx, &connect.Request[capsule_api.ListBuildsRequest]{ + Msg: &capsule_api.ListBuildsRequest{ + CapsuleId: capsule.CapsuleID, + }, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, b := range resp.Msg.GetBuilds() { + if strings.HasPrefix(b.GetBuildId(), toComplete) { + buildIds = append(buildIds, formatBuild(b)) + } + } + + if len(buildIds) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + return buildIds, cobra.ShellCompDirectiveDefault +} + +func formatBuild(b *capsule_api.Build) string { + var age string + if b.GetCreatedAt().AsTime().IsZero() { + age = "-" + } else { + age = time.Since(b.GetCreatedAt().AsTime()).Truncate(time.Second).String() + } + + return fmt.Sprintf("%v\t (Age: %v)", b.GetBuildId(), age) +} diff --git a/cmd/rig/cmd/capsule/common.go b/cmd/rig/cmd/capsule/common.go index f6c5942be..da89b17d5 100644 --- a/cmd/rig/cmd/capsule/common.go +++ b/cmd/rig/cmd/capsule/common.go @@ -9,13 +9,11 @@ import ( "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-sdk" - "github.com/rigdev/rig/cmd/rig/cmd/base" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" - "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/utils" - "github.com/spf13/cobra" ) +var CapsuleID string + func GetCurrentContainerResources(ctx context.Context, client rig.Client) (*capsule.ContainerSettings, uint32, error) { resp, err := client.Capsule().Get(ctx, connect.NewRequest(&capsule.GetRequest{ CapsuleId: CapsuleID, @@ -83,342 +81,6 @@ func GetCurrentRollout(ctx context.Context, client rig.Client) (*capsule.Rollout return r.Msg.GetRollout(), nil } -var capsuleCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - capsuleIDs := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - resp, err := rc.Capsule().List(ctx, &connect.Request[capsule.ListRequest]{ - Msg: &capsule.ListRequest{}, - }) - if err != nil { - return err - } - - for _, c := range resp.Msg.GetCapsules() { - if strings.HasPrefix(c.GetCapsuleId(), toComplete) { - capsuleIDs = append(capsuleIDs, formatCapsule(c)) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(capsuleIDs) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return capsuleIDs, cobra.ShellCompDirectiveDefault -} - -var BuildCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) > 0 { - return nil, cobra.ShellCompDirectiveError - } - - if CapsuleID == "" { - return nil, cobra.ShellCompDirectiveError - } - - buildIds := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - resp, err := rc.Capsule().ListBuilds(ctx, &connect.Request[capsule.ListBuildsRequest]{ - Msg: &capsule.ListBuildsRequest{ - CapsuleId: CapsuleID, - }, - }) - if err != nil { - return err - } - - for _, b := range resp.Msg.GetBuilds() { - if strings.HasPrefix(b.GetBuildId(), toComplete) { - buildIds = append(buildIds, formatBuild(b)) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(buildIds) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return buildIds, cobra.ShellCompDirectiveDefault -} - -var RolloutCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if CapsuleID == "" { - return nil, cobra.ShellCompDirectiveError - } - - rolloutIds := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - resp, err := rc.Capsule().ListRollouts(ctx, &connect.Request[capsule.ListRolloutsRequest]{ - Msg: &capsule.ListRolloutsRequest{ - CapsuleId: CapsuleID, - }, - }) - if err != nil { - return err - } - - for _, r := range resp.Msg.GetRollouts() { - if strings.HasPrefix(fmt.Sprint(r.GetRolloutId()), toComplete) { - rolloutIds = append(rolloutIds, formatRollout(r)) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(rolloutIds) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return rolloutIds, cobra.ShellCompDirectiveDefault -} - -var InstanceCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if CapsuleID == "" { - return nil, cobra.ShellCompDirectiveError - } - - instanceIds := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - resp, err := rc.Capsule().ListInstances(ctx, &connect.Request[capsule.ListInstancesRequest]{ - Msg: &capsule.ListInstancesRequest{ - CapsuleId: CapsuleID, - }, - }) - if err != nil { - return err - } - - for _, i := range resp.Msg.GetInstances() { - if strings.HasPrefix(fmt.Sprint(i.GetInstanceId()), toComplete) { - instanceIds = append(instanceIds, formatInstance(i)) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(instanceIds) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return instanceIds, cobra.ShellCompDirectiveDefault -} - -var NetworkCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if CapsuleID == "" { - return nil, cobra.ShellCompDirectiveError - } - - interfaces := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - n, err := GetCurrentNetwork(ctx, rc) - if err != nil { - return err - } - - for _, i := range n.GetInterfaces() { - if strings.HasPrefix(i.GetName(), toComplete) { - interfaces = append(interfaces, i.GetName()) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(interfaces) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return interfaces, cobra.ShellCompDirectiveDefault -} - -var MountCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if CapsuleID == "" { - return nil, cobra.ShellCompDirectiveError - } - - paths := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - r, err := GetCurrentRollout(ctx, rc) - if err != nil { - return err - } - - for _, f := range r.GetConfig().GetConfigFiles() { - if strings.HasPrefix(f.GetPath(), toComplete) { - paths = append(paths, formatMount(f)) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(paths) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return paths, cobra.ShellCompDirectiveDefault -} - -var EnvCompletions = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if CapsuleID == "" { - return nil, cobra.ShellCompDirectiveError - } - - envKeys := []string{} - - if cmd.Annotations == nil { - cmd.Annotations = map[string]string{} - } - cmd.Annotations[base.OmitUser] = "true" - - f := base.Register( - func(ctx context.Context, rc rig.Client, cfg *cmd_config.Config) error { - if cfg.GetCurrentContext() == nil || cfg.GetCurrentAuth() == nil { - return errors.UnauthenticatedErrorf("") - } - - r, err := GetCurrentRollout(ctx, rc) - if err != nil { - return err - } - - for k := range r.GetConfig().GetContainerSettings().GetEnvironmentVariables() { - if strings.HasPrefix(k, toComplete) { - envKeys = append(envKeys, k) - } - } - - return nil - }, - ) - - if err := f(cmd, args); err != nil { - return nil, cobra.ShellCompDirectiveError - } - - cmd.Annotations[base.OmitUser] = "" - - if len(envKeys) == 0 { - return nil, cobra.ShellCompDirectiveError - } - - return envKeys, cobra.ShellCompDirectiveDefault -} - func formatCapsule(c *capsule.Capsule) string { var age string if c.GetCurrentRollout() == 0 { @@ -430,43 +92,6 @@ func formatCapsule(c *capsule.Capsule) string { return fmt.Sprintf("%v\t (Rollout: %v, Updated At: %v)", c.GetCapsuleId(), c.GetCurrentRollout(), age) } -func formatRollout(r *capsule.Rollout) string { - return fmt.Sprintf("%v\t (State: %v)", r.GetRolloutId(), r.GetStatus().GetState()) -} - -func formatInstance(i *capsule.Instance) string { - var startedAt string - if i.GetStartedAt().AsTime().IsZero() { - startedAt = "-" - } else { - startedAt = time.Since(i.GetStartedAt().AsTime()).Truncate(time.Second).String() - } - - return fmt.Sprintf("%v\t (State: %v, Started At: %v)", i.GetInstanceId(), i.GetState(), startedAt) -} - -func formatBuild(b *capsule.Build) string { - var age string - if b.GetCreatedAt().AsTime().IsZero() { - age = "-" - } else { - age = time.Since(b.GetCreatedAt().AsTime()).Truncate(time.Second).String() - } - - return fmt.Sprintf("%v\t (Age: %v)", b.GetBuildId(), age) -} - -func formatMount(m *capsule.ConfigFile) string { - var age string - if m.GetUpdatedAt().AsTime().IsZero() { - age = "-" - } else { - age = time.Since(m.GetUpdatedAt().AsTime()).Truncate(time.Second).String() - } - - return fmt.Sprintf("%v\t (Age: %v)", m.GetPath(), age) -} - func Truncated(str string, max int) string { if len(str) > max { return str[:strings.LastIndexAny(str[:max], " .,:;-")] + "..." diff --git a/cmd/rig/cmd/capsule/delete.go b/cmd/rig/cmd/capsule/delete.go deleted file mode 100644 index 8eb334726..000000000 --- a/cmd/rig/cmd/capsule/delete.go +++ /dev/null @@ -1,23 +0,0 @@ -package capsule - -import ( - "context" - - "github.com/bufbuild/connect-go" - "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" - "github.com/spf13/cobra" -) - -func delete(ctx context.Context, cmd *cobra.Command, nc rig.Client) error { - if _, err := nc.Capsule().Delete(ctx, &connect.Request[capsule.DeleteRequest]{ - Msg: &capsule.DeleteRequest{ - CapsuleId: CapsuleID, - }, - }); err != nil { - return err - } - - cmd.Println("Delete capsule", CapsuleID) - return nil -} diff --git a/cmd/rig/cmd/capsule/env/get.go b/cmd/rig/cmd/capsule/env/get.go index baa5fbe47..f1ffe0cbe 100644 --- a/cmd/rig/cmd/capsule/env/get.go +++ b/cmd/rig/cmd/capsule/env/get.go @@ -1,15 +1,13 @@ package env import ( - "context" - - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func get(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) error { - r, err := capsule.GetCurrentRollout(ctx, rc) +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + r, err := capsule.GetCurrentRollout(ctx, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/capsule/env/remove.go b/cmd/rig/cmd/capsule/env/remove.go index 917605bc4..ae7ac4e9e 100644 --- a/cmd/rig/cmd/capsule/env/remove.go +++ b/cmd/rig/cmd/capsule/env/remove.go @@ -1,17 +1,15 @@ package env import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" cmd_capsule "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func remove(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) error { +func (c Cmd) remove(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var key string var err error if len(args) > 0 { @@ -23,7 +21,7 @@ func remove(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Clien } } - r, err := cmd_capsule.GetCurrentRollout(ctx, rc) + r, err := cmd_capsule.GetCurrentRollout(ctx, c.Rig) if err != nil { return err } @@ -36,7 +34,7 @@ func remove(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Clien delete(cs.GetEnvironmentVariables(), key) - if _, err := rc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: cmd_capsule.CapsuleID, Changes: []*capsule.Change{ diff --git a/cmd/rig/cmd/capsule/env/set.go b/cmd/rig/cmd/capsule/env/set.go index 1754a72ab..67daa44f5 100644 --- a/cmd/rig/cmd/capsule/env/set.go +++ b/cmd/rig/cmd/capsule/env/set.go @@ -1,22 +1,20 @@ package env import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" cmd_capsule "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func set(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) error { +func (c Cmd) set(cmd *cobra.Command, args []string) error { + ctx := c.Ctx if len(args) != 2 { return errors.InvalidArgumentErrorf("expected key and value arguments") } - r, err := cmd_capsule.GetCurrentRollout(ctx, rc) + r, err := cmd_capsule.GetCurrentRollout(ctx, c.Rig) if err != nil { return err } @@ -28,7 +26,7 @@ func set(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) } cs.EnvironmentVariables[args[0]] = args[1] - if _, err := rc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: cmd_capsule.CapsuleID, Changes: []*capsule.Change{ diff --git a/cmd/rig/cmd/capsule/env/setup.go b/cmd/rig/cmd/capsule/env/setup.go index 59f86a8d1..0b48d3cf6 100644 --- a/cmd/rig/cmd/capsule/env/setup.go +++ b/cmd/rig/cmd/capsule/env/setup.go @@ -1,13 +1,26 @@ package env import ( + "context" + "strings" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) -func Setup(parent *cobra.Command) *cobra.Command { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { env := &cobra.Command{ Use: "env", Short: "Manage environment variables for the capsule", @@ -17,7 +30,7 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "set key value", Short: "Set an environment variable", Args: cobra.ExactArgs(2), - RunE: base.Register(set), + RunE: c.set, ValidArgsFunction: common.NoCompletions, } env.AddCommand(envSet) @@ -26,8 +39,8 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "get [key]", Short: "Get an environment variable", Args: cobra.MaximumNArgs(1), - RunE: base.Register(get), - ValidArgsFunction: common.Complete(capsule.EnvCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.get, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } env.AddCommand(envGet) @@ -35,12 +48,39 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "remove [key]", Short: "Remove an environment variable", Args: cobra.ExactArgs(1), - RunE: base.Register(remove), - ValidArgsFunction: common.Complete(capsule.EnvCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.remove, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } env.AddCommand(envRemove) parent.AddCommand(env) +} + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if capsule.CapsuleID == "" { + return nil, cobra.ShellCompDirectiveError + } + + var envKeys []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + r, err := capsule.GetCurrentRollout(c.Ctx, c.Rig) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for k := range r.GetConfig().GetContainerSettings().GetEnvironmentVariables() { + if strings.HasPrefix(k, toComplete) { + envKeys = append(envKeys, k) + } + } + + if len(envKeys) == 0 { + return nil, cobra.ShellCompDirectiveError + } - return env + return envKeys, cobra.ShellCompDirectiveDefault } diff --git a/cmd/rig/cmd/capsule/instance/get.go b/cmd/rig/cmd/capsule/instance/get.go index 49fd29603..e1a5acd59 100644 --- a/cmd/rig/cmd/capsule/instance/get.go +++ b/cmd/rig/cmd/capsule/instance/get.go @@ -1,7 +1,6 @@ package instance import ( - "context" "fmt" "time" @@ -9,14 +8,14 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" cmd_capsule "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func get(ctx context.Context, args []string, cmd *cobra.Command, nc rig.Client) error { - resp, err := nc.Capsule().ListInstances(ctx, &connect.Request[capsule.ListInstancesRequest]{ +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.Capsule().ListInstances(ctx, &connect.Request[capsule.ListInstancesRequest]{ Msg: &capsule.ListInstancesRequest{ CapsuleId: cmd_capsule.CapsuleID, Pagination: &model.Pagination{ diff --git a/cmd/rig/cmd/capsule/instance/logs.go b/cmd/rig/cmd/capsule/instance/logs.go index 7903ae97f..ece525c64 100644 --- a/cmd/rig/cmd/capsule/instance/logs.go +++ b/cmd/rig/cmd/capsule/instance/logs.go @@ -1,29 +1,28 @@ package instance import ( - "context" "os" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/base" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func logs(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) logs(cmd *cobra.Command, args []string) error { + ctx := c.Ctx arg := "" if len(args) > 0 { arg = args[0] } - instanceID, err := provideInstanceID(ctx, nc, capsule_cmd.CapsuleID, arg) + instanceID, err := c.provideInstanceID(ctx, capsule_cmd.CapsuleID, arg) if err != nil { return err } - s, err := nc.Capsule().Logs(ctx, &connect.Request[capsule.LogsRequest]{ + s, err := c.Rig.Capsule().Logs(ctx, &connect.Request[capsule.LogsRequest]{ Msg: &capsule.LogsRequest{ CapsuleId: capsule_cmd.CapsuleID, InstanceId: instanceID, diff --git a/cmd/rig/cmd/capsule/instance/restart.go b/cmd/rig/cmd/capsule/instance/restart.go index c9bc6e4fd..d1422a537 100644 --- a/cmd/rig/cmd/capsule/instance/restart.go +++ b/cmd/rig/cmd/capsule/instance/restart.go @@ -1,27 +1,25 @@ package instance import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func restart(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) restart(cmd *cobra.Command, args []string) error { + ctx := c.Ctx arg := "" if len(args) > 0 { arg = args[0] } - instanceID, err := provideInstanceID(ctx, nc, capsule_cmd.CapsuleID, arg) + instanceID, err := c.provideInstanceID(ctx, capsule_cmd.CapsuleID, arg) if err != nil { return err } - if _, err := nc.Capsule().RestartInstance(ctx, &connect.Request[capsule.RestartInstanceRequest]{ + if _, err := c.Rig.Capsule().RestartInstance(ctx, &connect.Request[capsule.RestartInstanceRequest]{ Msg: &capsule.RestartInstanceRequest{ CapsuleId: capsule_cmd.CapsuleID, InstanceId: instanceID, diff --git a/cmd/rig/cmd/capsule/instance/setup.go b/cmd/rig/cmd/capsule/instance/setup.go index e425cb38a..361ec81a5 100644 --- a/cmd/rig/cmd/capsule/instance/setup.go +++ b/cmd/rig/cmd/capsule/instance/setup.go @@ -2,15 +2,20 @@ package instance import ( "context" + "fmt" + "strings" + "time" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" cmd_capsule "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -23,7 +28,15 @@ var ( follow bool ) -func Setup(parent *cobra.Command) *cobra.Command { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { instance := &cobra.Command{ Use: "instance", Short: "Inspect and restart instances", @@ -33,8 +46,8 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "get [instance-id]", Short: "Get one or more instances", Args: cobra.MaximumNArgs(1), - RunE: base.Register(get), - ValidArgsFunction: common.Complete(cmd_capsule.InstanceCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.get, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } GetInstances.Flags().BoolVar(&outputJSON, "json", false, "output as json") GetInstances.Flags().IntVarP(&offset, "offset", "o", 0, "offset for pagination") @@ -48,8 +61,8 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "restart [instance-id]", Short: "Restart a single instance", Args: cobra.MaximumNArgs(1), - RunE: base.Register(restart), - ValidArgsFunction: common.Complete(cmd_capsule.InstanceCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.restart, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } instance.AddCommand(restartInstance) @@ -57,24 +70,22 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "logs [instance-id]", Short: "Read instance logs from the capsule ", Args: cobra.MaximumNArgs(1), - RunE: base.Register(logs), - ValidArgsFunction: common.Complete(cmd_capsule.InstanceCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.logs, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } logs.Flags().BoolVarP(&follow, "follow", "f", false, "keep the connection open and read out logs as they are produced") logs.RegisterFlagCompletionFunc("follow", common.BoolCompletions) instance.AddCommand(logs) parent.AddCommand(instance) - - return instance } -func provideInstanceID(ctx context.Context, nc rig.Client, capsuleID string, arg string) (string, error) { +func (c Cmd) provideInstanceID(ctx context.Context, capsuleID string, arg string) (string, error) { if arg != "" { return arg, nil } - res, err := nc.Capsule().ListInstances(ctx, &connect.Request[capsule.ListInstancesRequest]{ + res, err := c.Rig.Capsule().ListInstances(ctx, &connect.Request[capsule.ListInstancesRequest]{ Msg: &capsule.ListInstancesRequest{ CapsuleId: capsuleID, }, @@ -99,3 +110,47 @@ func provideInstanceID(ctx context.Context, nc rig.Client, capsuleID string, arg _, s, err := common.PromptSelect("instance", items) return s, err } + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if cmd_capsule.CapsuleID == "" { + return nil, cobra.ShellCompDirectiveError + } + + var instanceIds []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + resp, err := c.Rig.Capsule().ListInstances(c.Ctx, &connect.Request[capsule.ListInstancesRequest]{ + Msg: &capsule.ListInstancesRequest{ + CapsuleId: capsule_cmd.CapsuleID, + }, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, i := range resp.Msg.GetInstances() { + if strings.HasPrefix(fmt.Sprint(i.GetInstanceId()), toComplete) { + instanceIds = append(instanceIds, formatInstance(i)) + } + } + + if len(instanceIds) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + return instanceIds, cobra.ShellCompDirectiveDefault +} + +func formatInstance(i *capsule.Instance) string { + var startedAt string + if i.GetStartedAt().AsTime().IsZero() { + startedAt = "-" + } else { + startedAt = time.Since(i.GetStartedAt().AsTime()).Truncate(time.Second).String() + } + + return fmt.Sprintf("%v\t (State: %v, Started At: %v)", i.GetInstanceId(), i.GetState(), startedAt) +} diff --git a/cmd/rig/cmd/capsule/mount/get.go b/cmd/rig/cmd/capsule/mount/get.go index 0701e8307..ca27b0b22 100644 --- a/cmd/rig/cmd/capsule/mount/get.go +++ b/cmd/rig/cmd/capsule/mount/get.go @@ -9,13 +9,13 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func get(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) error { - r, err := capsule_cmd.GetCurrentRollout(ctx, rc) +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + r, err := capsule_cmd.GetCurrentRollout(ctx, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/capsule/mount/remove.go b/cmd/rig/cmd/capsule/mount/remove.go index 98bbf894b..f8386a757 100644 --- a/cmd/rig/cmd/capsule/mount/remove.go +++ b/cmd/rig/cmd/capsule/mount/remove.go @@ -1,17 +1,15 @@ package mount import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func remove(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) error { +func (c Cmd) remove(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var path string var err error if len(args) != 1 { @@ -27,7 +25,7 @@ func remove(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Clien RemoveConfigFile: path, } - if _, err := rc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: capsule_cmd.CapsuleID, Changes: []*capsule.Change{ diff --git a/cmd/rig/cmd/capsule/mount/set.go b/cmd/rig/cmd/capsule/mount/set.go index d024471f0..1b5b8a928 100644 --- a/cmd/rig/cmd/capsule/mount/set.go +++ b/cmd/rig/cmd/capsule/mount/set.go @@ -1,18 +1,17 @@ package mount import ( - "context" "os" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func set(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) error { +func (c Cmd) set(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error if srcPath == "" { srcPath, err = common.PromptInput("Source path", common.ValidateFilePathOpt) @@ -40,7 +39,7 @@ func set(ctx context.Context, args []string, cmd *cobra.Command, rc rig.Client) }, } - if _, err := rc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: capsule_cmd.CapsuleID, Changes: []*capsule.Change{ diff --git a/cmd/rig/cmd/capsule/mount/setup.go b/cmd/rig/cmd/capsule/mount/setup.go index bd8ccdd90..df73c8f3f 100644 --- a/cmd/rig/cmd/capsule/mount/setup.go +++ b/cmd/rig/cmd/capsule/mount/setup.go @@ -1,10 +1,18 @@ package mount import ( + "context" + "fmt" + "strings" + "time" + + capsule_api "github.com/rigdev/rig-go-api/api/v1/capsule" + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -14,10 +22,17 @@ var ( var ( srcPath string dstPath string - // path string ) -func Setup(parent *cobra.Command) *cobra.Command { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { mount := &cobra.Command{ Use: "mount", Short: "Manage config files mounts in the capsule", @@ -27,8 +42,8 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "get [mount-path]", Short: "Get one or multiple mounts", Args: cobra.MaximumNArgs(1), - RunE: base.Register(get), - ValidArgsFunction: common.Complete(capsule.MountCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.get, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } mountGet.Flags().StringVar(&dstPath, "download", "", "download the mount to specified path. If empty use current dir") mountGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") @@ -39,7 +54,7 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "set", Short: "Mount a local configuration file in specified path the capsule", Args: cobra.NoArgs, - RunE: base.Register(set), + RunE: c.set, ValidArgsFunction: common.NoCompletions, } mountSet.Flags().StringVar(&srcPath, "src", "", "source path") @@ -51,12 +66,51 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "remove [mount-path]", Short: "Remove a mount", Args: cobra.MaximumNArgs(1), - RunE: base.Register(remove), - ValidArgsFunction: common.Complete(capsule.MountCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.remove, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } mount.AddCommand(mountRemove) parent.AddCommand(mount) - return mount } + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if capsule.CapsuleID == "" { + return nil, cobra.ShellCompDirectiveError + } + + var paths []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + r, err := capsule.GetCurrentRollout(c.Ctx, c.Rig) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, f := range r.GetConfig().GetConfigFiles() { + if strings.HasPrefix(f.GetPath(), toComplete) { + paths = append(paths, formatMount(f)) + } + } + + if len(paths) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + return paths, cobra.ShellCompDirectiveDefault +} + +func formatMount(m *capsule_api.ConfigFile) string { + var age string + if m.GetUpdatedAt().AsTime().IsZero() { + age = "-" + } else { + age = time.Since(m.GetUpdatedAt().AsTime()).Truncate(time.Second).String() + } + + return fmt.Sprintf("%v\t (Age: %v)", m.GetPath(), age) +} diff --git a/cmd/rig/cmd/capsule/network/configure.go b/cmd/rig/cmd/capsule/network/configure.go index 7e9f6f200..402739ea5 100644 --- a/cmd/rig/cmd/capsule/network/configure.go +++ b/cmd/rig/cmd/capsule/network/configure.go @@ -1,13 +1,11 @@ package network import ( - "context" "encoding/json" "os" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" @@ -16,7 +14,8 @@ import ( "gopkg.in/yaml.v3" ) -func configure(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) configure(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error networkFile := "" if len(args) == 0 { @@ -47,7 +46,7 @@ func configure(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl return err } - if _, err := nc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: capsule_cmd.CapsuleID, Changes: []*capsule.Change{{ diff --git a/cmd/rig/cmd/capsule/network/get.go b/cmd/rig/cmd/capsule/network/get.go index 7cb8e78fd..8f6c2935d 100644 --- a/cmd/rig/cmd/capsule/network/get.go +++ b/cmd/rig/cmd/capsule/network/get.go @@ -1,20 +1,19 @@ package network import ( - "context" "fmt" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/spf13/cobra" ) -func get(ctx context.Context, cmd *cobra.Command, args []string, client rig.Client) error { - n, err := capsule_cmd.GetCurrentNetwork(ctx, client) +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + n, err := capsule_cmd.GetCurrentNetwork(ctx, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/capsule/network/setup.go b/cmd/rig/cmd/capsule/network/setup.go index 3101c1caa..5a82c7628 100644 --- a/cmd/rig/cmd/capsule/network/setup.go +++ b/cmd/rig/cmd/capsule/network/setup.go @@ -1,17 +1,30 @@ package network import ( + "context" + "strings" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( outputJSON bool ) -func Setup(parent *cobra.Command) *cobra.Command { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { network := &cobra.Command{ Use: "network", Short: "Configure and inspect the network of the capsule", @@ -21,23 +34,49 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "configure [network-file]", Short: "configure the network of the capsule", Args: cobra.MaximumNArgs(1), - RunE: base.Register(configure), + RunE: c.configure, } - network.AddCommand(networkConfigure) networkGet := &cobra.Command{ Use: "get [name]", Short: "get the entire network or a specific interface of the capsule", Args: cobra.MaximumNArgs(1), - RunE: base.Register(get), - ValidArgsFunction: common.Complete(capsule.NetworkCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.get, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } networkGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") networkGet.RegisterFlagCompletionFunc("json", common.BoolCompletions) network.AddCommand(networkGet) parent.AddCommand(network) +} + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if capsule.CapsuleID == "" { + return nil, cobra.ShellCompDirectiveError + } + + var interfaces []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + n, err := capsule.GetCurrentNetwork(c.Ctx, c.Rig) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, i := range n.GetInterfaces() { + if strings.HasPrefix(i.GetName(), toComplete) { + interfaces = append(interfaces, i.GetName()) + } + } + + if len(interfaces) == 0 { + return nil, cobra.ShellCompDirectiveError + } - return network + return interfaces, cobra.ShellCompDirectiveDefault } diff --git a/cmd/rig/cmd/capsule/resource/get.go b/cmd/rig/cmd/capsule/resource/get.go index e9110474f..16bf93f47 100644 --- a/cmd/rig/cmd/capsule/resource/get.go +++ b/cmd/rig/cmd/capsule/resource/get.go @@ -11,6 +11,10 @@ import ( "github.com/spf13/cobra" ) +func (r Cmd) get(cmd *cobra.Command, args []string) error { + return get(r.Ctx, cmd, r.Rig) +} + func get(ctx context.Context, cmd *cobra.Command, client rig.Client) error { containerSettings, replicas, err := capsule.GetCurrentContainerResources(ctx, client) if err != nil { diff --git a/cmd/rig/cmd/capsule/resource/scale.go b/cmd/rig/cmd/capsule/resource/scale.go index 25b938351..ae8fe265b 100644 --- a/cmd/rig/cmd/capsule/resource/scale.go +++ b/cmd/rig/cmd/capsule/resource/scale.go @@ -16,6 +16,10 @@ import ( "k8s.io/apimachinery/pkg/api/resource" ) +func (r Cmd) scale(cmd *cobra.Command, args []string) error { + return scale(r.Ctx, cmd, r.Rig, args) +} + func scale(ctx context.Context, cmd *cobra.Command, client rig.Client, args []string) error { container, r, err := capsule_cmd.GetCurrentContainerResources(ctx, client) if err != nil { diff --git a/cmd/rig/cmd/capsule/resource/setup.go b/cmd/rig/cmd/capsule/resource/setup.go index 6fbbedaad..fc98d2ac6 100644 --- a/cmd/rig/cmd/capsule/resource/setup.go +++ b/cmd/rig/cmd/capsule/resource/setup.go @@ -1,9 +1,12 @@ package resource import ( + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -21,7 +24,14 @@ var ( replicas int ) -func Setup(parent *cobra.Command) *cobra.Command { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client +} + +func (r Cmd) Setup(parent *cobra.Command) { resource := &cobra.Command{ Use: "resource", Short: "Scale and inspect the resources of the capsule", @@ -31,7 +41,7 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "get", Short: "Displays the resources (container size) and replicas of the capsule", Args: cobra.NoArgs, - RunE: base.Register(get), + RunE: r.get, ValidArgsFunction: common.NoCompletions, } resourcesGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") @@ -42,7 +52,7 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "scale", Short: "Sets the container resources for the capsule", Args: cobra.NoArgs, - RunE: base.Register(scale), + RunE: r.scale, ValidArgsFunction: common.NoCompletions, } resourcesScale.Flags().StringVar(&requestCPU, "request-cpu", "", "Minimum CPU cores per container") @@ -60,6 +70,4 @@ func Setup(parent *cobra.Command) *cobra.Command { resource.AddCommand(resourcesScale) parent.AddCommand(resource) - - return resource } diff --git a/cmd/rig/cmd/capsule/rollout/events.go b/cmd/rig/cmd/capsule/rollout/events.go index 20b85c5d1..5887068c3 100644 --- a/cmd/rig/cmd/capsule/rollout/events.go +++ b/cmd/rig/cmd/capsule/rollout/events.go @@ -1,7 +1,6 @@ package rollout import ( - "context" "strconv" "time" @@ -9,13 +8,13 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func CapsuleEvents(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) capsuleEvents(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var rollout uint64 var err error if len(args) > 0 { @@ -24,7 +23,7 @@ func CapsuleEvents(ctx context.Context, cmd *cobra.Command, args []string, nc ri return errors.InvalidArgumentErrorf("invalid rollout id - %v", err) } } else { - resp, err := nc.Capsule().Get(ctx, &connect.Request[capsule.GetRequest]{ + resp, err := c.Rig.Capsule().Get(ctx, &connect.Request[capsule.GetRequest]{ Msg: &capsule.GetRequest{ CapsuleId: capsule_cmd.CapsuleID, }, @@ -36,7 +35,7 @@ func CapsuleEvents(ctx context.Context, cmd *cobra.Command, args []string, nc ri rollout = resp.Msg.GetCapsule().GetCurrentRollout() } - resp, err := nc.Capsule().ListEvents(ctx, &connect.Request[capsule.ListEventsRequest]{ + resp, err := c.Rig.Capsule().ListEvents(ctx, &connect.Request[capsule.ListEventsRequest]{ Msg: &capsule.ListEventsRequest{ CapsuleId: capsule_cmd.CapsuleID, Pagination: &model.Pagination{ diff --git a/cmd/rig/cmd/capsule/rollout/get.go b/cmd/rig/cmd/capsule/rollout/get.go index cfbe217a1..faf4e8106 100644 --- a/cmd/rig/cmd/capsule/rollout/get.go +++ b/cmd/rig/cmd/capsule/rollout/get.go @@ -1,7 +1,6 @@ package rollout import ( - "context" "fmt" "strconv" "strings" @@ -11,15 +10,15 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func get(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { - resp, err := nc.Capsule().ListRollouts(ctx, &connect.Request[capsule.ListRolloutsRequest]{ +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.Capsule().ListRollouts(ctx, &connect.Request[capsule.ListRolloutsRequest]{ Msg: &capsule.ListRolloutsRequest{ CapsuleId: capsule_cmd.CapsuleID, Pagination: &model.Pagination{ diff --git a/cmd/rig/cmd/capsule/rollout/setup.go b/cmd/rig/cmd/capsule/rollout/setup.go index c22a429bb..aa7dcc674 100644 --- a/cmd/rig/cmd/capsule/rollout/setup.go +++ b/cmd/rig/cmd/capsule/rollout/setup.go @@ -1,10 +1,18 @@ package rollout import ( + "context" + "fmt" + "strings" + + "github.com/bufbuild/connect-go" + capsule_api "github.com/rigdev/rig-go-api/api/v1/capsule" + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -16,9 +24,15 @@ var ( outputJSON bool ) -var () +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} -func Setup(parent *cobra.Command) *cobra.Command { +func (c Cmd) Setup(parent *cobra.Command) { rollout := &cobra.Command{ Use: "rollout", Short: "Inspect the rollouts of the capsule", @@ -28,8 +42,8 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "get [rollout-id]", Short: "Get one or more rollouts", Args: cobra.MaximumNArgs(1), - RunE: base.Register(get), - ValidArgsFunction: common.Complete(capsule.RolloutCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.get, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } rolloutGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") rolloutGet.Flags().IntVarP(&offset, "offset", "o", 0, "offset for pagination") @@ -43,12 +57,47 @@ func Setup(parent *cobra.Command) *cobra.Command { Use: "events [rollout-id]", Short: "List events related to a rollout, default to the current rollout", Args: cobra.MaximumNArgs(1), - RunE: base.Register(CapsuleEvents), - ValidArgsFunction: common.Complete(capsule.RolloutCompletions, common.MaxArgsCompletionFilter(1)), + RunE: c.capsuleEvents, + ValidArgsFunction: common.Complete(c.completions, common.MaxArgsCompletionFilter(1)), } rollout.AddCommand(events) parent.AddCommand(rollout) +} + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if capsule.CapsuleID == "" { + return nil, cobra.ShellCompDirectiveError + } + + var rolloutIds []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + resp, err := c.Rig.Capsule().ListRollouts(c.Ctx, &connect.Request[capsule_api.ListRolloutsRequest]{ + Msg: &capsule_api.ListRolloutsRequest{ + CapsuleId: capsule.CapsuleID, + }, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, r := range resp.Msg.GetRollouts() { + if strings.HasPrefix(fmt.Sprint(r.GetRolloutId()), toComplete) { + rolloutIds = append(rolloutIds, formatRollout(r)) + } + } + + if len(rolloutIds) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + return rolloutIds, cobra.ShellCompDirectiveDefault +} - return rollout +func formatRollout(r *capsule_api.Rollout) string { + return fmt.Sprintf("%v\t (State: %v)", r.GetRolloutId(), r.GetStatus().GetState()) } diff --git a/cmd/rig/cmd/capsule/root/abort.go b/cmd/rig/cmd/capsule/root/abort.go new file mode 100644 index 000000000..9c70434ec --- /dev/null +++ b/cmd/rig/cmd/capsule/root/abort.go @@ -0,0 +1,33 @@ +package root + +import ( + "github.com/bufbuild/connect-go" + "github.com/rigdev/rig-go-api/api/v1/capsule" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/spf13/cobra" +) + +func (c Cmd) abort(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + cc, err := c.Rig.Capsule().Get(ctx, &connect.Request[capsule.GetRequest]{ + Msg: &capsule.GetRequest{ + CapsuleId: capsule_cmd.CapsuleID, + }, + }) + if err != nil { + return err + } + + if _, err := c.Rig.Capsule().AbortRollout(ctx, &connect.Request[capsule.AbortRolloutRequest]{ + Msg: &capsule.AbortRolloutRequest{ + CapsuleId: capsule_cmd.CapsuleID, + RolloutId: cc.Msg.GetCapsule().GetCurrentRollout(), + }, + }); err != nil { + return err + } + + cmd.Println("Current rollout aborted") + + return nil +} diff --git a/cmd/rig/cmd/capsule/config.go b/cmd/rig/cmd/capsule/root/config.go similarity index 77% rename from cmd/rig/cmd/capsule/config.go rename to cmd/rig/cmd/capsule/root/config.go index fd1f3ff0a..11650913c 100644 --- a/cmd/rig/cmd/capsule/config.go +++ b/cmd/rig/cmd/capsule/root/config.go @@ -1,16 +1,15 @@ -package capsule +package root import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func config(ctx context.Context, cmd *cobra.Command, rc rig.Client) error { +func (c Cmd) config(cmd *cobra.Command, args []string) error { + ctx := c.Ctx if len(args) > 0 && command == "" { return errors.InvalidArgumentErrorf("command must be set when args are provided") } @@ -18,7 +17,7 @@ func config(ctx context.Context, cmd *cobra.Command, rc rig.Client) error { var cs []*capsule.Change if command != "" { - r, err := GetCurrentRollout(ctx, rc) + r, err := capsule_cmd.GetCurrentRollout(ctx, c.Rig) if err != nil { return err } @@ -45,9 +44,9 @@ func config(ctx context.Context, cmd *cobra.Command, rc rig.Client) error { }) } - if _, err := rc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ - CapsuleId: CapsuleID, + CapsuleId: capsule_cmd.CapsuleID, Changes: cs, }, }); err != nil { diff --git a/cmd/rig/cmd/capsule/create.go b/cmd/rig/cmd/capsule/root/create.go similarity index 89% rename from cmd/rig/cmd/capsule/create.go rename to cmd/rig/cmd/capsule/root/create.go index 8fd64e3a7..5b8c093fb 100644 --- a/cmd/rig/cmd/capsule/create.go +++ b/cmd/rig/cmd/capsule/root/create.go @@ -1,23 +1,22 @@ -package capsule +package root import ( - "context" "os" "strconv" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/capsule" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client, cfg *cmd_config.Config) error { +func (c *Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error - if CapsuleID == "" { - CapsuleID, err = common.PromptInput("Capsule name:", common.ValidateSystemNameOpt) + if capsule_cmd.CapsuleID == "" { + capsule_cmd.CapsuleID, err = common.PromptInput("Capsule name:", common.ValidateSystemNameOpt) if err != nil { return err } @@ -216,9 +215,9 @@ func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clien } } - res, err := nc.Capsule().Create(ctx, &connect.Request[capsule.CreateRequest]{ + res, err := c.Rig.Capsule().Create(ctx, &connect.Request[capsule.CreateRequest]{ Msg: &capsule.CreateRequest{ - Name: CapsuleID, + Name: capsule_cmd.CapsuleID, }, }) if err != nil { @@ -229,7 +228,7 @@ func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clien if image != "" { var buildID string - if res, err := nc.Capsule().CreateBuild(ctx, &connect.Request[capsule.CreateBuildRequest]{ + if res, err := c.Rig.Capsule().CreateBuild(ctx, &connect.Request[capsule.CreateBuildRequest]{ Msg: &capsule.CreateBuildRequest{ CapsuleId: capsuleID, Image: image, @@ -256,7 +255,7 @@ func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clien } if len(init) > 0 { - if _, err := nc.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ + if _, err := c.Rig.Capsule().Deploy(ctx, &connect.Request[capsule.DeployRequest]{ Msg: &capsule.DeployRequest{ CapsuleId: capsuleID, Changes: init, @@ -266,6 +265,6 @@ func create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clien } } - cmd.Printf("Created new capsule '%v'\n", CapsuleID) + cmd.Printf("Created new capsule '%v'\n", capsule_cmd.CapsuleID) return nil } diff --git a/cmd/rig/cmd/capsule/root/delete.go b/cmd/rig/cmd/capsule/root/delete.go new file mode 100644 index 000000000..8d8e78389 --- /dev/null +++ b/cmd/rig/cmd/capsule/root/delete.go @@ -0,0 +1,22 @@ +package root + +import ( + "github.com/bufbuild/connect-go" + "github.com/rigdev/rig-go-api/api/v1/capsule" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/spf13/cobra" +) + +func (c Cmd) delete(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + if _, err := c.Rig.Capsule().Delete(ctx, &connect.Request[capsule.DeleteRequest]{ + Msg: &capsule.DeleteRequest{ + CapsuleId: capsule_cmd.CapsuleID, + }, + }); err != nil { + return err + } + + cmd.Println("Delete capsule", capsule_cmd.CapsuleID) + return nil +} diff --git a/cmd/rig/cmd/capsule/get.go b/cmd/rig/cmd/capsule/root/get.go similarity index 63% rename from cmd/rig/cmd/capsule/get.go rename to cmd/rig/cmd/capsule/root/get.go index 99dbdfd5c..3cf110e33 100644 --- a/cmd/rig/cmd/capsule/get.go +++ b/cmd/rig/cmd/capsule/root/get.go @@ -1,21 +1,21 @@ -package capsule +package root import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" + capsule_cmd "github.com/rigdev/rig/cmd/rig/cmd/capsule" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func get(ctx context.Context, cmd *cobra.Command, rc rig.Client, args []string) error { - resp, err := rc.Capsule().List(ctx, &connect.Request[capsule.ListRequest]{ +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.Capsule().List(ctx, &connect.Request[capsule.ListRequest]{ Msg: &capsule.ListRequest{ Pagination: &model.Pagination{ Offset: uint32(offset), @@ -29,25 +29,26 @@ func get(ctx context.Context, cmd *cobra.Command, rc rig.Client, args []string) capsules := resp.Msg.GetCapsules() - if CapsuleID != "" { + if capsule_cmd.CapsuleID != "" { found := false for _, c := range resp.Msg.GetCapsules() { - if c.GetCapsuleId() == CapsuleID { + if c.GetCapsuleId() == capsule_cmd.CapsuleID { capsules = []*capsule.Capsule{c} + found = true break } } if !found { - return errors.NotFoundErrorf("capsule %s not found", CapsuleID) + return errors.NotFoundErrorf("capsule %s not found", capsule_cmd.CapsuleID) } } if outputJSON { - for _, c := range capsules { - r, err := rc.Capsule().GetRollout(ctx, &connect.Request[capsule.GetRolloutRequest]{ + for _, cc := range capsules { + r, err := c.Rig.Capsule().GetRollout(ctx, &connect.Request[capsule.GetRolloutRequest]{ Msg: &capsule.GetRolloutRequest{ - CapsuleId: c.GetCapsuleId(), - RolloutId: c.GetCurrentRollout(), + CapsuleId: cc.GetCapsuleId(), + RolloutId: cc.GetCurrentRollout(), }, }) if errors.IsNotFound(err) { @@ -57,7 +58,7 @@ func get(ctx context.Context, cmd *cobra.Command, rc rig.Client, args []string) return err } - cmd.Println(common.ProtoToPrettyJson(c)) + cmd.Println(common.ProtoToPrettyJson(cc)) if r.Msg.GetRollout() != nil { cmd.Println(common.ProtoToPrettyJson(r.Msg.GetRollout())) } @@ -67,11 +68,11 @@ func get(ctx context.Context, cmd *cobra.Command, rc rig.Client, args []string) t := table.NewWriter() t.AppendHeader(table.Row{fmt.Sprintf("Capsules (%d)", resp.Msg.GetTotal()), "Replicas", "Build ID"}) - for _, c := range capsules { - r, err := rc.Capsule().GetRollout(ctx, &connect.Request[capsule.GetRolloutRequest]{ + for _, cc := range capsules { + r, err := c.Rig.Capsule().GetRollout(ctx, &connect.Request[capsule.GetRolloutRequest]{ Msg: &capsule.GetRolloutRequest{ - CapsuleId: c.GetCapsuleId(), - RolloutId: c.GetCurrentRollout(), + CapsuleId: cc.GetCapsuleId(), + RolloutId: cc.GetCurrentRollout(), }, }) if errors.IsNotFound(err) { @@ -82,7 +83,7 @@ func get(ctx context.Context, cmd *cobra.Command, rc rig.Client, args []string) } t.AppendRow(table.Row{ - c.GetCapsuleId(), + cc.GetCapsuleId(), r.Msg.GetRollout().GetConfig().GetReplicas(), r.Msg.GetRollout().GetConfig().GetBuildId(), }) diff --git a/cmd/rig/cmd/capsule/root/setup.go b/cmd/rig/cmd/capsule/root/setup.go new file mode 100644 index 000000000..850bb6bb8 --- /dev/null +++ b/cmd/rig/cmd/capsule/root/setup.go @@ -0,0 +1,203 @@ +package root + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/bufbuild/connect-go" + "github.com/docker/docker/client" + capsule_api "github.com/rigdev/rig-go-api/api/v1/capsule" + "github.com/rigdev/rig-go-sdk" + "github.com/rigdev/rig/cmd/common" + "github.com/rigdev/rig/cmd/rig/cmd/capsule" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/builddeploy" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/env" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/instance" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/mount" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/network" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/resource" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/rollout" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" + "github.com/spf13/cobra" + "go.uber.org/fx" +) + +var ( + offset int + limit int +) + +var ( + interactive bool + outputJSON bool + remote bool +) + +var ( + image string + buildID string + command string + args []string +) + +var omitCapsuleIDAnnotation = map[string]string{ + "OMIT_CAPSULE_ID": "true", +} + +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config + DockerClient *client.Client + + Resources resource.Cmd + BuildDeploy builddeploy.Cmd + Instance instance.Cmd + Network network.Cmd + Rollout rollout.Cmd + Env env.Cmd + Mount mount.Cmd +} + +func (c Cmd) Setup(parent *cobra.Command) { + capsuleCmd := &cobra.Command{ + Use: "capsule", + Short: "Manage capsules", + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + if parent.PersistentPreRunE != nil { + if err := parent.PersistentPreRunE(cmd, args); err != nil { + return err + } + } + if cmd.Annotations["OMIT_CAPSULE_ID"] != "" { + return nil + } + + if capsule.CapsuleID != "" { + return nil + } + + var err error + capsule.CapsuleID, err = common.PromptInput("Capsule id:", common.ValidateNonEmptyOpt) + if err != nil { + return err + } + return nil + }, + } + capsuleCmd.PersistentFlags().StringVarP(&capsule.CapsuleID, "capsule-id", "c", "", "Id of the capsule") + capsuleCmd.RegisterFlagCompletionFunc("capsule-id", c.completions) + + capsuleCreate := &cobra.Command{ + Use: "create", + Short: "Create a new capsule", + Args: cobra.NoArgs, + RunE: c.create, + Annotations: omitCapsuleIDAnnotation, + ValidArgsFunction: common.NoCompletions, + } + capsuleCreate.Flags().BoolVarP(&interactive, "interactive", "i", false, "interactive mode") + capsuleCreate.RegisterFlagCompletionFunc("interactive", common.BoolCompletions) + capsuleCmd.AddCommand(capsuleCreate) + + capsuleAbort := &cobra.Command{ + Use: "abort", + Short: "Abort the current rollout. This will leave the capsule in a undefined state", + Args: cobra.NoArgs, + RunE: c.abort, + ValidArgsFunction: common.NoCompletions, + } + capsuleCmd.AddCommand(capsuleAbort) + + capsuleDelete := &cobra.Command{ + Use: "delete", + Short: "Delete a capsule", + Args: cobra.NoArgs, + RunE: c.delete, + ValidArgsFunction: common.NoCompletions, + } + capsuleCmd.AddCommand(capsuleDelete) + + capsuleGet := &cobra.Command{ + Use: "get", + Short: "Get one or more capsules", + Args: cobra.NoArgs, + Annotations: omitCapsuleIDAnnotation, + RunE: c.get, + ValidArgsFunction: common.NoCompletions, + } + capsuleGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") + capsuleGet.Flags().IntVarP(&offset, "offset", "o", 0, "offset for pagination") + capsuleGet.Flags().IntVarP(&limit, "limit", "l", 10, "limit for pagination") + capsuleGet.RegisterFlagCompletionFunc("json", common.BoolCompletions) + capsuleGet.RegisterFlagCompletionFunc("offset", common.NoCompletions) + capsuleGet.RegisterFlagCompletionFunc("limit", common.NoCompletions) + capsuleCmd.AddCommand(capsuleGet) + + capsuleConfig := &cobra.Command{ + Use: "config", + Short: "Configure the capsule", + Args: cobra.NoArgs, + RunE: c.config, + ValidArgsFunction: common.NoCompletions, + } + capsuleConfig.Flags().Bool("auto-add-service-account", false, "automatically add the rig service account to the capsule") + capsuleConfig.Flags().StringVar(&command, "cmd", "", "Container CMD to run") + capsuleConfig.Flags().StringSliceVar(&args, "args", []string{}, "Container CMD args") + capsuleConfig.RegisterFlagCompletionFunc("auto-add-service-account", common.BoolCompletions) + capsuleConfig.RegisterFlagCompletionFunc("cmd", common.NoCompletions) + capsuleConfig.RegisterFlagCompletionFunc("args", common.NoCompletions) + capsuleCmd.AddCommand(capsuleConfig) + + c.Resources.Setup(capsuleCmd) + c.BuildDeploy.Setup(capsuleCmd) + c.Instance.Setup(capsuleCmd) + c.Network.Setup(capsuleCmd) + c.Rollout.Setup(capsuleCmd) + c.Env.Setup(capsuleCmd) + c.Mount.Setup(capsuleCmd) + + parent.AddCommand(capsuleCmd) +} + +func (c Cmd) completions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + var capsuleIDs []string + + if c.Cfg.GetCurrentContext() == nil || c.Cfg.GetCurrentAuth() == nil { + return nil, cobra.ShellCompDirectiveError + } + + resp, err := c.Rig.Capsule().List(c.Ctx, &connect.Request[capsule_api.ListRequest]{ + Msg: &capsule_api.ListRequest{}, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, c := range resp.Msg.GetCapsules() { + if strings.HasPrefix(c.GetCapsuleId(), toComplete) { + capsuleIDs = append(capsuleIDs, formatCapsule(c)) + } + } + + if len(capsuleIDs) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + return capsuleIDs, cobra.ShellCompDirectiveDefault +} + +func formatCapsule(c *capsule_api.Capsule) string { + var age string + if c.GetCurrentRollout() == 0 { + age = "-" + } else { + age = time.Since(c.GetUpdatedAt().AsTime()).Truncate(time.Second).String() + } + + return fmt.Sprintf("%v\t (Rollout: %v, Updated At: %v)", c.GetCapsuleId(), c.GetCurrentRollout(), age) +} diff --git a/cmd/rig/cmd/capsule/setup.go b/cmd/rig/cmd/capsule/setup.go deleted file mode 100644 index 6fd441f88..000000000 --- a/cmd/rig/cmd/capsule/setup.go +++ /dev/null @@ -1,140 +0,0 @@ -package capsule - -import ( - "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/base" - "github.com/spf13/cobra" -) - -var ( - offset int - limit int -) - -var ( - interactive bool - outputJSON bool - remote bool -) - -var ( - CapsuleID string - image string - buildID string - command string -) - -var ( - args []string -) - -var omitCapsuleIDAnnotation = map[string]string{ - "OMIT_CAPSULE_ID": "true", -} - -func Setup(parent *cobra.Command) *cobra.Command { - capsuleCmd := &cobra.Command{ - Use: "capsule", - Short: "Manage capsules", - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - if cmd.Annotations["OMIT_CAPSULE_ID"] != "" { - return nil - } - - if CapsuleID == "" { - var err error - CapsuleID, err = common.PromptInput("Capsule id:", common.ValidateNonEmptyOpt) - if err != nil { - return err - } - } - return nil - }, - } - capsuleCmd.PersistentFlags().StringVarP(&CapsuleID, "capsule-id", "c", "", "Id of the capsule") - capsuleCmd.RegisterFlagCompletionFunc("capsule-id", capsuleCompletions) - - capsuleCreate := &cobra.Command{ - Use: "create", - Short: "Create a new capsule", - Args: cobra.NoArgs, - RunE: base.Register(create), - Annotations: omitCapsuleIDAnnotation, - ValidArgsFunction: common.NoCompletions, - } - capsuleCreate.Flags().BoolVarP(&interactive, "interactive", "i", false, "interactive mode") - capsuleCreate.RegisterFlagCompletionFunc("interactive", common.BoolCompletions) - - capsuleCmd.AddCommand(capsuleCreate) - - capsuleDeploy := &cobra.Command{ - Use: "deploy", - Short: "Deploy the given build to a capsule", - Args: cobra.NoArgs, - RunE: base.Register(deploy), - Long: `Deploy either the given rig-build or docker image to a capsule. -If --build-id is given rig tries to find a matching existing rig-build to deploy. -If --image is given rig tries to create a new rig-build from the docker image (if it doesn't already exist) -Not both --build-id and --image can be given`, - } - capsuleDeploy.Flags().StringVarP(&buildID, "build-id", "b", "", "rig build id to deploy") - capsuleDeploy.Flags().StringVarP(&image, "image", "i", "", "docker image to deploy. Will create a new rig-build from the image if it doesn't exist") - capsuleDeploy.Flags().BoolVarP(&remote, "remote", "r", false, "if --image is also given, Rig will assume the image is from a remote registry. If not set, Rig will search locally and then remotely") - capsuleDeploy.RegisterFlagCompletionFunc("build-id", BuildCompletions) - capsuleDeploy.RegisterFlagCompletionFunc("image", common.NoCompletions) - capsuleDeploy.RegisterFlagCompletionFunc("remote", common.BoolCompletions) - capsuleCmd.AddCommand(capsuleDeploy) - - capsuleAbort := &cobra.Command{ - Use: "abort", - Short: "Abort the current rollout. This will leave the capsule in a undefined state", - Args: cobra.NoArgs, - RunE: base.Register(abort), - ValidArgsFunction: common.NoCompletions, - } - capsuleCmd.AddCommand(capsuleAbort) - - capsuleDelete := &cobra.Command{ - Use: "delete", - Short: "Delete a capsule", - Args: cobra.NoArgs, - RunE: base.Register(delete), - ValidArgsFunction: common.NoCompletions, - } - capsuleCmd.AddCommand(capsuleDelete) - - capsuleGet := &cobra.Command{ - Use: "get", - Short: "Get one or more capsules", - Args: cobra.NoArgs, - Annotations: omitCapsuleIDAnnotation, - RunE: base.Register(get), - ValidArgsFunction: common.NoCompletions, - } - capsuleGet.Flags().BoolVar(&outputJSON, "json", false, "output as json") - capsuleGet.Flags().IntVarP(&offset, "offset", "o", 0, "offset for pagination") - capsuleGet.Flags().IntVarP(&limit, "limit", "l", 10, "limit for pagination") - capsuleGet.RegisterFlagCompletionFunc("json", common.BoolCompletions) - capsuleGet.RegisterFlagCompletionFunc("offset", common.NoCompletions) - capsuleGet.RegisterFlagCompletionFunc("limit", common.NoCompletions) - capsuleCmd.AddCommand(capsuleGet) - - capsuleConfig := &cobra.Command{ - Use: "config", - Short: "Configure the capsule", - Args: cobra.NoArgs, - RunE: base.Register(config), - ValidArgsFunction: common.NoCompletions, - } - capsuleConfig.Flags().Bool("auto-add-service-account", false, "automatically add the rig service account to the capsule") - capsuleConfig.Flags().StringVar(&command, "cmd", "", "Container CMD to run") - capsuleConfig.Flags().StringSliceVar(&args, "args", []string{}, "Container CMD args") - capsuleConfig.RegisterFlagCompletionFunc("auto-add-service-account", common.BoolCompletions) - capsuleConfig.RegisterFlagCompletionFunc("cmd", common.NoCompletions) - capsuleConfig.RegisterFlagCompletionFunc("args", common.NoCompletions) - capsuleCmd.AddCommand(capsuleConfig) - - parent.AddCommand(capsuleCmd) - - return capsuleCmd -} diff --git a/cmd/rig/cmd/cluster/getconfig.go b/cmd/rig/cmd/cluster/getconfig.go index ee58476a7..a41ae7072 100644 --- a/cmd/rig/cmd/cluster/getconfig.go +++ b/cmd/rig/cmd/cluster/getconfig.go @@ -1,18 +1,17 @@ package cluster import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/cluster" - "github.com/rigdev/rig-go-sdk" "github.com/spf13/cobra" "gopkg.in/yaml.v3" ) -func GetConfig(ctx context.Context, cmd *cobra.Command, client rig.Client) error { - resp, err := client.Cluster().GetConfig(ctx, connect.NewRequest(&cluster.GetConfigRequest{})) +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.Cluster().GetConfig(ctx, connect.NewRequest(&cluster.GetConfigRequest{})) if err != nil { return err } diff --git a/cmd/rig/cmd/cluster/setup.go b/cmd/rig/cmd/cluster/setup.go index 217d3589e..99cecc4a1 100644 --- a/cmd/rig/cmd/cluster/setup.go +++ b/cmd/rig/cmd/cluster/setup.go @@ -1,11 +1,21 @@ package cluster import ( - "github.com/rigdev/rig/cmd/rig/cmd/base" + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/spf13/cobra" + "go.uber.org/fx" ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client +} + +func (c Cmd) Setup(parent *cobra.Command) { cluster := &cobra.Command{ Use: "cluster", Short: "Manage Rig clusters", @@ -15,7 +25,7 @@ func Setup(parent *cobra.Command) { Use: "get-config", Short: "Returns the config of the Rig cluster", Args: cobra.NoArgs, - RunE: base.Register(GetConfig), + RunE: c.get, } cluster.AddCommand(getConfig) diff --git a/cmd/rig/cmd/config/init.go b/cmd/rig/cmd/config/init.go index f966f176f..e168dd46a 100644 --- a/cmd/rig/cmd/config/init.go +++ b/cmd/rig/cmd/config/init.go @@ -1,21 +1,19 @@ package config import ( - "context" "fmt" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" - "go.uber.org/zap" ) -func ConfigInit(ctx context.Context, cmd *cobra.Command, cfg *cmd_config.Config, logger *zap.Logger) error { +func (c Cmd) init(cmd *cobra.Command, args []string) error { if ok, err := common.PromptConfirm("Do you want to configure a new context?", true); err != nil { return err } else if !ok { return fmt.Errorf("aborted") } - return cmd_config.CreateDefaultContext(cfg) + return cmd_config.CreateDefaultContext(c.Cfg) } diff --git a/cmd/rig/cmd/config/setup.go b/cmd/rig/cmd/config/setup.go index df815f7e6..a97ec2f93 100644 --- a/cmd/rig/cmd/config/setup.go +++ b/cmd/rig/cmd/config/setup.go @@ -1,11 +1,24 @@ package config import ( + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { config := &cobra.Command{ Use: "config", Short: "Manage Rig CLI configuration", @@ -15,7 +28,7 @@ func Setup(parent *cobra.Command) { Use: "init", Short: "Initialize a new context", Args: cobra.NoArgs, - RunE: base.Register(ConfigInit), + RunE: c.init, Annotations: map[string]string{ base.OmitProject: "", base.OmitUser: "", @@ -27,7 +40,7 @@ func Setup(parent *cobra.Command) { Use: "use-context [context]", Short: "Change the current context to use", Args: cobra.MaximumNArgs(1), - RunE: base.Register(ConfigUseContext), + RunE: c.useContext, Annotations: map[string]string{ base.OmitProject: "", base.OmitUser: "", diff --git a/cmd/rig/cmd/config/use_context.go b/cmd/rig/cmd/config/use_context.go index d86845adc..cc3f89b4d 100644 --- a/cmd/rig/cmd/config/use_context.go +++ b/cmd/rig/cmd/config/use_context.go @@ -2,12 +2,13 @@ package config import ( "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" + "github.com/spf13/cobra" ) -func ConfigUseContext(args []string, cfg *cmd_config.Config) error { +func (c Cmd) useContext(cmd *cobra.Command, args []string) error { if len(args) > 0 { - return cmd_config.UseContext(cfg, args[0]) + return cmd_config.UseContext(c.Cfg, args[0]) } - return cmd_config.SelectContext(cfg) + return cmd_config.SelectContext(c.Cfg) } diff --git a/cmd/rig/cmd/database/connect.go b/cmd/rig/cmd/database/connect.go index a0b65fb66..70cb0cf33 100644 --- a/cmd/rig/cmd/database/connect.go +++ b/cmd/rig/cmd/database/connect.go @@ -1,21 +1,19 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func Connect(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) connect(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetDatabase(ctx, identifier, nc) + _, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } @@ -34,7 +32,7 @@ func Connect(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clie } } - endpointRes, err := nc.Database().GetEndpoint(ctx, &connect.Request[database.GetEndpointRequest]{ + endpointRes, err := c.Rig.Database().GetEndpoint(ctx, &connect.Request[database.GetEndpointRequest]{ Msg: &database.GetEndpointRequest{ DatabaseId: id, ClientId: clientID, diff --git a/cmd/rig/cmd/database/create.go b/cmd/rig/cmd/database/create.go index f775e21e8..1f6ecf307 100644 --- a/cmd/rig/cmd/database/create.go +++ b/cmd/rig/cmd/database/create.go @@ -1,16 +1,14 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func Create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error if name == "" { name, err = common.PromptInput("Database name:", common.ValidateNonEmptyOpt) @@ -31,7 +29,7 @@ func Create(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Clien return err } - res, err := nc.Database().Create(ctx, &connect.Request[database.CreateRequest]{Msg: &database.CreateRequest{ + res, err := c.Rig.Database().Create(ctx, &connect.Request[database.CreateRequest]{Msg: &database.CreateRequest{ Initializers: []*database.Update{ {Field: &database.Update_Name{Name: name}}, }, diff --git a/cmd/rig/cmd/database/create_credential.go b/cmd/rig/cmd/database/create_credential.go index 10adcdb1a..5c1c27019 100644 --- a/cmd/rig/cmd/database/create_credential.go +++ b/cmd/rig/cmd/database/create_credential.go @@ -1,21 +1,19 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func CreateCredential(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) createCredentials(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetDatabase(ctx, identifier, nc) + _, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } @@ -26,7 +24,7 @@ func CreateCredential(ctx context.Context, cmd *cobra.Command, args []string, nc return err } } - res, err := nc.Database().CreateCredential(ctx, &connect.Request[database.CreateCredentialRequest]{ + res, err := c.Rig.Database().CreateCredential(ctx, &connect.Request[database.CreateCredentialRequest]{ Msg: &database.CreateCredentialRequest{ DatabaseId: id, Name: name, diff --git a/cmd/rig/cmd/database/create_table.go b/cmd/rig/cmd/database/create_table.go index bde5064ba..7147eb75f 100644 --- a/cmd/rig/cmd/database/create_table.go +++ b/cmd/rig/cmd/database/create_table.go @@ -1,21 +1,19 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func CreateTable(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) createTable(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetDatabase(ctx, identifier, nc) + _, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } @@ -27,7 +25,7 @@ func CreateTable(ctx context.Context, cmd *cobra.Command, args []string, nc rig. } } - if _, err := nc.Database().CreateTable(ctx, &connect.Request[database.CreateTableRequest]{ + if _, err := c.Rig.Database().CreateTable(ctx, &connect.Request[database.CreateTableRequest]{ Msg: &database.CreateTableRequest{ DatabaseId: id, TableName: name, diff --git a/cmd/rig/cmd/database/delete.go b/cmd/rig/cmd/database/delete.go index 178b123e8..95d03d323 100644 --- a/cmd/rig/cmd/database/delete.go +++ b/cmd/rig/cmd/database/delete.go @@ -1,26 +1,24 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func Delete(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) delete(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - db, id, err := common.GetDatabase(ctx, identifier, nc) + db, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } - if _, err := nc.Database().Delete(ctx, &connect.Request[database.DeleteRequest]{ + if _, err := c.Rig.Database().Delete(ctx, &connect.Request[database.DeleteRequest]{ Msg: &database.DeleteRequest{ DatabaseId: id, }, diff --git a/cmd/rig/cmd/database/delete_credential.go b/cmd/rig/cmd/database/delete_credential.go index 872e50ad8..e3ded666e 100644 --- a/cmd/rig/cmd/database/delete_credential.go +++ b/cmd/rig/cmd/database/delete_credential.go @@ -1,21 +1,19 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func DeleteCredential(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) deleteCredential(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetDatabase(ctx, identifier, nc) + _, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } @@ -27,7 +25,7 @@ func DeleteCredential(ctx context.Context, cmd *cobra.Command, args []string, nc } } - if _, err := nc.Database().DeleteCredential(ctx, &connect.Request[database.DeleteCredentialRequest]{ + if _, err := c.Rig.Database().DeleteCredential(ctx, &connect.Request[database.DeleteCredentialRequest]{ Msg: &database.DeleteCredentialRequest{ DatabaseId: id, CredentialName: name, diff --git a/cmd/rig/cmd/database/delete_table.go b/cmd/rig/cmd/database/delete_table.go index 733870524..eafe3c347 100644 --- a/cmd/rig/cmd/database/delete_table.go +++ b/cmd/rig/cmd/database/delete_table.go @@ -1,21 +1,19 @@ package database import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func DeleteTable(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) deleteTable(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetDatabase(ctx, identifier, nc) + _, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } @@ -27,7 +25,7 @@ func DeleteTable(ctx context.Context, cmd *cobra.Command, args []string, nc rig. } } - if _, err := nc.Database().DeleteTable(ctx, &connect.Request[database.DeleteTableRequest]{ + if _, err := c.Rig.Database().DeleteTable(ctx, &connect.Request[database.DeleteTableRequest]{ Msg: &database.DeleteTableRequest{ DatabaseId: id, TableName: name, diff --git a/cmd/rig/cmd/database/get.go b/cmd/rig/cmd/database/get.go index 5b8a18aa7..c9ee201ff 100644 --- a/cmd/rig/cmd/database/get.go +++ b/cmd/rig/cmd/database/get.go @@ -1,20 +1,18 @@ package database import ( - "context" - "github.com/jedib0t/go-pretty/v6/table" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func Get(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - db, id, err := common.GetDatabase(ctx, identifier, nc) + db, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/database/list.go b/cmd/rig/cmd/database/list.go index b2182b3d4..e6532a530 100644 --- a/cmd/rig/cmd/database/list.go +++ b/cmd/rig/cmd/database/list.go @@ -1,20 +1,19 @@ package database import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/database" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func List(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { - res, err := nc.Database().List(ctx, &connect.Request[database.ListRequest]{ +func (c Cmd) list(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + res, err := c.Rig.Database().List(ctx, &connect.Request[database.ListRequest]{ Msg: &database.ListRequest{ Pagination: &model.Pagination{ Offset: uint32(offset), diff --git a/cmd/rig/cmd/database/list_tables.go b/cmd/rig/cmd/database/list_tables.go index df7e25d8e..bc6bb2bfc 100644 --- a/cmd/rig/cmd/database/list_tables.go +++ b/cmd/rig/cmd/database/list_tables.go @@ -1,29 +1,28 @@ package database import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/database" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func ListTables(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) listTables(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetDatabase(ctx, identifier, nc) + _, id, err := common.GetDatabase(ctx, identifier, c.Rig) if err != nil { return err } - res, err := nc.Database().ListTables(ctx, &connect.Request[database.ListTablesRequest]{ + res, err := c.Rig.Database().ListTables(ctx, &connect.Request[database.ListTablesRequest]{ Msg: &database.ListTablesRequest{ DatabaseId: id, Pagination: &model.Pagination{ diff --git a/cmd/rig/cmd/database/setup.go b/cmd/rig/cmd/database/setup.go index 20f2db6f9..62fbf1bb4 100644 --- a/cmd/rig/cmd/database/setup.go +++ b/cmd/rig/cmd/database/setup.go @@ -1,12 +1,15 @@ package database import ( + "context" "errors" "fmt" "github.com/rigdev/rig-go-api/api/v1/database" - "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig-go-sdk" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -25,14 +28,22 @@ var ( clientSecret string ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { database := &cobra.Command{ Use: "database", } createDatabase := &cobra.Command{ Use: "create", - RunE: base.Register(Create), + RunE: c.create, Args: cobra.NoArgs, } createDatabase.Flags().StringVarP(&name, "name", "n", "", "name of the database") @@ -41,7 +52,7 @@ func Setup(parent *cobra.Command) { createDatabaseCredential := &cobra.Command{ Use: "create-credentials [id | db-name]", - RunE: base.Register(CreateCredential), + RunE: c.createCredentials, Args: cobra.MaximumNArgs(1), } createDatabaseCredential.Flags().StringVarP(&name, "name", "n", "", "name of the credentials") @@ -49,7 +60,7 @@ func Setup(parent *cobra.Command) { deleteCredential := &cobra.Command{ Use: "delete-credentials [id | db-name]", - RunE: base.Register(DeleteCredential), + RunE: c.deleteCredential, Args: cobra.MaximumNArgs(1), } deleteCredential.Flags().StringVarP(&name, "name", "n", "", "name of the credentials") @@ -57,7 +68,7 @@ func Setup(parent *cobra.Command) { getDatabase := &cobra.Command{ Use: "get [id | name]", - RunE: base.Register(Get), + RunE: c.get, Args: cobra.MaximumNArgs(1), } getDatabase.Flags().BoolVar(&outputJSON, "json", false, "output as json") @@ -65,7 +76,7 @@ func Setup(parent *cobra.Command) { connect := &cobra.Command{ Use: "connect [id | name]", - RunE: base.Register(Connect), + RunE: c.connect, Args: cobra.MaximumNArgs(1), } connect.Flags().StringVarP(&clientID, "client-id", "i", "", "client id") @@ -74,7 +85,7 @@ func Setup(parent *cobra.Command) { delete := &cobra.Command{ Use: "delete [id | name]", - RunE: base.Register(Delete), + RunE: c.delete, Args: cobra.MaximumNArgs(1), } database.AddCommand(delete) @@ -82,7 +93,7 @@ func Setup(parent *cobra.Command) { list := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, - RunE: base.Register(List), + RunE: c.list, Args: cobra.NoArgs, } list.Flags().BoolVar(&outputJSON, "json", false, "output as json") @@ -92,7 +103,7 @@ func Setup(parent *cobra.Command) { createTable := &cobra.Command{ Use: "create-table [id | db-name]", - RunE: base.Register(CreateTable), + RunE: c.createTable, Args: cobra.MaximumNArgs(1), } createTable.Flags().StringVarP(&name, "name", "n", "", "name of the table") @@ -100,7 +111,7 @@ func Setup(parent *cobra.Command) { listTables := &cobra.Command{ Use: "list-tables [id | name]", - RunE: base.Register(ListTables), + RunE: c.listTables, Args: cobra.MaximumNArgs(1), } listTables.Flags().BoolVar(&outputJSON, "json", false, "output as json") @@ -110,7 +121,7 @@ func Setup(parent *cobra.Command) { deleteTable := &cobra.Command{ Use: "delete-table [id | db-name]", - RunE: base.Register(DeleteTable), + RunE: c.deleteTable, Args: cobra.MaximumNArgs(1), } deleteTable.Flags().StringVarP(&name, "name", "n", "", "name of the table") diff --git a/cmd/rig/cmd/dev/kind/create.go b/cmd/rig/cmd/dev/kind/create.go index 578fba0a5..111a83e8c 100644 --- a/cmd/rig/cmd/dev/kind/create.go +++ b/cmd/rig/cmd/dev/kind/create.go @@ -16,9 +16,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/client" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" + "github.com/spf13/cobra" "golang.org/x/exp/slices" "sigs.k8s.io/kind/pkg/cluster" ) @@ -33,7 +33,8 @@ var config string //go:embed registry.yaml var registry string -func Create(ctx context.Context, dc *client.Client, cfg *cmd_config.Config) error { +func (c Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx if err := checkBinaries(kubectl, kind, helm); err != nil { return err } @@ -50,11 +51,11 @@ func Create(ctx context.Context, dc *client.Client, cfg *cmd_config.Config) erro return err } - if err := Deploy(ctx, dc); err != nil { + if err := c.deploy(cmd, args); err != nil { return err } - if err := setupKindContext(ctx, cfg); err != nil { + if err := c.setupKindContext(ctx); err != nil { return err } @@ -66,7 +67,8 @@ func Create(ctx context.Context, dc *client.Client, cfg *cmd_config.Config) erro return nil } -func Deploy(ctx context.Context, dc *client.Client) error { +func (c Cmd) deploy(cmd *cobra.Command, args []string) error { + ctx := c.Ctx if err := checkBinaries(kind, kubectl, helm, docker); err != nil { return err } @@ -80,7 +82,7 @@ func Deploy(ctx context.Context, dc *client.Client) error { } dockerTag = strings.TrimPrefix(dockerTag, "v") rigImage := fmt.Sprintf("ghcr.io/rigdev/rig:%s", dockerTag) - res, err := dc.ImageList(ctx, types.ImageListOptions{ + res, err := c.DockerClient.ImageList(ctx, types.ImageListOptions{ Filters: filters.NewArgs(filters.KeyValuePair{ Key: "reference", Value: rigImage, @@ -110,7 +112,7 @@ func Deploy(ctx context.Context, dc *client.Client) error { if chartPath != "" { chart = chartPath } - args := []string{ + cArgs := []string{ "--kube-context", "kind-rig", "upgrade", "--install", "rig", chart, "--namespace", "rig-system", @@ -124,11 +126,11 @@ func Deploy(ctx context.Context, dc *client.Client) error { "--create-namespace", } if chartPath == "" { - args = append(args, "--repo", "https://charts.rig.dev") + cArgs = append(args, "--repo", "https://charts.rig.dev") } if err := runCmd( - "helm", args..., + "helm", cArgs..., ); err != nil { return err } @@ -140,7 +142,7 @@ func Deploy(ctx context.Context, dc *client.Client) error { return nil } -func Clean() error { +func (c Cmd) clean(cmd *cobra.Command, args []string) error { if err := checkBinaries(kind); err != nil { return err } @@ -281,7 +283,7 @@ func helmInstall() error { return nil } -func setupKindContext(ctx context.Context, cfg *cmd_config.Config) error { +func (c Cmd) setupKindContext(ctx context.Context) error { fmt.Println("") fmt.Println("Rig on the Kind cluster listens on the port 30047. This requires you to use a different context than the default one which uses port 4747.") ok, err := common.PromptConfirm("Create a new context which uses port 30047?", true) @@ -289,7 +291,7 @@ func setupKindContext(ctx context.Context, cfg *cmd_config.Config) error { return err } if ok { - if err := cmd_config.CreateContext(cfg, "kind", "http://localhost:30047/"); err != nil { + if err := cmd_config.CreateContext(c.Cfg, "kind", "http://localhost:30047/"); err != nil { return err } return nil @@ -302,7 +304,7 @@ func setupKindContext(ctx context.Context, cfg *cmd_config.Config) error { if !ok { return nil } - return cmd_config.SelectContext(cfg) + return cmd_config.SelectContext(c.Cfg) } type binary struct { diff --git a/cmd/rig/cmd/dev/kind/setup.go b/cmd/rig/cmd/dev/kind/setup.go index 50324d6a1..f3c5fa638 100644 --- a/cmd/rig/cmd/dev/kind/setup.go +++ b/cmd/rig/cmd/dev/kind/setup.go @@ -1,8 +1,14 @@ package kind import ( + "context" + + "github.com/docker/docker/client" + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -11,7 +17,16 @@ var ( chartPath string ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + DockerClient *client.Client + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c *Cmd) Setup(parent *cobra.Command) { kind := &cobra.Command{ Use: "kind", Short: "The kind command is used to setup and manage a development kubernetes cluster running Rig using Kind", @@ -21,7 +36,7 @@ func Setup(parent *cobra.Command) { Use: "create", Short: "Create a rig cluster in Kind for local development", Args: cobra.NoArgs, - RunE: base.Register(Create), + RunE: c.create, Annotations: map[string]string{ base.OmitUser: "", base.OmitProject: "", @@ -36,7 +51,7 @@ func Setup(parent *cobra.Command) { Use: "deploy", Short: "Deploy a new (or specific) version of Rig to the kind cluster", Args: cobra.NoArgs, - RunE: base.Register(Deploy), + RunE: c.deploy, Annotations: map[string]string{ base.OmitUser: "", base.OmitProject: "", @@ -51,7 +66,7 @@ func Setup(parent *cobra.Command) { Use: "clean", Short: "Deletes the rig kind-cluster", Args: cobra.NoArgs, - RunE: base.Register(Clean), + RunE: c.clean, Annotations: map[string]string{ base.OmitUser: "", base.OmitProject: "", diff --git a/cmd/rig/cmd/dev/setup.go b/cmd/rig/cmd/dev/setup.go index a66d26a01..35299d21c 100644 --- a/cmd/rig/cmd/dev/setup.go +++ b/cmd/rig/cmd/dev/setup.go @@ -3,13 +3,21 @@ package dev import ( "github.com/rigdev/rig/cmd/rig/cmd/dev/kind" "github.com/spf13/cobra" + "go.uber.org/fx" ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Kind kind.Cmd +} + +func (d *Cmd) Setup(parent *cobra.Command) { dev := &cobra.Command{ Use: "dev", } - kind.Setup(dev) + + d.Kind.Setup(dev) parent.AddCommand(dev) } diff --git a/cmd/rig/cmd/group/create.go b/cmd/rig/cmd/group/create.go index d6cab9bcf..004d647b2 100644 --- a/cmd/rig/cmd/group/create.go +++ b/cmd/rig/cmd/group/create.go @@ -1,16 +1,14 @@ package group import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/group" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func GroupCreate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error if name == "" { name, err = common.PromptInput("Name:", common.ValidateNonEmptyOpt) @@ -27,7 +25,7 @@ func GroupCreate(ctx context.Context, cmd *cobra.Command, args []string, nc rig. }, } - res, err := nc.Group().Create(ctx, &connect.Request[group.CreateRequest]{ + res, err := c.Rig.Group().Create(ctx, &connect.Request[group.CreateRequest]{ Msg: &group.CreateRequest{ Initializers: updates, }, diff --git a/cmd/rig/cmd/group/delete.go b/cmd/rig/cmd/group/delete.go index 0d7b69582..f8a33d8c6 100644 --- a/cmd/rig/cmd/group/delete.go +++ b/cmd/rig/cmd/group/delete.go @@ -1,27 +1,25 @@ package group import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/group" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func GroupDelete(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) delete(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - g, uid, err := common.GetGroup(ctx, identifier, nc) + g, uid, err := common.GetGroup(ctx, identifier, c.Rig) if err != nil { return err } - _, err = nc.Group().Delete(ctx, &connect.Request[group.DeleteRequest]{ + _, err = c.Rig.Group().Delete(ctx, &connect.Request[group.DeleteRequest]{ Msg: &group.DeleteRequest{ GroupId: uid, }, diff --git a/cmd/rig/cmd/group/get.go b/cmd/rig/cmd/group/get.go index 42d4fc2dc..4a95a9bcc 100644 --- a/cmd/rig/cmd/group/get.go +++ b/cmd/rig/cmd/group/get.go @@ -1,20 +1,18 @@ package group import ( - "context" - "github.com/jedib0t/go-pretty/v6/table" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func GroupGet(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - g, uid, err := common.GetGroup(ctx, identifier, nc) + g, uid, err := common.GetGroup(ctx, identifier, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/group/list.go b/cmd/rig/cmd/group/list.go index 38d380cd3..1c7d5a8a5 100644 --- a/cmd/rig/cmd/group/list.go +++ b/cmd/rig/cmd/group/list.go @@ -1,7 +1,6 @@ package group import ( - "context" "fmt" "strings" @@ -9,12 +8,12 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/group" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func GroupList(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) list(cmd *cobra.Command, args []string) error { + ctx := c.Ctx search := strings.Join(args, " ") req := &group.ListRequest{ Pagination: &model.Pagination{ @@ -23,7 +22,7 @@ func GroupList(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl }, Search: search, } - resp, err := nc.Group().List(ctx, &connect.Request[group.ListRequest]{Msg: req}) + resp, err := c.Rig.Group().List(ctx, &connect.Request[group.ListRequest]{Msg: req}) if err != nil { return err } diff --git a/cmd/rig/cmd/group/list_groups_for_user.go b/cmd/rig/cmd/group/list_groups_for_user.go index 91f651745..60cefe8df 100644 --- a/cmd/rig/cmd/group/list_groups_for_user.go +++ b/cmd/rig/cmd/group/list_groups_for_user.go @@ -1,29 +1,28 @@ package group import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/group" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func GroupListGroupsForUser(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) listGroupsForUser(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, uid, err := common.GetUser(ctx, identifier, nc) + _, uid, err := common.GetUser(ctx, identifier, c.Rig) if err != nil { return err } - resp, err := nc.Group().ListGroupsForUser(ctx, &connect.Request[group.ListGroupsForUserRequest]{ + resp, err := c.Rig.Group().ListGroupsForUser(ctx, &connect.Request[group.ListGroupsForUserRequest]{ Msg: &group.ListGroupsForUserRequest{ UserId: uid, Pagination: &model.Pagination{ diff --git a/cmd/rig/cmd/group/list_members.go b/cmd/rig/cmd/group/list_members.go index aa856b493..2d003e0c0 100644 --- a/cmd/rig/cmd/group/list_members.go +++ b/cmd/rig/cmd/group/list_members.go @@ -1,28 +1,27 @@ package group import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/group" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func GroupListMembers(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) listMembers(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, uid, err := common.GetGroup(ctx, identifier, nc) + _, uid, err := common.GetGroup(ctx, identifier, c.Rig) if err != nil { return err } - resp, err := nc.Group().ListMembers(ctx, &connect.Request[group.ListMembersRequest]{ + resp, err := c.Rig.Group().ListMembers(ctx, &connect.Request[group.ListMembersRequest]{ Msg: &group.ListMembersRequest{ GroupId: uid, }, diff --git a/cmd/rig/cmd/group/setup.go b/cmd/rig/cmd/group/setup.go index 0921e13a9..cb239a4fc 100644 --- a/cmd/rig/cmd/group/setup.go +++ b/cmd/rig/cmd/group/setup.go @@ -1,8 +1,11 @@ package group import ( - "github.com/rigdev/rig/cmd/rig/cmd/base" + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -18,7 +21,14 @@ var ( name string ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client +} + +func (c Cmd) Setup(parent *cobra.Command) { group := &cobra.Command{ Use: "group", Short: "Manage user groups", @@ -26,7 +36,7 @@ func Setup(parent *cobra.Command) { create := &cobra.Command{ Use: "create", - RunE: base.Register(GroupCreate), + RunE: c.create, Args: cobra.NoArgs, } create.Flags().StringVarP(&name, "name", "n", "", "name of the group") @@ -34,7 +44,7 @@ func Setup(parent *cobra.Command) { delete := &cobra.Command{ Use: "delete [group-id | group-name]", - RunE: base.Register(GroupDelete), + RunE: c.delete, Args: cobra.MaximumNArgs(1), } group.AddCommand(delete) @@ -42,14 +52,14 @@ func Setup(parent *cobra.Command) { update := &cobra.Command{ Use: "update [group-id | group-name]", Args: cobra.MaximumNArgs(1), - RunE: base.Register(GroupUpdate), + RunE: c.update, } group.AddCommand(update) get := &cobra.Command{ Use: "get [group-id | group-name]", Args: cobra.MaximumNArgs(1), - RunE: base.Register(GroupGet), + RunE: c.get, } get.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") group.AddCommand(get) @@ -58,7 +68,7 @@ func Setup(parent *cobra.Command) { Use: "list [search...]", Args: cobra.MinimumNArgs(0), Aliases: []string{"ls"}, - RunE: base.Register(GroupList), + RunE: c.list, } list.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") list.Flags().IntVarP(&limit, "limit", "l", 10, "limit the number of groups to return") @@ -67,7 +77,7 @@ func Setup(parent *cobra.Command) { listMembers := &cobra.Command{ Use: "list-members [group-id | group-name]", - RunE: base.Register(GroupListMembers), + RunE: c.listMembers, Args: cobra.MaximumNArgs(1), } listMembers.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") @@ -77,7 +87,7 @@ func Setup(parent *cobra.Command) { listGroupsForUser := &cobra.Command{ Use: "list-groups-for-user [user-id | {email|username|phone}]", - RunE: base.Register(GroupListGroupsForUser), + RunE: c.listGroupsForUser, Args: cobra.MaximumNArgs(1), } listGroupsForUser.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") diff --git a/cmd/rig/cmd/group/update.go b/cmd/rig/cmd/group/update.go index 6db35c298..931d45212 100644 --- a/cmd/rig/cmd/group/update.go +++ b/cmd/rig/cmd/group/update.go @@ -1,13 +1,11 @@ package group import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/group" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) @@ -34,12 +32,13 @@ func (f groupField) String() string { } } -func GroupUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) update(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - g, uid, err := common.GetGroup(ctx, identifier, nc) + g, uid, err := common.GetGroup(ctx, identifier, c.Rig) if err != nil { return err } @@ -70,7 +69,7 @@ func GroupUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc rig. } } - _, err = nc.Group().Update(ctx, &connect.Request[group.UpdateRequest]{ + _, err = c.Rig.Group().Update(ctx, &connect.Request[group.UpdateRequest]{ Msg: &group.UpdateRequest{ GroupId: uid, Updates: updates, diff --git a/cmd/rig/cmd/project/create.go b/cmd/rig/cmd/project/create.go index 4fcfec0df..6ec7b95f3 100644 --- a/cmd/rig/cmd/project/create.go +++ b/cmd/rig/cmd/project/create.go @@ -1,18 +1,15 @@ package project import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/project" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" ) -func ProjectCreate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client, cfg *cmd_config.Config) error { +func (c Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx if name == "" { var err error name, err = common.PromptInput("Project name:", common.ValidateNonEmptyOpt) @@ -29,7 +26,7 @@ func ProjectCreate(ctx context.Context, cmd *cobra.Command, args []string, nc ri }, } - res, err := nc.Project().Create(ctx, &connect.Request[project.CreateRequest]{ + res, err := c.Rig.Project().Create(ctx, &connect.Request[project.CreateRequest]{ Msg: &project.CreateRequest{ Initializers: initializers, }, @@ -42,7 +39,7 @@ func ProjectCreate(ctx context.Context, cmd *cobra.Command, args []string, nc ri cmd.Printf("Successfully created project %s with id %s \n", name, p.GetProjectId()) if useProject { - res, err := nc.Project().Use(ctx, &connect.Request[project.UseRequest]{ + res, err := c.Rig.Project().Use(ctx, &connect.Request[project.UseRequest]{ Msg: &project.UseRequest{ ProjectId: p.GetProjectId(), }, @@ -51,9 +48,9 @@ func ProjectCreate(ctx context.Context, cmd *cobra.Command, args []string, nc ri return err } - cfg.GetCurrentContext().Project.ProjectID = uuid.UUID(p.GetProjectId()) - cfg.GetCurrentContext().Project.ProjectToken = res.Msg.GetProjectToken() - if err := cfg.Save(); err != nil { + c.Cfg.GetCurrentContext().Project.ProjectID = uuid.UUID(p.GetProjectId()) + c.Cfg.GetCurrentContext().Project.ProjectToken = res.Msg.GetProjectToken() + if err := c.Cfg.Save(); err != nil { return err } diff --git a/cmd/rig/cmd/project/delete.go b/cmd/rig/cmd/project/delete.go index b7bc57510..b65dc9ce4 100644 --- a/cmd/rig/cmd/project/delete.go +++ b/cmd/rig/cmd/project/delete.go @@ -1,18 +1,16 @@ package project import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/project" - "github.com/rigdev/rig-go-sdk" "github.com/spf13/cobra" ) -func ProjectDelete(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) delete(cmd *cobra.Command, args []string) error { + ctx := c.Ctx req := &project.DeleteRequest{} - _, err := nc.Project().Delete(ctx, &connect.Request[project.DeleteRequest]{Msg: req}) + _, err := c.Rig.Project().Delete(ctx, &connect.Request[project.DeleteRequest]{Msg: req}) if err != nil { return err } diff --git a/cmd/rig/cmd/project/get.go b/cmd/rig/cmd/project/get.go index 9b599e6c7..24b49e899 100644 --- a/cmd/rig/cmd/project/get.go +++ b/cmd/rig/cmd/project/get.go @@ -1,19 +1,17 @@ package project import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/project" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func ProjectGet(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) get(cmd *cobra.Command, args []string) error { + ctx := c.Ctx req := &project.GetRequest{} - resp, err := nc.Project().Get(ctx, &connect.Request[project.GetRequest]{Msg: req}) + resp, err := c.Rig.Project().Get(ctx, &connect.Request[project.GetRequest]{Msg: req}) if err != nil { return err } diff --git a/cmd/rig/cmd/project/get_settings.go b/cmd/rig/cmd/project/get_settings.go index fce73acc0..ac836d744 100644 --- a/cmd/rig/cmd/project/get_settings.go +++ b/cmd/rig/cmd/project/get_settings.go @@ -1,19 +1,17 @@ package project import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/project/settings" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func ProjectGetSettings(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) getSettings(cmd *cobra.Command, args []string) error { + ctx := c.Ctx req := &settings.GetSettingsRequest{} - resp, err := nc.ProjectSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{Msg: req}) + resp, err := c.Rig.ProjectSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{Msg: req}) if err != nil { return err } diff --git a/cmd/rig/cmd/project/list.go b/cmd/rig/cmd/project/list.go index ea5b20019..c18147546 100644 --- a/cmd/rig/cmd/project/list.go +++ b/cmd/rig/cmd/project/list.go @@ -1,20 +1,18 @@ package project import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/project" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" ) -func ProjectList(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client, cfg *cmd_config.Config) error { +func (c Cmd) list(cmd *cobra.Command, args []string) error { + ctx := c.Ctx req := &project.ListRequest{ Pagination: &model.Pagination{ Offset: uint32(offset), @@ -22,7 +20,7 @@ func ProjectList(ctx context.Context, cmd *cobra.Command, args []string, nc rig. }, } - resp, err := nc.Project().List(ctx, &connect.Request[project.ListRequest]{Msg: req}) + resp, err := c.Rig.Project().List(ctx, &connect.Request[project.ListRequest]{Msg: req}) if err != nil { return err } diff --git a/cmd/rig/cmd/project/setup.go b/cmd/rig/cmd/project/setup.go index c6dc5119f..c5bebf03e 100644 --- a/cmd/rig/cmd/project/setup.go +++ b/cmd/rig/cmd/project/setup.go @@ -1,8 +1,13 @@ package project import ( + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -21,7 +26,15 @@ var ( useProject bool ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config +} + +func (c Cmd) Setup(parent *cobra.Command) { project := &cobra.Command{ Use: "project", Short: "Manage Rig projects", @@ -30,7 +43,7 @@ func Setup(parent *cobra.Command) { getSettings := &cobra.Command{ Use: "get-settings", Args: cobra.NoArgs, - RunE: base.Register(ProjectGetSettings), + RunE: c.getSettings, } getSettings.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") project.AddCommand(getSettings) @@ -38,7 +51,7 @@ func Setup(parent *cobra.Command) { updateSettings := &cobra.Command{ Use: "update-settings", Args: cobra.NoArgs, - RunE: base.Register(ProjectUpdateSettings), + RunE: c.updateSettings, } updateSettings.Flags().StringVarP(&field, "field", "f", "", "Field to update") updateSettings.Flags().StringVarP(&value, "value", "v", "", "Value to set") @@ -66,7 +79,7 @@ func Setup(parent *cobra.Command) { createProject := &cobra.Command{ Use: "create", Args: cobra.NoArgs, - RunE: base.Register(ProjectCreate), + RunE: c.create, Annotations: map[string]string{ base.OmitProject: "", }, @@ -78,14 +91,14 @@ func Setup(parent *cobra.Command) { deleteProject := &cobra.Command{ Use: "delete", Args: cobra.NoArgs, - RunE: base.Register(ProjectDelete), + RunE: c.delete, } project.AddCommand(deleteProject) getProject := &cobra.Command{ Use: "get ", Args: cobra.NoArgs, - RunE: base.Register(ProjectGet), + RunE: c.get, } getProject.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") project.AddCommand(getProject) @@ -93,7 +106,7 @@ func Setup(parent *cobra.Command) { updateProject := &cobra.Command{ Use: "update", Args: cobra.NoArgs, - RunE: base.Register(ProjectUpdate), + RunE: c.update, } updateProject.Flags().StringVarP(&field, "field", "f", "", "Field to update") updateProject.Flags().StringVarP(&value, "value", "v", "", "Value to set") @@ -118,7 +131,7 @@ func Setup(parent *cobra.Command) { listProjects := &cobra.Command{ Use: "list", Args: cobra.NoArgs, - RunE: base.Register(ProjectList), + RunE: c.list, Annotations: map[string]string{ base.OmitProject: "", }, @@ -132,7 +145,7 @@ func Setup(parent *cobra.Command) { Use: "use [project-id | project-name]", Short: "Set the project to query for project-scoped resources", Args: cobra.MaximumNArgs(1), - RunE: base.Register(ProjectUse), + RunE: c.use, } project.AddCommand(use) diff --git a/cmd/rig/cmd/project/update.go b/cmd/rig/cmd/project/update.go index 6c3c9407c..de1c03b79 100644 --- a/cmd/rig/cmd/project/update.go +++ b/cmd/rig/cmd/project/update.go @@ -1,12 +1,10 @@ package project import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/project" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" @@ -30,8 +28,9 @@ func (p projectField) String() string { } } -func ProjectUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { - resp, err := nc.Project().Get(ctx, &connect.Request[project.GetRequest]{Msg: &project.GetRequest{}}) +func (c Cmd) update(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.Project().Get(ctx, &connect.Request[project.GetRequest]{Msg: &project.GetRequest{}}) if err != nil { return err } @@ -42,7 +41,7 @@ func ProjectUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc ri return err } - _, err = nc.Project().Update(ctx, &connect.Request[project.UpdateRequest]{ + _, err = c.Rig.Project().Update(ctx, &connect.Request[project.UpdateRequest]{ Msg: &project.UpdateRequest{ Updates: []*project.Update{u}, }, @@ -79,7 +78,7 @@ func ProjectUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc ri } } - _, err = nc.Project().Update(ctx, connect.NewRequest(&project.UpdateRequest{ + _, err = c.Rig.Project().Update(ctx, connect.NewRequest(&project.UpdateRequest{ Updates: updates, })) if err != nil { diff --git a/cmd/rig/cmd/project/update_settings.go b/cmd/rig/cmd/project/update_settings.go index 48f2cb6b2..f37684dbd 100644 --- a/cmd/rig/cmd/project/update_settings.go +++ b/cmd/rig/cmd/project/update_settings.go @@ -1,14 +1,12 @@ package project import ( - "context" "fmt" "strconv" "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/project/settings" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" "google.golang.org/protobuf/encoding/protojson" @@ -92,8 +90,9 @@ func (f settingsField) String() string { } } -func ProjectUpdateSettings(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { - res, err := nc.ProjectSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{}) +func (c Cmd) updateSettings(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + res, err := c.Rig.ProjectSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{}) if err != nil { return err } @@ -107,7 +106,7 @@ func ProjectUpdateSettings(ctx context.Context, cmd *cobra.Command, args []strin return err } - _, err = nc.ProjectSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ + _, err = c.Rig.ProjectSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ Msg: &settings.UpdateSettingsRequest{ Updates: []*settings.Update{u}, }, @@ -153,7 +152,7 @@ func ProjectUpdateSettings(ctx context.Context, cmd *cobra.Command, args []strin return nil } - _, err = nc.ProjectSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ + _, err = c.Rig.ProjectSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ Msg: &settings.UpdateSettingsRequest{ Updates: updates, }, diff --git a/cmd/rig/cmd/project/use_project.go b/cmd/rig/cmd/project/use_project.go index ee297549d..5107ae983 100644 --- a/cmd/rig/cmd/project/use_project.go +++ b/cmd/rig/cmd/project/use_project.go @@ -5,25 +5,23 @@ import ( "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/project" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" - "go.uber.org/zap" ) -func ProjectUse(ctx context.Context, cmd *cobra.Command, args []string, client rig.Client, cfg *cmd_config.Config, logger *zap.Logger) error { +func (c Cmd) use(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var projectID uuid.UUID var err error if len(args) == 0 { - projectID, err = promptForProjectID(ctx, client) + projectID, err = c.promptForProjectID(ctx) } else { - projectID, err = projectIDFromArg(ctx, client, args[0]) + projectID, err = c.projectIDFromArg(ctx, args[0]) } - res, err := client.Project().Use(ctx, &connect.Request[project.UseRequest]{ + res, err := c.Rig.Project().Use(ctx, &connect.Request[project.UseRequest]{ Msg: &project.UseRequest{ ProjectId: projectID.String(), }, @@ -32,9 +30,9 @@ func ProjectUse(ctx context.Context, cmd *cobra.Command, args []string, client r return err } - cfg.GetCurrentContext().Project.ProjectID = projectID - cfg.GetCurrentContext().Project.ProjectToken = res.Msg.GetProjectToken() - if err := cfg.Save(); err != nil { + c.Cfg.GetCurrentContext().Project.ProjectID = projectID + c.Cfg.GetCurrentContext().Project.ProjectToken = res.Msg.GetProjectToken() + if err := c.Cfg.Save(); err != nil { return err } @@ -43,8 +41,8 @@ func ProjectUse(ctx context.Context, cmd *cobra.Command, args []string, client r return nil } -func promptForProjectID(ctx context.Context, client rig.Client) (uuid.UUID, error) { - res, err := client.Project().List(ctx, &connect.Request[project.ListRequest]{}) +func (c Cmd) promptForProjectID(ctx context.Context) (uuid.UUID, error) { + res, err := c.Rig.Project().List(ctx, &connect.Request[project.ListRequest]{}) if err != nil { return uuid.Nil, err } @@ -67,11 +65,11 @@ func promptForProjectID(ctx context.Context, client rig.Client) (uuid.UUID, erro return projectID, nil } -func projectIDFromArg(ctx context.Context, client rig.Client, projectArg string) (uuid.UUID, error) { +func (c Cmd) projectIDFromArg(ctx context.Context, projectArg string) (uuid.UUID, error) { if id, err := uuid.Parse(projectArg); err == nil { return id, nil } - res, err := client.Project().List(ctx, &connect.Request[project.ListRequest]{}) + res, err := c.Rig.Project().List(ctx, &connect.Request[project.ListRequest]{}) if err != nil { return uuid.Nil, err } diff --git a/cmd/rig/cmd/root.go b/cmd/rig/cmd/root.go index d5025827f..a8422ae14 100644 --- a/cmd/rig/cmd/root.go +++ b/cmd/rig/cmd/root.go @@ -1,16 +1,14 @@ package cmd import ( + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/rig/cmd/auth" - "github.com/rigdev/rig/cmd/rig/cmd/capsule" - capsuleBuild "github.com/rigdev/rig/cmd/rig/cmd/capsule/build" - "github.com/rigdev/rig/cmd/rig/cmd/capsule/env" - "github.com/rigdev/rig/cmd/rig/cmd/capsule/instance" - "github.com/rigdev/rig/cmd/rig/cmd/capsule/mount" - "github.com/rigdev/rig/cmd/rig/cmd/capsule/network" - "github.com/rigdev/rig/cmd/rig/cmd/capsule/resource" - "github.com/rigdev/rig/cmd/rig/cmd/capsule/rollout" + "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig/cmd/rig/cmd/capsule/root" "github.com/rigdev/rig/cmd/rig/cmd/cluster" + "github.com/rigdev/rig/cmd/rig/cmd/cmd_config" "github.com/rigdev/rig/cmd/rig/cmd/config" "github.com/rigdev/rig/cmd/rig/cmd/dev" "github.com/rigdev/rig/cmd/rig/cmd/group" @@ -19,38 +17,52 @@ import ( "github.com/rigdev/rig/cmd/rig/cmd/user" "github.com/rigdev/rig/internal/build" "github.com/spf13/cobra" + "go.uber.org/fx" + "go.uber.org/zap" ) -// Used for flags. -var ( - rootCmd = &cobra.Command{ - Use: "rig", - Short: "CLI tool for managing your Rig projects", +type RootCmd struct { + fx.In + + Ctx context.Context + Rig rig.Client + Cfg *cmd_config.Config + Logger *zap.Logger + + Dev dev.Cmd + Capsule root.Cmd + Auth auth.Cmd + User user.Cmd + ServiceAccount service_account.Cmd + Group group.Cmd + Cluster cluster.Cmd + Config config.Cmd + Project project.Cmd +} + +func (r RootCmd) Execute() error { + rootCmd := &cobra.Command{ + Use: "rig", + Short: "CLI tool for managing your Rig projects", + PersistentPreRunE: r.preRun, } -) -// Execute executes the root command. -func Execute() error { // database.Setup(rootCmd) // storage.Setup(rootCmd) - auth.Setup(rootCmd) - user.Setup(rootCmd) - service_account.Setup(rootCmd) - group.Setup(rootCmd) - project.Setup(rootCmd) - config.Setup(rootCmd) - cluster.Setup(rootCmd) - dev.Setup(rootCmd) - - capsuleCmd := capsule.Setup(rootCmd) - resource.Setup(capsuleCmd) - capsuleBuild.Setup(capsuleCmd) - instance.Setup(capsuleCmd) - network.Setup(capsuleCmd) - rollout.Setup(capsuleCmd) - env.Setup(capsuleCmd) - mount.Setup(capsuleCmd) - + r.Dev.Setup(rootCmd) + r.Capsule.Setup(rootCmd) + r.Auth.Setup(rootCmd) + r.User.Setup(rootCmd) + r.ServiceAccount.Setup(rootCmd) + r.Group.Setup(rootCmd) + r.Cluster.Setup(rootCmd) + r.Config.Setup(rootCmd) + r.Project.Setup(rootCmd) rootCmd.AddCommand(build.VersionCommand()) + return rootCmd.Execute() } + +func (r RootCmd) preRun(cmd *cobra.Command, args []string) error { + return base.CheckAuth(cmd, r.Rig, r.Cfg) +} diff --git a/cmd/rig/cmd/service_account/create.go b/cmd/rig/cmd/service_account/create.go index e580c2c6c..7a76fa0a5 100644 --- a/cmd/rig/cmd/service_account/create.go +++ b/cmd/rig/cmd/service_account/create.go @@ -1,16 +1,14 @@ package service_account import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/service_account" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func ServiceAccountCreate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var name string var err error @@ -21,7 +19,7 @@ func ServiceAccountCreate(ctx context.Context, cmd *cobra.Command, args []string } } - resp, err := nc.ServiceAccount().Create(ctx, &connect.Request[service_account.CreateRequest]{ + resp, err := c.Rig.ServiceAccount().Create(ctx, &connect.Request[service_account.CreateRequest]{ Msg: &service_account.CreateRequest{ Name: name, }, diff --git a/cmd/rig/cmd/service_account/delete.go b/cmd/rig/cmd/service_account/delete.go index b0417c367..541670aa6 100644 --- a/cmd/rig/cmd/service_account/delete.go +++ b/cmd/rig/cmd/service_account/delete.go @@ -1,17 +1,15 @@ package service_account import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/service_account" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" ) -func ServiceAccountDelete(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) delete(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var id string var err error @@ -31,7 +29,7 @@ func ServiceAccountDelete(ctx context.Context, cmd *cobra.Command, args []string return err } - _, err = nc.ServiceAccount().Delete(ctx, &connect.Request[service_account.DeleteRequest]{ + _, err = c.Rig.ServiceAccount().Delete(ctx, &connect.Request[service_account.DeleteRequest]{ Msg: &service_account.DeleteRequest{ ServiceAccountId: id, }, diff --git a/cmd/rig/cmd/service_account/list.go b/cmd/rig/cmd/service_account/list.go index 15fc3a15f..21a23bea3 100644 --- a/cmd/rig/cmd/service_account/list.go +++ b/cmd/rig/cmd/service_account/list.go @@ -1,18 +1,16 @@ package service_account import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/service_account" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func ServiceAccountList(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { - resp, err := nc.ServiceAccount().List(ctx, &connect.Request[service_account.ListRequest]{ +func (c Cmd) list(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + resp, err := c.Rig.ServiceAccount().List(ctx, &connect.Request[service_account.ListRequest]{ Msg: &service_account.ListRequest{}, }) if err != nil { diff --git a/cmd/rig/cmd/service_account/setup.go b/cmd/rig/cmd/service_account/setup.go index cc283b27f..dc0bc8ef2 100644 --- a/cmd/rig/cmd/service_account/setup.go +++ b/cmd/rig/cmd/service_account/setup.go @@ -1,8 +1,11 @@ package service_account import ( - "github.com/rigdev/rig/cmd/rig/cmd/base" + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -18,7 +21,14 @@ var ( name string ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client +} + +func (c Cmd) Setup(parent *cobra.Command) { serviceAccount := &cobra.Command{ Use: "service-account", Short: "Manage service accounts", @@ -26,7 +36,7 @@ func Setup(parent *cobra.Command) { create := &cobra.Command{ Use: "create", - RunE: base.Register(ServiceAccountCreate), + RunE: c.create, Args: cobra.NoArgs, } create.Flags().StringVarP(&name, "name", "n", "", "name of the credential") @@ -34,7 +44,7 @@ func Setup(parent *cobra.Command) { list := &cobra.Command{ Use: "list", - RunE: base.Register(ServiceAccountList), + RunE: c.list, Args: cobra.NoArgs, } list.Flags().BoolVar(&outputJSON, "json", false, "Output as JSON") @@ -45,7 +55,7 @@ func Setup(parent *cobra.Command) { delete := &cobra.Command{ Use: "delete [id]", - RunE: base.Register(ServiceAccountDelete), + RunE: c.delete, Args: cobra.MaximumNArgs(1), } serviceAccount.AddCommand(delete) diff --git a/cmd/rig/cmd/storage/copy.go b/cmd/rig/cmd/storage/copy.go index bb9583c0a..3e6d77b6b 100644 --- a/cmd/rig/cmd/storage/copy.go +++ b/cmd/rig/cmd/storage/copy.go @@ -15,7 +15,6 @@ import ( "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/progress" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/iterator" "github.com/spf13/cobra" @@ -27,7 +26,8 @@ var excludeList = []string{ ".DS_Store", } -func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) cp(cmd *cobra.Command, args []string) error { + ctx := c.Ctx rawFrom := args[0] rawTo := args[1] @@ -48,7 +48,7 @@ func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl base = filepath.Base(prefix) } if !strings.Contains(base, ".") { - res, err := nc.Storage().ListObjects(ctx, &connect.Request[storage.ListObjectsRequest]{ + res, err := c.Rig.Storage().ListObjects(ctx, &connect.Request[storage.ListObjectsRequest]{ Msg: &storage.ListObjectsRequest{ Bucket: bucket, Prefix: prefix, @@ -65,7 +65,7 @@ func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl rawTo = path.Join(rawTo, base) } - res, err := nc.Storage().GetObject(ctx, &connect.Request[storage.GetObjectRequest]{ + res, err := c.Rig.Storage().GetObject(ctx, &connect.Request[storage.GetObjectRequest]{ Msg: &storage.GetObjectRequest{ Bucket: bucket, Path: prefix, @@ -105,7 +105,7 @@ func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl } pw.AppendTracker(t) - if _, err := nc.Storage().CopyObject(ctx, &connect.Request[storage.CopyObjectRequest]{ + if _, err := c.Rig.Storage().CopyObject(ctx, &connect.Request[storage.CopyObjectRequest]{ Msg: &storage.CopyObjectRequest{ FromBucket: bucket, FromPath: obj.GetPath(), @@ -142,7 +142,7 @@ func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl } pw.AppendTracker(t) - if err := downloadFile(ctx, cmd, t, bucket, path.Join(rawTo, p), nc); err != nil { + if err := c.downloadFile(ctx, cmd, t, bucket, path.Join(rawTo, p)); err != nil { log.Fatal(err) } @@ -211,7 +211,7 @@ func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl sem.Acquire(ctx, 1) go func() { - if err := uploadFile(ctx, cmd, t, bucket, path.Join(prefix, p), nc); err != nil { + if err := c.uploadFile(ctx, cmd, t, bucket, path.Join(prefix, p)); err != nil { log.Fatal(err) } @@ -227,7 +227,7 @@ func StorageCp(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl } } -func uploadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bucket, path string, nc rig.Client) error { +func (c Cmd) uploadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bucket, path string) error { from := t.Message f, err := os.Open(from) @@ -264,8 +264,8 @@ func uploadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bu } // Upload. - c := nc.Storage().UploadObject(ctx) - if err := c.Send(&storage.UploadObjectRequest{Request: &storage.UploadObjectRequest_Metadata_{Metadata: m}}); err != nil { + cc := c.Rig.Storage().UploadObject(ctx) + if err := cc.Send(&storage.UploadObjectRequest{Request: &storage.UploadObjectRequest_Metadata_{Metadata: m}}); err != nil { return err } @@ -273,7 +273,7 @@ func uploadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bu for { n, err := f.Read(buffer) if err == io.EOF { - _, err := c.CloseAndReceive() + _, err := cc.CloseAndReceive() if err != nil { return err } @@ -283,7 +283,7 @@ func uploadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bu return err } - if err := c.Send(&storage.UploadObjectRequest{Request: &storage.UploadObjectRequest_Chunk{Chunk: buffer[:n]}}); err != nil { + if err := cc.Send(&storage.UploadObjectRequest{Request: &storage.UploadObjectRequest_Chunk{Chunk: buffer[:n]}}); err != nil { return err } @@ -291,7 +291,7 @@ func uploadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bu } } -func downloadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bucket, path string, nc rig.Client) error { +func (c Cmd) downloadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, bucket, path string) error { from := t.Message // Create the directories if they don't exist. if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { @@ -306,7 +306,7 @@ func downloadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, defer f.Close() // Download. - c, err := nc.Storage().DownloadObject(ctx, &connect.Request[storage.DownloadObjectRequest]{ + cc, err := c.Rig.Storage().DownloadObject(ctx, &connect.Request[storage.DownloadObjectRequest]{ Msg: &storage.DownloadObjectRequest{ Bucket: bucket, Path: from, @@ -315,10 +315,10 @@ func downloadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, if err != nil { return err } - defer c.Close() + defer cc.Close() - for c.Receive() { - res := c.Msg() + for cc.Receive() { + res := cc.Msg() n, err := f.Write(res.GetChunk()) if err != nil { return err @@ -326,13 +326,13 @@ func downloadFile(ctx context.Context, cmd *cobra.Command, t *progress.Tracker, t.Increment(int64(n)) } // For some reason the EOF error does not match io.EOF, but instead is unknown at just says unknown: EOF - if c.Err() == io.EOF { + if cc.Err() == io.EOF { return nil } - if errors.IsUnknown(c.Err()) { + if errors.IsUnknown(cc.Err()) { return nil - } else if c.Err() != nil { - return c.Err() + } else if cc.Err() != nil { + return cc.Err() } else { return nil } diff --git a/cmd/rig/cmd/storage/create_bucket.go b/cmd/rig/cmd/storage/create_bucket.go index 7f656fdec..1d49b5dfb 100644 --- a/cmd/rig/cmd/storage/create_bucket.go +++ b/cmd/rig/cmd/storage/create_bucket.go @@ -1,19 +1,17 @@ package storage import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/list" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/uuid" "github.com/spf13/cobra" ) -func StorageCreateBucket(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) createBucket(cmd *cobra.Command, args []string) error { + ctx := c.Ctx l := list.NewWriter() l.SetStyle(list.StyleConnectedRounded) @@ -22,7 +20,7 @@ func StorageCreateBucket(ctx context.Context, cmd *cobra.Command, args []string, if len(args) == 1 { id, err := uuid.Parse(args[0]) if err != nil { - res, err := nc.Storage().LookupProvider(ctx, &connect.Request[storage.LookupProviderRequest]{ + res, err := c.Rig.Storage().LookupProvider(ctx, &connect.Request[storage.LookupProviderRequest]{ Msg: &storage.LookupProviderRequest{ Name: args[0], }, @@ -35,7 +33,7 @@ func StorageCreateBucket(ctx context.Context, cmd *cobra.Command, args []string, pid = id.String() } } else { - res, err := nc.Storage().ListProviders(ctx, &connect.Request[storage.ListProvidersRequest]{ + res, err := c.Rig.Storage().ListProviders(ctx, &connect.Request[storage.ListProvidersRequest]{ Msg: &storage.ListProvidersRequest{}, }) if err != nil { @@ -81,7 +79,7 @@ func StorageCreateBucket(ctx context.Context, cmd *cobra.Command, args []string, return err } - _, err = nc.Storage().CreateBucket(ctx, &connect.Request[storage.CreateBucketRequest]{ + _, err = c.Rig.Storage().CreateBucket(ctx, &connect.Request[storage.CreateBucketRequest]{ Msg: &storage.CreateBucketRequest{ Bucket: name, ProviderBucket: providerBucketName, diff --git a/cmd/rig/cmd/storage/create_provider.go b/cmd/rig/cmd/storage/create_provider.go index 4f78de245..c0ad56aaa 100644 --- a/cmd/rig/cmd/storage/create_provider.go +++ b/cmd/rig/cmd/storage/create_provider.go @@ -2,7 +2,6 @@ package storage import ( "bufio" - "context" "fmt" "io" "os" @@ -10,12 +9,12 @@ import ( "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/storage" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageCreateProvider(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) createProvider(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error if name == "" { name, err = common.PromptInput("Provider identifier:", common.ValidateNonEmptyOpt) @@ -143,7 +142,7 @@ func StorageCreateProvider(ctx context.Context, cmd *cobra.Command, args []strin } } - _, err = nc.Storage().CreateProvider(ctx, &connect.Request[storage.CreateProviderRequest]{ + _, err = c.Rig.Storage().CreateProvider(ctx, &connect.Request[storage.CreateProviderRequest]{ Msg: &storage.CreateProviderRequest{ Name: name, Config: config, diff --git a/cmd/rig/cmd/storage/delete_bucket.go b/cmd/rig/cmd/storage/delete_bucket.go index ba763585b..9a4f0202c 100644 --- a/cmd/rig/cmd/storage/delete_bucket.go +++ b/cmd/rig/cmd/storage/delete_bucket.go @@ -1,17 +1,15 @@ package storage import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/list" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageDeleteBucket(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) deleteBucket(cmd *cobra.Command, args []string) error { + ctx := c.Ctx l := list.NewWriter() l.SetStyle(list.StyleConnectedRounded) var bucket string @@ -25,7 +23,7 @@ func StorageDeleteBucket(ctx context.Context, cmd *cobra.Command, args []string, bucket = args[0] } - _, err = nc.Storage().DeleteBucket(ctx, &connect.Request[storage.DeleteBucketRequest]{ + _, err = c.Rig.Storage().DeleteBucket(ctx, &connect.Request[storage.DeleteBucketRequest]{ Msg: &storage.DeleteBucketRequest{ Bucket: bucket, }, diff --git a/cmd/rig/cmd/storage/delete_object.go b/cmd/rig/cmd/storage/delete_object.go index 350713f80..b5fa89061 100644 --- a/cmd/rig/cmd/storage/delete_object.go +++ b/cmd/rig/cmd/storage/delete_object.go @@ -1,18 +1,15 @@ package storage import ( - "context" - - "github.com/rigdev/rig-go-sdk" - "github.com/rigdev/rig/cmd/common" - "github.com/rigdev/rig/pkg/errors" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/storage" + "github.com/rigdev/rig/cmd/common" + "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func StorageDeleteObject(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) deleteObject(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var path string var err error if len(args) < 1 { @@ -28,7 +25,7 @@ func StorageDeleteObject(ctx context.Context, cmd *cobra.Command, args []string, if err != nil { return err } - _, err = nc.Storage().DeleteObject(ctx, &connect.Request[storage.DeleteObjectRequest]{ + _, err = c.Rig.Storage().DeleteObject(ctx, &connect.Request[storage.DeleteObjectRequest]{ Msg: &storage.DeleteObjectRequest{ Bucket: bucket, Path: prefix, diff --git a/cmd/rig/cmd/storage/delete_provider.go b/cmd/rig/cmd/storage/delete_provider.go index 3bd531332..82007987a 100644 --- a/cmd/rig/cmd/storage/delete_provider.go +++ b/cmd/rig/cmd/storage/delete_provider.go @@ -1,26 +1,24 @@ package storage import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageDeleteProvider(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) deleteProvider(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - g, uid, err := common.GetStorageProvider(ctx, identifier, nc) + g, uid, err := common.GetStorageProvider(ctx, identifier, c.Rig) if err != nil { return err } - _, err = nc.Storage().DeleteProvider(ctx, &connect.Request[storage.DeleteProviderRequest]{ + _, err = c.Rig.Storage().DeleteProvider(ctx, &connect.Request[storage.DeleteProviderRequest]{ Msg: &storage.DeleteProviderRequest{ ProviderId: uid, }, diff --git a/cmd/rig/cmd/storage/get_bucket.go b/cmd/rig/cmd/storage/get_bucket.go index b865f1b4c..5d6ba68b7 100644 --- a/cmd/rig/cmd/storage/get_bucket.go +++ b/cmd/rig/cmd/storage/get_bucket.go @@ -1,17 +1,15 @@ package storage import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageGetBucket(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) getBucket(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var bucket string var err error if len(args) < 1 { @@ -23,7 +21,7 @@ func StorageGetBucket(ctx context.Context, cmd *cobra.Command, args []string, nc bucket = args[0] } - res, err := nc.Storage().GetBucket(ctx, &connect.Request[storage.GetBucketRequest]{ + res, err := c.Rig.Storage().GetBucket(ctx, &connect.Request[storage.GetBucketRequest]{ Msg: &storage.GetBucketRequest{ Bucket: bucket, }, diff --git a/cmd/rig/cmd/storage/get_object.go b/cmd/rig/cmd/storage/get_object.go index 96102fd87..f4bd975b4 100644 --- a/cmd/rig/cmd/storage/get_object.go +++ b/cmd/rig/cmd/storage/get_object.go @@ -1,18 +1,16 @@ package storage import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func StorageGetObject(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) getObject(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var path string var err error if len(args) < 1 { @@ -28,7 +26,7 @@ func StorageGetObject(ctx context.Context, cmd *cobra.Command, args []string, nc if err != nil { return err } - res, err := nc.Storage().GetObject(ctx, &connect.Request[storage.GetObjectRequest]{ + res, err := c.Rig.Storage().GetObject(ctx, &connect.Request[storage.GetObjectRequest]{ Msg: &storage.GetObjectRequest{ Bucket: bucket, Path: prefix, diff --git a/cmd/rig/cmd/storage/get_provider.go b/cmd/rig/cmd/storage/get_provider.go index 525a5e42a..2447c0708 100644 --- a/cmd/rig/cmd/storage/get_provider.go +++ b/cmd/rig/cmd/storage/get_provider.go @@ -1,20 +1,18 @@ package storage import ( - "context" - "github.com/jedib0t/go-pretty/v6/table" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageGetProvider(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) getProvider(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - g, uid, err := common.GetStorageProvider(ctx, identifier, nc) + g, uid, err := common.GetStorageProvider(ctx, identifier, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/storage/list_providers.go b/cmd/rig/cmd/storage/list_providers.go index 42db6a789..895e7d16c 100644 --- a/cmd/rig/cmd/storage/list_providers.go +++ b/cmd/rig/cmd/storage/list_providers.go @@ -1,26 +1,25 @@ package storage import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/storage" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" ) -func StorageListProviders(ctx context.Context, cmd *cobra.Command, nc rig.Client) error { +func (c Cmd) listProviders(cmd *cobra.Command, args []string) error { + ctx := c.Ctx Pagination := &model.Pagination{ Offset: uint32(offset), Limit: uint32(limit), } - resp, err := nc.Storage().ListProviders(ctx, &connect.Request[storage.ListProvidersRequest]{ + resp, err := c.Rig.Storage().ListProviders(ctx, &connect.Request[storage.ListProvidersRequest]{ Msg: &storage.ListProvidersRequest{ Pagination: Pagination, }, diff --git a/cmd/rig/cmd/storage/ls.go b/cmd/rig/cmd/storage/ls.go index 2464ec21e..474a9ae9c 100644 --- a/cmd/rig/cmd/storage/ls.go +++ b/cmd/rig/cmd/storage/ls.go @@ -1,7 +1,6 @@ package storage import ( - "context" "fmt" "path" "strings" @@ -10,12 +9,12 @@ import ( "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/list" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageLs(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) ls(cmd *cobra.Command, args []string) error { + ctx := c.Ctx l := list.NewWriter() l.SetStyle(list.StyleConnectedRounded) @@ -23,7 +22,7 @@ func StorageLs(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl // List buckets. token := "" for { - res, err := nc.Storage().ListBuckets(ctx, &connect.Request[storage.ListBucketsRequest]{ + res, err := c.Rig.Storage().ListBuckets(ctx, &connect.Request[storage.ListBucketsRequest]{ Msg: &storage.ListBucketsRequest{ Token: token, }, @@ -66,7 +65,7 @@ func StorageLs(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cl // List files. token := "" for { - res, err := nc.Storage().ListObjects(ctx, &connect.Request[storage.ListObjectsRequest]{ + res, err := c.Rig.Storage().ListObjects(ctx, &connect.Request[storage.ListObjectsRequest]{ Msg: &storage.ListObjectsRequest{ Token: token, Bucket: bucket, diff --git a/cmd/rig/cmd/storage/setup.go b/cmd/rig/cmd/storage/setup.go index dbe647c92..f2d69b7aa 100644 --- a/cmd/rig/cmd/storage/setup.go +++ b/cmd/rig/cmd/storage/setup.go @@ -1,10 +1,13 @@ package storage import ( + "context" + "github.com/erikgeiser/promptkit/textinput" - "github.com/rigdev/rig/cmd/rig/cmd/base" + "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -32,7 +35,14 @@ var ( providerBucketName string ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client +} + +func (c Cmd) Setup(parent *cobra.Command) { storage := &cobra.Command{ Use: "storage", } @@ -42,7 +52,7 @@ func Setup(parent *cobra.Command) { Aliases: []string{"cp"}, Short: "Copy files to and from buckets", Args: cobra.ExactArgs(2), - RunE: base.Register(StorageCp), + RunE: c.cp, } cp.PersistentFlags().BoolVarP(&storageRecursive, "recursive", "r", false, "if copy should be recursive") storage.AddCommand(cp) @@ -52,7 +62,7 @@ func Setup(parent *cobra.Command) { Aliases: []string{"ls"}, Short: "List buckets and objects", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageLs), + RunE: c.ls, } ls.PersistentFlags().BoolVarP(&storageRecursive, "recursive", "r", false, "if listing should be recursive. Does only work for listing within a single bucket") ls.Flags().BoolVar(&outputJson, "json", false, "output as json") @@ -62,7 +72,7 @@ func Setup(parent *cobra.Command) { Use: "create-bucket [provider-name]", Short: "Create a new bucket", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageCreateBucket), + RunE: c.createBucket, } createBucket.Flags().StringVarP(&name, "name", "n", "", "name of the bucket") createBucket.Flags().StringVarP(&providerBucketName, "provider-bucket-name", "p", "", "name of the bucket on the provider") @@ -73,7 +83,7 @@ func Setup(parent *cobra.Command) { Use: "delete-bucket [bucket-name]", Short: "Delete a bucket", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageDeleteBucket), + RunE: c.deleteBucket, } storage.AddCommand(deleteBucket) @@ -81,7 +91,7 @@ func Setup(parent *cobra.Command) { Use: "unlink-bucket [bucket-name]", Short: "Unlink a bucket", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageUnlinkBucket), + RunE: c.unlinkBucket, } storage.AddCommand(unlinkBucket) @@ -89,7 +99,7 @@ func Setup(parent *cobra.Command) { Use: "get-object [path]", Short: "Get an object", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageGetObject), + RunE: c.getObject, } getObject.Flags().BoolVar(&outputJson, "json", false, "output as json") storage.AddCommand(getObject) @@ -98,7 +108,7 @@ func Setup(parent *cobra.Command) { Use: "get-bucket [bucket]", Short: "Get a bucket", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageGetBucket), + RunE: c.getBucket, } getBucket.Flags().BoolVar(&outputJson, "json", false, "output as json") storage.AddCommand(getBucket) @@ -107,7 +117,7 @@ func Setup(parent *cobra.Command) { Use: "delete-object [path]", Short: "Delete an object", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageDeleteObject), + RunE: c.deleteObject, } storage.AddCommand(deleteObject) @@ -115,7 +125,7 @@ func Setup(parent *cobra.Command) { Use: "create-provider", Short: "Create a new provider", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageCreateProvider), + RunE: c.createProvider, } createProvider.Flags().StringVarP(&name, "name", "n", "", "name of the provider") @@ -143,7 +153,7 @@ func Setup(parent *cobra.Command) { Use: "list-providers", Short: "List all providers", Args: cobra.NoArgs, - RunE: base.Register(StorageListProviders), + RunE: c.listProviders, } listProviders.Flags().IntVarP(&limit, "limit", "l", 10, "limit the number of groups to return") listProviders.Flags().IntVarP(&offset, "offset", "o", 0, "offset the number of groups to return") @@ -156,7 +166,7 @@ func Setup(parent *cobra.Command) { Use: "get-provider [id | name]", Short: "Get a provider", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageGetProvider), + RunE: c.getProvider, } GetProvider.Flags().BoolVar(&outputJson, "json", false, "output as json") storage.AddCommand(GetProvider) @@ -165,7 +175,7 @@ func Setup(parent *cobra.Command) { Use: "delete-provider [id | name]", Short: "Delete a provider", Args: cobra.MaximumNArgs(1), - RunE: base.Register(StorageDeleteProvider), + RunE: c.deleteProvider, } storage.AddCommand(DeleteProvider) } diff --git a/cmd/rig/cmd/storage/unlink_bucket.go b/cmd/rig/cmd/storage/unlink_bucket.go index 7ddfaae97..013b1e1a9 100644 --- a/cmd/rig/cmd/storage/unlink_bucket.go +++ b/cmd/rig/cmd/storage/unlink_bucket.go @@ -1,17 +1,15 @@ package storage import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/list" "github.com/rigdev/rig-go-api/api/v1/storage" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func StorageUnlinkBucket(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) unlinkBucket(cmd *cobra.Command, args []string) error { + ctx := c.Ctx l := list.NewWriter() l.SetStyle(list.StyleConnectedRounded) var bucket string @@ -25,7 +23,7 @@ func StorageUnlinkBucket(ctx context.Context, cmd *cobra.Command, args []string, bucket = args[0] } - _, err = nc.Storage().UnlinkBucket(ctx, &connect.Request[storage.UnlinkBucketRequest]{ + _, err = c.Rig.Storage().UnlinkBucket(ctx, &connect.Request[storage.UnlinkBucketRequest]{ Msg: &storage.UnlinkBucketRequest{ Bucket: bucket, }, diff --git a/cmd/rig/cmd/user/add_member.go b/cmd/rig/cmd/user/add_member.go index 3d21e7b23..b5ab7b638 100644 --- a/cmd/rig/cmd/user/add_member.go +++ b/cmd/rig/cmd/user/add_member.go @@ -1,21 +1,19 @@ package user import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/group" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserAddMember(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) addMember(cmd *cobra.Command, args []string) error { + ctx := c.Ctx uidentifier := "" if len(args) > 1 { uidentifier = args[0] } - u, uuid, err := common.GetUser(ctx, uidentifier, nc) + u, uuid, err := common.GetUser(ctx, uidentifier, c.Rig) if err != nil { return err } @@ -23,7 +21,7 @@ func UserAddMember(ctx context.Context, cmd *cobra.Command, args []string, nc ri var guid string var gname string if groupIdentifier == "" { - groupsRes, err := nc.Group().List(ctx, connect.NewRequest(&group.ListRequest{})) + groupsRes, err := c.Rig.Group().List(ctx, connect.NewRequest(&group.ListRequest{})) if err != nil { return err } @@ -60,7 +58,7 @@ func UserAddMember(ctx context.Context, cmd *cobra.Command, args []string, nc ri return nil } } else { - g, id, err := common.GetGroup(ctx, groupIdentifier, nc) + g, id, err := common.GetGroup(ctx, groupIdentifier, c.Rig) if err != nil { return err } @@ -68,7 +66,7 @@ func UserAddMember(ctx context.Context, cmd *cobra.Command, args []string, nc ri gname = g.GetName() } - _, err = nc.Group().AddMember(ctx, &connect.Request[group.AddMemberRequest]{ + _, err = c.Rig.Group().AddMember(ctx, &connect.Request[group.AddMemberRequest]{ Msg: &group.AddMemberRequest{ GroupId: guid, UserIds: []string{uuid}, diff --git a/cmd/rig/cmd/user/create.go b/cmd/rig/cmd/user/create.go index ac02d4230..54fa67300 100644 --- a/cmd/rig/cmd/user/create.go +++ b/cmd/rig/cmd/user/create.go @@ -1,21 +1,19 @@ package user import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/user" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserCreate(ctx context.Context, cmd *cobra.Command, args []string, client rig.Client) error { +func (c Cmd) create(cmd *cobra.Command, args []string) error { + ctx := c.Ctx updates, err := common.GetUserAndPasswordUpdates(username, email, phoneNumber, password) if err != nil { return err } - res, err := client.User().Create(ctx, &connect.Request[user.CreateRequest]{ + res, err := c.Rig.User().Create(ctx, &connect.Request[user.CreateRequest]{ Msg: &user.CreateRequest{ Initializers: updates, }, diff --git a/cmd/rig/cmd/user/delete.go b/cmd/rig/cmd/user/delete.go index 69feba690..fa522a6c3 100644 --- a/cmd/rig/cmd/user/delete.go +++ b/cmd/rig/cmd/user/delete.go @@ -1,26 +1,24 @@ package user import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/user" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserDelete(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) delete(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetUser(ctx, identifier, nc) + _, id, err := common.GetUser(ctx, identifier, c.Rig) if err != nil { return err } - _, err = nc.User().Delete(ctx, connect.NewRequest(&user.DeleteRequest{ + _, err = c.Rig.User().Delete(ctx, connect.NewRequest(&user.DeleteRequest{ UserId: id, })) if err != nil { diff --git a/cmd/rig/cmd/user/get.go b/cmd/rig/cmd/user/get.go index 44d3094aa..9b6737356 100644 --- a/cmd/rig/cmd/user/get.go +++ b/cmd/rig/cmd/user/get.go @@ -1,20 +1,18 @@ package user import ( - "context" - "github.com/jedib0t/go-pretty/v6/table" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserLookup(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) lookup(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - u, id, err := common.GetUser(ctx, identifier, nc) + u, id, err := common.GetUser(ctx, identifier, c.Rig) if err != nil { return err } diff --git a/cmd/rig/cmd/user/get_settings.go b/cmd/rig/cmd/user/get_settings.go index 0cf635813..3a995d6a8 100644 --- a/cmd/rig/cmd/user/get_settings.go +++ b/cmd/rig/cmd/user/get_settings.go @@ -1,18 +1,16 @@ package user import ( - "context" - "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/user/settings" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserGetSettings(ctx context.Context, cmd *cobra.Command, nc rig.Client) error { - res, err := nc.UserSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{}) +func (c Cmd) getSettings(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + res, err := c.Rig.UserSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{}) if err != nil { return err } diff --git a/cmd/rig/cmd/user/list.go b/cmd/rig/cmd/user/list.go index f55ab970f..141606319 100644 --- a/cmd/rig/cmd/user/list.go +++ b/cmd/rig/cmd/user/list.go @@ -1,7 +1,6 @@ package user import ( - "context" "fmt" "strings" @@ -9,12 +8,12 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/user" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserList(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) list(cmd *cobra.Command, args []string) error { + ctx := c.Ctx search := strings.Join(args, " ") req := &user.ListRequest{ Pagination: &model.Pagination{ @@ -23,7 +22,7 @@ func UserList(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Cli }, Search: search, } - resp, err := nc.User().List(ctx, &connect.Request[user.ListRequest]{Msg: req}) + resp, err := c.Rig.User().List(ctx, &connect.Request[user.ListRequest]{Msg: req}) if err != nil { return err } diff --git a/cmd/rig/cmd/user/list_sessions.go b/cmd/rig/cmd/user/list_sessions.go index 446d7cb5e..b73aabb42 100644 --- a/cmd/rig/cmd/user/list_sessions.go +++ b/cmd/rig/cmd/user/list_sessions.go @@ -1,29 +1,28 @@ package user import ( - "context" "fmt" "github.com/bufbuild/connect-go" "github.com/jedib0t/go-pretty/v6/table" "github.com/rigdev/rig-go-api/api/v1/user" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserListSessions(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) listSessions(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - _, id, err := common.GetUser(ctx, identifier, nc) + _, id, err := common.GetUser(ctx, identifier, c.Rig) if err != nil { return err } - resp, err := nc.User().ListSessions(ctx, connect.NewRequest(&user.ListSessionsRequest{ + resp, err := c.Rig.User().ListSessions(ctx, connect.NewRequest(&user.ListSessionsRequest{ UserId: id, Pagination: &model.Pagination{ Offset: uint32(offset), diff --git a/cmd/rig/cmd/user/migrate.go b/cmd/rig/cmd/user/migrate.go index cfd58e92a..d70f91813 100644 --- a/cmd/rig/cmd/user/migrate.go +++ b/cmd/rig/cmd/user/migrate.go @@ -12,7 +12,6 @@ import ( "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/user" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" "google.golang.org/api/iterator" @@ -70,7 +69,8 @@ type firebaseUser struct { CreatedAt string `json:"createdAt"` } -func UserMigrate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) migrate(cmd *cobra.Command, args []string) error { + ctx := c.Ctx var err error fields := []string{ platformFirebase.String(), @@ -86,18 +86,18 @@ func UserMigrate(ctx context.Context, cmd *cobra.Command, args []string, nc rig. switch platform { case platformFirebase.String(): if usersFilePath != "" { - return migrateFromFirebaseUsersFile(ctx, nc) + return c.migrateFromFirebaseUsersFile(ctx) } else if credFilePath != "" { - return migrateFromFirebaseCredentials(ctx, nc) + return c.migrateFromFirebaseCredentials(ctx) } else { - return migrateFromFirebase(ctx, nc) + return c.migrateFromFirebase(ctx) } default: return fmt.Errorf("invalid migration platform") } } -func migrateFromFirebase(ctx context.Context, nc rig.Client) error { +func (c Cmd) migrateFromFirebase(ctx context.Context) error { fields := []string{ methodCredentials.String(), methodUsersFile.String(), @@ -110,15 +110,15 @@ func migrateFromFirebase(ctx context.Context, nc rig.Client) error { switch migrationMethod(i + 1) { case methodCredentials: - return migrateFromFirebaseCredentials(ctx, nc) + return c.migrateFromFirebaseCredentials(ctx) case methodUsersFile: - return migrateFromFirebaseUsersFile(ctx, nc) + return c.migrateFromFirebaseUsersFile(ctx) default: return fmt.Errorf("invalid migration method") } } -func migrateFromFirebaseCredentials(ctx context.Context, nc rig.Client) error { +func (c Cmd) migrateFromFirebaseCredentials(ctx context.Context) error { var err error if credFilePath == "" { credFilePath, err = common.PromptInput("Credentials Path:", common.ValidateNonEmptyOpt) @@ -137,12 +137,12 @@ func migrateFromFirebaseCredentials(ctx context.Context, nc rig.Client) error { return err } - c := map[string]interface{}{} - if err := json.Unmarshal(bytevalue, &c); err != nil { + cc := map[string]interface{}{} + if err := json.Unmarshal(bytevalue, &cc); err != nil { return err } - projectID, ok := c["project_id"].(string) + projectID, ok := cc["project_id"].(string) if !ok { return fmt.Errorf("project_id not found in credentials") } @@ -237,7 +237,7 @@ func migrateFromFirebaseCredentials(ctx context.Context, nc rig.Client) error { }) } - _, err = nc.User().Create(ctx, &connect.Request[user.CreateRequest]{ + _, err = c.Rig.User().Create(ctx, &connect.Request[user.CreateRequest]{ Msg: &user.CreateRequest{ Initializers: us, }, @@ -259,7 +259,7 @@ func migrateFromFirebaseCredentials(ctx context.Context, nc rig.Client) error { return nil } -func migrateFromFirebaseUsersFile(ctx context.Context, nc rig.Client) error { +func (c Cmd) migrateFromFirebaseUsersFile(ctx context.Context) error { var err error if usersFilePath == "" { usersFilePath, err = common.PromptInput("users.json path:", common.ValidateNonEmptyOpt) @@ -353,7 +353,7 @@ func migrateFromFirebaseUsersFile(ctx context.Context, nc rig.Client) error { }) } - _, err = nc.User().Create(ctx, &connect.Request[user.CreateRequest]{ + _, err = c.Rig.User().Create(ctx, &connect.Request[user.CreateRequest]{ Msg: &user.CreateRequest{ Initializers: us, }, diff --git a/cmd/rig/cmd/user/remove_member.go b/cmd/rig/cmd/user/remove_member.go index c5b3b6259..57eb7fba7 100644 --- a/cmd/rig/cmd/user/remove_member.go +++ b/cmd/rig/cmd/user/remove_member.go @@ -1,28 +1,26 @@ package user import ( - "context" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/group" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" ) -func UserRemoveMember(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) removeMember(cmd *cobra.Command, args []string) error { + ctx := c.Ctx uidentifier := "" if len(args) > 1 { uidentifier = args[1] } - _, uuid, err := common.GetUser(ctx, uidentifier, nc) + _, uuid, err := common.GetUser(ctx, uidentifier, c.Rig) if err != nil { return err } var guid string var gname string if groupIdentifier == "" { - res, err := nc.Group().ListGroupsForUser(ctx, &connect.Request[group.ListGroupsForUserRequest]{ + res, err := c.Rig.Group().ListGroupsForUser(ctx, &connect.Request[group.ListGroupsForUserRequest]{ Msg: &group.ListGroupsForUserRequest{ UserId: uuid, }, @@ -43,7 +41,7 @@ func UserRemoveMember(ctx context.Context, cmd *cobra.Command, args []string, nc guid = res.Msg.GetGroups()[i].GetGroupId() } else { - g, id, err := common.GetGroup(ctx, groupIdentifier, nc) + g, id, err := common.GetGroup(ctx, groupIdentifier, c.Rig) if err != nil { return err } @@ -51,7 +49,7 @@ func UserRemoveMember(ctx context.Context, cmd *cobra.Command, args []string, nc gname = g.GetName() } - _, err = nc.Group().RemoveMember(ctx, &connect.Request[group.RemoveMemberRequest]{ + _, err = c.Rig.Group().RemoveMember(ctx, &connect.Request[group.RemoveMemberRequest]{ Msg: &group.RemoveMemberRequest{ GroupId: guid, UserId: uuid, diff --git a/cmd/rig/cmd/user/setup.go b/cmd/rig/cmd/user/setup.go index 47a66ae0a..022f11bff 100644 --- a/cmd/rig/cmd/user/setup.go +++ b/cmd/rig/cmd/user/setup.go @@ -1,8 +1,11 @@ package user import ( - "github.com/rigdev/rig/cmd/rig/cmd/base" + "context" + + "github.com/rigdev/rig-go-sdk" "github.com/spf13/cobra" + "go.uber.org/fx" ) var ( @@ -31,7 +34,14 @@ var ( outputJson bool ) -func Setup(parent *cobra.Command) { +type Cmd struct { + fx.In + + Ctx context.Context + Rig rig.Client +} + +func (c Cmd) Setup(parent *cobra.Command) { user := &cobra.Command{ Use: "user", Short: "Manage users in your projects", @@ -39,7 +49,7 @@ func Setup(parent *cobra.Command) { create := &cobra.Command{ Use: "create", - RunE: base.Register(UserCreate), + RunE: c.create, Args: cobra.NoArgs, } create.Flags().StringVarP(&email, "email", "e", "", "email of the user") @@ -50,7 +60,7 @@ func Setup(parent *cobra.Command) { update := &cobra.Command{ Use: "update [user-id | {email|username|phone}]", - RunE: base.Register(UserUpdate), + RunE: c.update, Args: cobra.MaximumNArgs(1), } update.Flags().StringVarP(&field, "field", "f", "", "field to update") @@ -83,7 +93,7 @@ func Setup(parent *cobra.Command) { get := &cobra.Command{ Use: "get [user-id | {email|username|phone}]", - RunE: base.Register(UserLookup), + RunE: c.lookup, Args: cobra.MaximumNArgs(1), } get.Flags().BoolVar(&outputJson, "json", false, "output as json") @@ -91,7 +101,7 @@ func Setup(parent *cobra.Command) { list := &cobra.Command{ Use: "list [search...]", - RunE: base.Register(UserList), + RunE: c.list, } list.Flags().IntVarP(&offset, "offset", "o", 0, "offset for pagination") list.Flags().IntVarP(&limit, "limit", "l", 10, "limit for pagination") @@ -100,14 +110,14 @@ func Setup(parent *cobra.Command) { delete := &cobra.Command{ Use: "delete [user-id | {email|username|phone}]", - RunE: base.Register(UserDelete), + RunE: c.delete, Args: cobra.MaximumNArgs(1), } user.AddCommand(delete) listSessions := &cobra.Command{ Use: "list-sessions [user-id | {email|username|phone}]", - RunE: base.Register(UserListSessions), + RunE: c.listSessions, Args: cobra.MaximumNArgs(1), } listSessions.Flags().IntVarP(&offset, "offset", "o", 0, "offset for pagination") @@ -117,7 +127,7 @@ func Setup(parent *cobra.Command) { getSettings := &cobra.Command{ Use: "get-settings", - RunE: base.Register(UserGetSettings), + RunE: c.getSettings, Args: cobra.NoArgs, } getSettings.Flags().BoolVar(&outputJson, "json", false, "output as json") @@ -125,7 +135,7 @@ func Setup(parent *cobra.Command) { updateSettings := &cobra.Command{ Use: "update-settings", - RunE: base.Register(UserUpdateSettings), + RunE: c.updateSettings, Args: cobra.NoArgs, } updateSettings.Flags().StringVarP(&field, "field", "f", "", "field to update") @@ -162,7 +172,7 @@ func Setup(parent *cobra.Command) { migrate := &cobra.Command{ Use: "migrate", - RunE: base.Register(UserMigrate), + RunE: c.migrate, Args: cobra.NoArgs, } migrate.Flags().StringVarP(&platform, "platform", "p", "Firebase", "platform to migrate from") @@ -193,7 +203,7 @@ func Setup(parent *cobra.Command) { addUser := &cobra.Command{ Use: "add-member [user-id | {email|username|phone}]", - RunE: base.Register(UserAddMember), + RunE: c.addMember, Args: cobra.MaximumNArgs(1), } addUser.Flags().StringVarP(&groupIdentifier, "group", "g", "", "group to add the user to") @@ -201,7 +211,7 @@ func Setup(parent *cobra.Command) { removeUser := &cobra.Command{ Use: "remove-member [user-id | {email|username|phone}]", - RunE: base.Register(UserRemoveMember), + RunE: c.removeMember, Args: cobra.MaximumNArgs(1), } removeUser.Flags().StringVarP(&groupIdentifier, "group", "g", "", "group to remove the user from") diff --git a/cmd/rig/cmd/user/update.go b/cmd/rig/cmd/user/update.go index dacf90fd7..7b93a4d97 100644 --- a/cmd/rig/cmd/user/update.go +++ b/cmd/rig/cmd/user/update.go @@ -1,7 +1,6 @@ package user import ( - "context" "encoding/json" "fmt" "strconv" @@ -9,7 +8,6 @@ import ( "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/user" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/rigdev/rig/pkg/errors" "github.com/spf13/cobra" @@ -86,12 +84,13 @@ func (f userProfileField) String() string { } } -func UserUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { +func (c Cmd) update(cmd *cobra.Command, args []string) error { + ctx := c.Ctx identifier := "" if len(args) > 0 { identifier = args[0] } - u, id, err := common.GetUser(ctx, identifier, nc) + u, id, err := common.GetUser(ctx, identifier, c.Rig) if err != nil { return err } @@ -102,7 +101,7 @@ func UserUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.C return err } - _, err = nc.User().Update(ctx, &connect.Request[user.UpdateRequest]{ + _, err = c.Rig.User().Update(ctx, &connect.Request[user.UpdateRequest]{ Msg: &user.UpdateRequest{ UserId: id, Updates: []*user.Update{u}, @@ -149,7 +148,7 @@ func UserUpdate(ctx context.Context, cmd *cobra.Command, args []string, nc rig.C } } - _, err = nc.User().Update(ctx, connect.NewRequest(&user.UpdateRequest{ + _, err = c.Rig.User().Update(ctx, connect.NewRequest(&user.UpdateRequest{ UserId: id, Updates: updates, })) diff --git a/cmd/rig/cmd/user/update_settings.go b/cmd/rig/cmd/user/update_settings.go index 6348464ff..15d4ccc56 100644 --- a/cmd/rig/cmd/user/update_settings.go +++ b/cmd/rig/cmd/user/update_settings.go @@ -1,17 +1,14 @@ package user import ( - "context" + "encoding/json" "errors" "fmt" "strconv" - "encoding/json" - "github.com/bufbuild/connect-go" "github.com/rigdev/rig-go-api/api/v1/user/settings" "github.com/rigdev/rig-go-api/model" - "github.com/rigdev/rig-go-sdk" "github.com/rigdev/rig/cmd/common" "github.com/spf13/cobra" "golang.org/x/exp/slices" @@ -111,8 +108,9 @@ func (f settingsField) String() string { } } -func UserUpdateSettings(ctx context.Context, cmd *cobra.Command, args []string, nc rig.Client) error { - res, err := nc.UserSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{}) +func (c Cmd) updateSettings(cmd *cobra.Command, args []string) error { + ctx := c.Ctx + res, err := c.Rig.UserSettings().GetSettings(ctx, &connect.Request[settings.GetSettingsRequest]{}) if err != nil { return err } @@ -126,7 +124,7 @@ func UserUpdateSettings(ctx context.Context, cmd *cobra.Command, args []string, return err } - _, err = nc.UserSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ + _, err = c.Rig.UserSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ Msg: &settings.UpdateSettingsRequest{ Settings: []*settings.Update{u}, }, @@ -175,7 +173,7 @@ func UserUpdateSettings(ctx context.Context, cmd *cobra.Command, args []string, return nil } - _, err = nc.UserSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ + _, err = c.Rig.UserSettings().UpdateSettings(ctx, &connect.Request[settings.UpdateSettingsRequest]{ Msg: &settings.UpdateSettingsRequest{ Settings: updates, }, diff --git a/cmd/rig/main.go b/cmd/rig/main.go index 7867473dc..1c6b31c87 100644 --- a/cmd/rig/main.go +++ b/cmd/rig/main.go @@ -1,7 +1,17 @@ package main -import "github.com/rigdev/rig/cmd/rig/cmd" +import ( + "github.com/rigdev/rig/cmd/rig/cmd" + "github.com/rigdev/rig/cmd/rig/cmd/base" + "go.uber.org/fx" +) func main() { - cmd.Execute() + fx.New( + base.Module, + fx.NopLogger, + fx.Invoke(func(r cmd.RootCmd) error { + return r.Execute() + }), + ) }