From 674926cd8cb1b50ac39fd5b88ca1c545054eb284 Mon Sep 17 00:00:00 2001 From: ale8k Date: Tue, 17 Dec 2024 13:27:54 +0000 Subject: [PATCH 1/4] feat(jimmctl migrate): enable users to specify model names --- cmd/jimmctl/cmd/migratemodel.go | 37 +++++++++---------- cmd/jimmctl/cmd/migratemodel_test.go | 46 +++++++++--------------- internal/jimm/jimm.go | 35 ++++++++++++++---- internal/jimm/jimm_test.go | 42 ++++++++++++++++++---- internal/jujuapi/controllerroot.go | 2 +- internal/jujuapi/jimm.go | 8 ++--- internal/jujuapi/jimm_test.go | 13 +++++-- internal/testutils/jimmtest/jimm_mock.go | 6 ++-- pkg/api/params/params.go | 4 +-- 9 files changed, 117 insertions(+), 76 deletions(-) diff --git a/cmd/jimmctl/cmd/migratemodel.go b/cmd/jimmctl/cmd/migratemodel.go index da58d2b78..381a34457 100644 --- a/cmd/jimmctl/cmd/migratemodel.go +++ b/cmd/jimmctl/cmd/migratemodel.go @@ -3,15 +3,12 @@ package cmd import ( - "fmt" - "github.com/juju/cmd/v3" "github.com/juju/gnuflag" jujuapi "github.com/juju/juju/api" jujucmd "github.com/juju/juju/cmd" "github.com/juju/juju/cmd/modelcmd" "github.com/juju/juju/jujuclient" - "github.com/juju/names/v5" "github.com/canonical/jimm/v3/internal/errors" "github.com/canonical/jimm/v3/pkg/api" @@ -20,15 +17,24 @@ import ( const ( migrateModelCommandDoc = ` -The migrate command migrates a model(s) to a new controller. Specify -a model-uuid to migrate and the destination controller name. +The migrate commands migrates a model, or many models between two controllers +registered within JIMM. + +You may specify a model name (of the form owner/name) or model UUID. + +For example, JIMM is aware of controller-a and controller-b and controller-a has +models: + - alice@canonical.com/model-a + - 2cb433a6-04eb-4ec4-9567-90426d20a004 + +You may run the migrate command like so to migrate the two models +from controller-a to controller-b: + jimmctl migrate controller-b model-a 2cb433a6-04eb-4ec4-9567-90426d20a004 -Note that multiple models can be targeted for migration by supplying -multiple model uuids. ` migrateModelCommandExample = ` jimmctl migrate mycontroller 2cb433a6-04eb-4ec4-9567-90426d20a004 - jimmctl migrate mycontroller 2cb433a6-04eb-4ec4-9567-90426d20a004 fd469983-27c2-423b-bebf-84f616fb036b ... + jimmctl migrate mycontroller model-a model-b fd469983-27c2-423b-bebf-84f616fb036b ... ` ) @@ -49,7 +55,7 @@ type migrateModelCommand struct { store jujuclient.ClientStore dialOpts *jujuapi.DialOpts targetController string - modelTags []string + modelTargets []string } func (c *migrateModelCommand) Info() *cmd.Info { @@ -74,19 +80,14 @@ func (c *migrateModelCommand) SetFlags(f *gnuflag.FlagSet) { // Init implements the cmd.Command interface. func (c *migrateModelCommand) Init(args []string) error { if len(args) < 2 { - return errors.E("Missing controller name and model uuid arguments") + return errors.E("Missing controller name and model target arguments") } for i, arg := range args { if i == 0 { c.targetController = arg continue } - mt := names.NewModelTag(arg) - _, err := names.ParseModelTag(mt.String()) - if err != nil { - return errors.E(err, fmt.Sprintf("%s is not a valid model uuid", arg)) - } - c.modelTags = append(c.modelTags, mt.String()) + c.modelTargets = append(c.modelTargets, arg) } return nil } @@ -105,8 +106,8 @@ func (c *migrateModelCommand) Run(ctxt *cmd.Context) error { client := api.NewClient(apiCaller) specs := []apiparams.MigrateModelInfo{} - for _, model := range c.modelTags { - specs = append(specs, apiparams.MigrateModelInfo{ModelTag: model, TargetController: c.targetController}) + for _, model := range c.modelTargets { + specs = append(specs, apiparams.MigrateModelInfo{TargetModelNameOrUUID: model, TargetController: c.targetController}) } req := apiparams.MigrateModelRequest{Specs: specs} events, err := client.MigrateModel(&req) diff --git a/cmd/jimmctl/cmd/migratemodel_test.go b/cmd/jimmctl/cmd/migratemodel_test.go index 289d6d510..179e500bc 100644 --- a/cmd/jimmctl/cmd/migratemodel_test.go +++ b/cmd/jimmctl/cmd/migratemodel_test.go @@ -3,10 +3,13 @@ package cmd_test import ( + "fmt" + "github.com/juju/cmd/v3/cmdtesting" jujuparams "github.com/juju/juju/rpc/params" "github.com/juju/names/v5" gc "gopkg.in/check.v1" + "gopkg.in/yaml.v3" "github.com/canonical/jimm/v3/cmd/jimmctl/cmd" "github.com/canonical/jimm/v3/internal/testutils/cmdtest" @@ -19,21 +22,6 @@ type migrateModelSuite struct { var _ = gc.Suite(&migrateModelSuite{}) -var migrationResultRegex = `results: -- modeltag: model-.* - error: - message: 'target prechecks failed: model with same UUID already exists (.*)' - code: "" - info: {} - migrationid: "" -- modeltag: model-.* - error: - message: 'target prechecks failed: model with same UUID already exists (.*)' - code: "" - info: {} - migrationid: "" -` - // TestMigrateModelCommandSuperuser tests that a migration request makes it through to the Juju controller. // Because our test suite only spins up 1 controller the furthest we can go is reaching Juju pre-checks which // detect that a model with the same UUID already exists on the target controller. @@ -48,26 +36,26 @@ func (s *migrateModelSuite) TestMigrateModelCommandSuperuser(c *gc.C) { // alice is superuser bClient := s.SetupCLIAccess(c, "alice") - context, err := cmdtesting.RunCommand(c, cmd.NewMigrateModelCommandForTesting(s.ClientStore(), bClient), "controller-1", mt.Id(), mt2.Id()) + context, err := cmdtesting.RunCommand( + c, cmd.NewMigrateModelCommandForTesting(s.ClientStore(), bClient), + "controller-1", + mt.Id(), + "charlie@canonical.com/model-2", + ) c.Assert(err, gc.IsNil) - c.Assert(cmdtesting.Stdout(context), gc.Matches, migrationResultRegex) -} - -func (s *migrateModelSuite) TestMigrateModelCommandFailsWithInvalidModelTag(c *gc.C) { - s.AddController(c, "controller-1", s.APIInfo(c)) - cct := names.NewCloudCredentialTag(jimmtest.TestCloudName + "/charlie@canonical.com/cred") - s.UpdateCloudCredential(c, cct, jujuparams.CloudCredential{AuthType: "empty"}) - s.AddModel(c, names.NewUserTag("charlie@canonical.com"), "model-2", names.NewCloudTag(jimmtest.TestCloudName), jimmtest.TestCloudRegionName, cct) + res := &jujuparams.InitiateMigrationResults{} + out := cmdtesting.Stdout(context) + err = yaml.Unmarshal([]byte(out), res) + c.Assert(err, gc.IsNil) - // alice is superuser - bClient := s.SetupCLIAccess(c, "alice") - _, err := cmdtesting.RunCommand(c, cmd.NewMigrateModelCommandForTesting(s.ClientStore(), bClient), "controller-1", "001", "002") - c.Assert(err, gc.ErrorMatches, ".* is not a valid model uuid") + expected := "target prechecks failed: model with same UUID already exists (%s)" + c.Assert(res.Results[0].Error.Message, gc.Equals, fmt.Sprintf(expected, mt.Id())) + c.Assert(res.Results[1].Error.Message, gc.Equals, fmt.Sprintf(expected, mt2.Id())) } func (s *migrateModelSuite) TestMigrateModelCommandFailsWithMissingArgs(c *gc.C) { bClient := s.SetupCLIAccess(c, "alice") _, err := cmdtesting.RunCommand(c, cmd.NewMigrateModelCommandForTesting(s.ClientStore(), bClient), "myController") - c.Assert(err, gc.ErrorMatches, "Missing controller name and model uuid arguments") + c.Assert(err, gc.ErrorMatches, "Missing controller name and model target arguments") } diff --git a/internal/jimm/jimm.go b/internal/jimm/jimm.go index fdadd7977..254abebb5 100644 --- a/internal/jimm/jimm.go +++ b/internal/jimm/jimm.go @@ -14,6 +14,7 @@ import ( "github.com/coreos/go-oidc/v3/oidc" "github.com/go-macaroon-bakery/macaroon-bakery/v3/bakery" + "github.com/google/uuid" "github.com/juju/juju/api/base" "github.com/juju/juju/core/crossmodel" jujuparams "github.com/juju/juju/rpc/params" @@ -753,25 +754,45 @@ func fillMigrationTarget(db *db.Database, credStore credentials.CredentialStore, } // InitiateInternalMigration initiates a model migration between two controllers within JIMM. -func (j *JIMM) InitiateInternalMigration(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetController string) (jujuparams.InitiateMigrationResult, error) { +func (j *JIMM) InitiateInternalMigration(ctx context.Context, user *openfga.User, modelNameOrUUID string, targetController string) (jujuparams.InitiateMigrationResult, error) { const op = errors.Op("jimm.InitiateInternalMigration") migrationTarget, _, err := fillMigrationTarget(j.Database, j.CredentialStore, targetController) if err != nil { return jujuparams.InitiateMigrationResult{}, errors.E(op, err) } - // Check that the model exists - model := dbmodel.Model{ - UUID: sql.NullString{ - String: modelTag.Id(), + + model := dbmodel.Model{} + // Check if the user is providing a model UUID or name + _, err = uuid.Parse(modelNameOrUUID) + if err != nil { + s := strings.Split(modelNameOrUUID, "/") + if len(s) != 2 { + return jujuparams.InitiateMigrationResult{}, errors.E(op, "missing model name") + } + + owner, name := s[0], s[1] + if !names.IsValidUser(owner) { + return jujuparams.InitiateMigrationResult{}, errors.E(op, "invalid user name") + } + if !names.IsValidModelName(name) { + return jujuparams.InitiateMigrationResult{}, errors.E(op, "invalid model name") + } + + model.Name = name + model.OwnerIdentityName = owner + } else { + model.UUID = sql.NullString{ + String: modelNameOrUUID, Valid: true, - }, + } } + err = j.Database.GetModel(ctx, &model) if err != nil { return jujuparams.InitiateMigrationResult{}, errors.E(op, err) } - spec := jujuparams.MigrationSpec{ModelTag: modelTag.String(), TargetInfo: migrationTarget} + spec := jujuparams.MigrationSpec{ModelTag: model.ResourceTag().String(), TargetInfo: migrationTarget} result, err := initiateMigration(ctx, j, user, spec) if err != nil { return result, errors.E(op, err) diff --git a/internal/jimm/jimm_test.go b/internal/jimm/jimm_test.go index 478a29b07..a20766ab3 100644 --- a/internal/jimm/jimm_test.go +++ b/internal/jimm/jimm_test.go @@ -778,16 +778,39 @@ func TestInitiateInternalMigration(t *testing.T) { migrateInfo params.MigrateModelInfo expectedError string }{{ - about: "success", + about: "success with uuid", user: "alice@canonical.com", - migrateInfo: params.MigrateModelInfo{ModelTag: "model-00000002-0000-0000-0000-000000000001", TargetController: "myController"}, + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "00000002-0000-0000-0000-000000000001", TargetController: "myController"}, + }, { + about: "a success with name", + user: "alice@canonical.com", + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "alice@canonical.com/model-1", TargetController: "myController"}, }, { about: "model doesn't exist", user: "alice@canonical.com", - migrateInfo: params.MigrateModelInfo{ModelTag: "model-00000002-0000-0000-0000-000000000002", TargetController: "myController"}, + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "00000002-0000-0000-0000-000000000002", TargetController: "myController"}, expectedError: "model not found", - }, - } + }, { + about: "model doesn't exist", + user: "alice@canonical.com", + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "00000002-0000-0000-0000-000000000002", TargetController: "myController"}, + expectedError: "model not found", + }, { + about: "a missing model name", + user: "alice@canonical.com", + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "alice@canonical.com", TargetController: "myController"}, + expectedError: "missing model name", + }, { + about: "using an invalid user name", + user: "alice@canonical.com", + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "*bad wolf*@canonical.com/model-1", TargetController: "myController"}, + expectedError: "invalid user name", + }, { + about: "using an invalid model name", + user: "alice@canonical.com", + migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "alice@canonical.com/*bad wolf*", TargetController: "myController"}, + expectedError: "invalid model name", + }} for _, test := range tests { c.Run(test.about, func(c *qt.C) { c.Patch(jimm.InitiateMigration, func(ctx context.Context, j *jimm.JIMM, user *openfga.User, spec jujuparams.MigrationSpec) (jujuparams.InitiateMigrationResult, error) { @@ -806,9 +829,14 @@ func TestInitiateInternalMigration(t *testing.T) { dbUser := env.User(test.user).DBObject(c, j.Database) user := openfga.NewUser(&dbUser, nil) - mt, err := names.ParseModelTag(test.migrateInfo.ModelTag) c.Assert(err, qt.IsNil) - res, err := j.InitiateInternalMigration(ctx, user, mt, test.migrateInfo.TargetController) + + res, err := j.InitiateInternalMigration( + ctx, + user, + test.migrateInfo.TargetModelNameOrUUID, + test.migrateInfo.TargetController, + ) if test.expectedError != "" { c.Assert(err, qt.ErrorMatches, test.expectedError) } else { diff --git a/internal/jujuapi/controllerroot.go b/internal/jujuapi/controllerroot.go index c0fe44465..74a792014 100644 --- a/internal/jujuapi/controllerroot.go +++ b/internal/jujuapi/controllerroot.go @@ -64,7 +64,7 @@ type JIMM interface { GrantModelAccess(ctx context.Context, user *openfga.User, mt names.ModelTag, ut names.UserTag, access jujuparams.UserAccessPermission) error GrantOfferAccess(ctx context.Context, u *openfga.User, offerURL string, ut names.UserTag, access jujuparams.OfferAccessPermission) error GrantServiceAccountAccess(ctx context.Context, u *openfga.User, svcAccTag jimmnames.ServiceAccountTag, tags []string) error - InitiateInternalMigration(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetController string) (jujuparams.InitiateMigrationResult, error) + InitiateInternalMigration(ctx context.Context, user *openfga.User, modelNameOrUUID string, targetController string) (jujuparams.InitiateMigrationResult, error) InitiateMigration(ctx context.Context, user *openfga.User, spec jujuparams.MigrationSpec) (jujuparams.InitiateMigrationResult, error) ListApplicationOffers(ctx context.Context, user *openfga.User, filters ...jujuparams.OfferFilter) ([]jujuparams.ApplicationOfferAdminDetailsV5, error) ListIdentities(ctx context.Context, user *openfga.User, pagination pagination.LimitOffsetPagination, match string) ([]openfga.User, error) diff --git a/internal/jujuapi/jimm.go b/internal/jujuapi/jimm.go index 7e5d70e6e..14bca66a7 100644 --- a/internal/jujuapi/jimm.go +++ b/internal/jujuapi/jimm.go @@ -501,13 +501,9 @@ func (r *controllerRoot) MigrateModel(ctx context.Context, args apiparams.Migrat const op = errors.Op("jujuapi.MigrateModel") results := make([]jujuparams.InitiateMigrationResult, len(args.Specs)) + for i, arg := range args.Specs { - mt, err := names.ParseModelTag(arg.ModelTag) - if err != nil { - results[i].Error = mapError(errors.E(op, err)) - continue - } - result, err := r.jimm.InitiateInternalMigration(ctx, r.user, mt, arg.TargetController) + result, err := r.jimm.InitiateInternalMigration(ctx, r.user, arg.TargetModelNameOrUUID, arg.TargetController) if err != nil { result.Error = mapError(errors.E(op, err)) } diff --git a/internal/jujuapi/jimm_test.go b/internal/jujuapi/jimm_test.go index f9d50a01a..d8e34d112 100644 --- a/internal/jujuapi/jimm_test.go +++ b/internal/jujuapi/jimm_test.go @@ -855,15 +855,22 @@ func (s *jimmSuite) TestJimmModelMigrationSuperuser(c *gc.C) { res, err := client.MigrateModel(&apiparams.MigrateModelRequest{ Specs: []apiparams.MigrateModelInfo{ - {ModelTag: mt.String(), TargetController: "controller-1"}, + {TargetModelNameOrUUID: mt.Id(), TargetController: "controller-1"}, + {TargetModelNameOrUUID: "charlie@canonical.com/model-20", TargetController: "controller-1"}, }, }) c.Assert(err, gc.IsNil) - c.Assert(res.Results, gc.HasLen, 1) + c.Assert(res.Results, gc.HasLen, 2) + item := res.Results[0] c.Assert(item.ModelTag, gc.Equals, mt.String()) c.Assert(item.MigrationId, gc.Equals, "") c.Assert(item.Error.Message, gc.Matches, "target prechecks failed: model with same UUID already exists .*") + + item2 := res.Results[1] + c.Assert(item2.ModelTag, gc.Equals, mt.String()) + c.Assert(item2.MigrationId, gc.Equals, "") + c.Assert(item2.Error.Message, gc.Matches, "target prechecks failed: model with same UUID already exists .*") } func (s *jimmSuite) TestJimmModelMigrationNonSuperuser(c *gc.C) { @@ -882,7 +889,7 @@ func (s *jimmSuite) TestJimmModelMigrationNonSuperuser(c *gc.C) { res, err := client.MigrateModel(&apiparams.MigrateModelRequest{ Specs: []apiparams.MigrateModelInfo{ - {ModelTag: mt.String(), TargetController: "controller-1"}, + {TargetModelNameOrUUID: mt.Id(), TargetController: "controller-1"}, }, }) c.Assert(err, gc.IsNil) diff --git a/internal/testutils/jimmtest/jimm_mock.go b/internal/testutils/jimmtest/jimm_mock.go index 7d264085f..0b61fa46c 100644 --- a/internal/testutils/jimmtest/jimm_mock.go +++ b/internal/testutils/jimmtest/jimm_mock.go @@ -65,7 +65,7 @@ type JIMM struct { GrantOfferAccess_ func(ctx context.Context, u *openfga.User, offerURL string, ut names.UserTag, access jujuparams.OfferAccessPermission) error GrantServiceAccountAccess_ func(ctx context.Context, u *openfga.User, svcAccTag jimmnames.ServiceAccountTag, entities []string) error GroupManager_ func() jimm.GroupManager - InitiateInternalMigration_ func(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetController string) (jujuparams.InitiateMigrationResult, error) + InitiateInternalMigration_ func(ctx context.Context, user *openfga.User, modelNameOrUUID string, targetController string) (jujuparams.InitiateMigrationResult, error) InitiateMigration_ func(ctx context.Context, user *openfga.User, spec jujuparams.MigrationSpec) (jujuparams.InitiateMigrationResult, error) ListApplicationOffers_ func(ctx context.Context, user *openfga.User, filters ...jujuparams.OfferFilter) ([]jujuparams.ApplicationOfferAdminDetailsV5, error) ListIdentities_ func(ctx context.Context, user *openfga.User, pagination pagination.LimitOffsetPagination, match string) ([]openfga.User, error) @@ -307,11 +307,11 @@ func (j *JIMM) InitiateMigration(ctx context.Context, user *openfga.User, spec j } return j.InitiateMigration_(ctx, user, spec) } -func (j *JIMM) InitiateInternalMigration(ctx context.Context, user *openfga.User, modelTag names.ModelTag, targetController string) (jujuparams.InitiateMigrationResult, error) { +func (j *JIMM) InitiateInternalMigration(ctx context.Context, user *openfga.User, modelNameOrUUID string, targetController string) (jujuparams.InitiateMigrationResult, error) { if j.InitiateInternalMigration_ == nil { return jujuparams.InitiateMigrationResult{}, errors.E(errors.CodeNotImplemented) } - return j.InitiateInternalMigration_(ctx, user, modelTag, targetController) + return j.InitiateInternalMigration_(ctx, user, modelNameOrUUID, targetController) } func (j *JIMM) ListApplicationOffers(ctx context.Context, user *openfga.User, filters ...jujuparams.OfferFilter) ([]jujuparams.ApplicationOfferAdminDetailsV5, error) { if j.ListApplicationOffers_ == nil { diff --git a/pkg/api/params/params.go b/pkg/api/params/params.go index 5bcd18799..fe79f3cef 100644 --- a/pkg/api/params/params.go +++ b/pkg/api/params/params.go @@ -471,8 +471,8 @@ type PurgeLogsResponse struct { // target controller must be specified with both the source model and // target controller residing within JIMM. type MigrateModelInfo struct { - // ModelTag is a tag of the form "model-" - ModelTag string `json:"model-tag"` + // TargetModelNameOrUUID is a tag of the form "model-/model-" + TargetModelNameOrUUID string `json:"model-tag"` // TargetController is the controller name of the form "" TargetController string `json:"target-controller"` } From 64945295a28583f979160de044cbef1773bcffcc Mon Sep 17 00:00:00 2001 From: ale8k Date: Wed, 18 Dec 2024 09:52:08 +0000 Subject: [PATCH 2/4] style(pr comments): update doc strings --- cmd/jimmctl/cmd/migratemodel.go | 10 ++++++---- pkg/api/params/params.go | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cmd/jimmctl/cmd/migratemodel.go b/cmd/jimmctl/cmd/migratemodel.go index 381a34457..127210477 100644 --- a/cmd/jimmctl/cmd/migratemodel.go +++ b/cmd/jimmctl/cmd/migratemodel.go @@ -24,17 +24,19 @@ You may specify a model name (of the form owner/name) or model UUID. For example, JIMM is aware of controller-a and controller-b and controller-a has models: - - alice@canonical.com/model-a + - user@domain.com/model-a - 2cb433a6-04eb-4ec4-9567-90426d20a004 You may run the migrate command like so to migrate the two models from controller-a to controller-b: - jimmctl migrate controller-b model-a 2cb433a6-04eb-4ec4-9567-90426d20a004 + jimmctl migrate controller-b user@domain.com/model-a 2cb433a6-04eb-4ec4-9567-90426d20a004 ` migrateModelCommandExample = ` - jimmctl migrate mycontroller 2cb433a6-04eb-4ec4-9567-90426d20a004 - jimmctl migrate mycontroller model-a model-b fd469983-27c2-423b-bebf-84f616fb036b ... + jimmctl migrate mycontroller 2cb433a6-04eb-4ec4-9567-90426d20a004 fd469983-27c2-423b-bebf-84f616fb036b ... + jimmctl migrate mycontroller user@domain.com/model-a user@domain.com/model-b ... + jimmctl migrate mycontroller user@domain.com/model-a fd469983-27c2-423b-bebf-84f616fb036b ... + ` ) diff --git a/pkg/api/params/params.go b/pkg/api/params/params.go index fe79f3cef..b3a2ecf83 100644 --- a/pkg/api/params/params.go +++ b/pkg/api/params/params.go @@ -471,7 +471,7 @@ type PurgeLogsResponse struct { // target controller must be specified with both the source model and // target controller residing within JIMM. type MigrateModelInfo struct { - // TargetModelNameOrUUID is a tag of the form "model-/model-" + // TargetModelNameOrUUID can be either the model name or model UUID. TargetModelNameOrUUID string `json:"model-tag"` // TargetController is the controller name of the form "" TargetController string `json:"target-controller"` From 75158c63fed4f441e536c7204fa001f68ffdc777 Mon Sep 17 00:00:00 2001 From: ale8k Date: Wed, 18 Dec 2024 17:30:58 +0000 Subject: [PATCH 3/4] style(command example): pR comment suggestion --- cmd/jimmctl/cmd/migratemodel.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cmd/jimmctl/cmd/migratemodel.go b/cmd/jimmctl/cmd/migratemodel.go index 127210477..7fa858f65 100644 --- a/cmd/jimmctl/cmd/migratemodel.go +++ b/cmd/jimmctl/cmd/migratemodel.go @@ -22,15 +22,6 @@ registered within JIMM. You may specify a model name (of the form owner/name) or model UUID. -For example, JIMM is aware of controller-a and controller-b and controller-a has -models: - - user@domain.com/model-a - - 2cb433a6-04eb-4ec4-9567-90426d20a004 - -You may run the migrate command like so to migrate the two models -from controller-a to controller-b: - jimmctl migrate controller-b user@domain.com/model-a 2cb433a6-04eb-4ec4-9567-90426d20a004 - ` migrateModelCommandExample = ` jimmctl migrate mycontroller 2cb433a6-04eb-4ec4-9567-90426d20a004 fd469983-27c2-423b-bebf-84f616fb036b ... From b1b540101a15a027a1952b1b029051748852fc19 Mon Sep 17 00:00:00 2001 From: ale8k Date: Thu, 19 Dec 2024 08:40:40 +0000 Subject: [PATCH 4/4] pr comments --- internal/jimm/jimm.go | 2 +- internal/jimm/jimm_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/jimm/jimm.go b/internal/jimm/jimm.go index 4dd3e3959..961c02ee4 100644 --- a/internal/jimm/jimm.go +++ b/internal/jimm/jimm.go @@ -745,7 +745,7 @@ func (j *JIMM) InitiateInternalMigration(ctx context.Context, user *openfga.User if err != nil { s := strings.Split(modelNameOrUUID, "/") if len(s) != 2 { - return jujuparams.InitiateMigrationResult{}, errors.E(op, "missing model name") + return jujuparams.InitiateMigrationResult{}, errors.E(op, "invalid model target") } owner, name := s[0], s[1] diff --git a/internal/jimm/jimm_test.go b/internal/jimm/jimm_test.go index a20766ab3..7885bc7da 100644 --- a/internal/jimm/jimm_test.go +++ b/internal/jimm/jimm_test.go @@ -796,10 +796,10 @@ func TestInitiateInternalMigration(t *testing.T) { migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "00000002-0000-0000-0000-000000000002", TargetController: "myController"}, expectedError: "model not found", }, { - about: "a missing model name", + about: "a missing model target", user: "alice@canonical.com", migrateInfo: params.MigrateModelInfo{TargetModelNameOrUUID: "alice@canonical.com", TargetController: "myController"}, - expectedError: "missing model name", + expectedError: "invalid model target", }, { about: "using an invalid user name", user: "alice@canonical.com",