diff --git a/internal/namespaces/init/init.go b/internal/namespaces/init/init.go index 25ae2a1391..309fbab129 100644 --- a/internal/namespaces/init/init.go +++ b/internal/namespaces/init/init.go @@ -136,7 +136,12 @@ Default path for configuration file is based on the following priority order: // Show logo banner, or simple welcome message printScalewayBanner() - err := promptProfileOverride(ctx, configPath, profileName) + config, err := loadConfigOrEmpty(configPath) + if err != nil { + return nil, err + } + + err = promptProfileOverride(ctx, config, configPath, profileName) if err != nil { return nil, err } @@ -215,11 +220,6 @@ Default path for configuration file is based on the following priority order: DefaultProjectID: &args.ProjectID, // An API key is always bound to a project. } - config, err := loadConfigOrEmpty(configPath) - if err != nil { - return nil, err - } - // Save the profile as default or as a named profile if profileName == scw.DefaultProfileName { // Default configuration diff --git a/internal/namespaces/init/init_test.go b/internal/namespaces/init/init_test.go index 40807c20a1..dfdae3c312 100644 --- a/internal/namespaces/init/init_test.go +++ b/internal/namespaces/init/init_test.go @@ -108,8 +108,9 @@ func TestInit(t *testing.T) { }, Profiles: map[string]*scw.Profile{ "test": { - AccessKey: &dummyAccessKey, - SecretKey: &dummySecretKey, + AccessKey: &dummyAccessKey, + SecretKey: &dummySecretKey, + DefaultZone: scw.StringPtr("fr-test"), // Used to check profile override }, }, } @@ -154,5 +155,46 @@ func TestInit(t *testing.T) { "yes", }, })) + + t.Run("No Prompt Overwrite for new profile", core.Test(&core.TestConfig{ + Commands: GetCommands(), + BeforeFunc: core.BeforeFuncCombine( + baseBeforeFunc(), + beforeFuncSaveConfig(dummyConfig), + ), + Cmd: appendArgs("scw -p test2 init", defaultArgs), + Check: core.TestCheckCombine( + core.TestCheckGolden(), + checkConfig(func(t *testing.T, ctx *core.CheckFuncCtx, config *scw.Config) { + assert.NotNil(t, config.Profiles["test2"], "new profile should have been created") + }), + ), + TmpHomeDir: true, + PromptResponseMocks: []string{ + // Do you want to override the current config? (Should not be prompted as profile is a new one) + "no", + }, + })) + + t.Run("Prompt Overwrite for existing profile", core.Test(&core.TestConfig{ + Commands: GetCommands(), + BeforeFunc: core.BeforeFuncCombine( + baseBeforeFunc(), + beforeFuncSaveConfig(dummyConfig), + ), + Cmd: appendArgs("scw -p test init", defaultArgs), + Check: core.TestCheckCombine( + core.TestCheckGolden(), + checkConfig(func(t *testing.T, ctx *core.CheckFuncCtx, config *scw.Config) { + assert.NotNil(t, config.Profiles["test"].DefaultZone) + assert.Equal(t, *config.Profiles["test"].DefaultZone, "fr-test") + }), + ), + TmpHomeDir: true, + PromptResponseMocks: []string{ + // Do you want to override the current config? (Should not be prompted as profile is a new one) + "no", + }, + })) }) } diff --git a/internal/namespaces/init/prompt.go b/internal/namespaces/init/prompt.go index b8adc9bc02..3d3dc65aac 100644 --- a/internal/namespaces/init/prompt.go +++ b/internal/namespaces/init/prompt.go @@ -163,15 +163,22 @@ func promptDefaultZone(ctx context.Context) (scw.Zone, error) { return scw.ParseZone(zone) } -// promptProfileOverride prompt user if profileName is getting override in configPath -func promptProfileOverride(ctx context.Context, configPath string, profileName string) error { - config, err := scw.LoadConfigFromPath(configPath) +// promptProfileOverride prompt user if profileName is getting override in config +func promptProfileOverride(ctx context.Context, config *scw.Config, configPath string, profileName string) error { + var profile *scw.Profile + var profileExists bool + + if profileName == scw.DefaultProfileName { + profile = &config.Profile + profileExists = true + } else { + profile, profileExists = config.Profiles[profileName] + } - // If it is not a new config, ask if we want to override the existing config - if err == nil && !config.IsEmpty() { + if !config.IsEmpty() && profileExists { _, _ = interactive.PrintlnWithoutIndent(` Current config is located at ` + configPath + ` - ` + terminal.Style(fmt.Sprint(config), color.Faint) + ` + ` + terminal.Style(fmt.Sprint(profile), color.Faint) + ` `) overrideConfig, err := interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ Prompt: fmt.Sprintf("Do you want to override the current profile (%s) ?", profileName), diff --git a/internal/namespaces/init/testdata/test-init-cl-iv2-config-no-prompt-overwrite-for-new-profile.cassette.yaml b/internal/namespaces/init/testdata/test-init-cl-iv2-config-no-prompt-overwrite-for-new-profile.cassette.yaml new file mode 100644 index 0000000000..4daaa07ee1 --- /dev/null +++ b/internal/namespaces/init/testdata/test-init-cl-iv2-config-no-prompt-overwrite-for-new-profile.cassette.yaml @@ -0,0 +1,35 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.20.1; linux; amd64) cli-e2e-test + url: https://api.scaleway.com/iam/v1alpha1/api-keys/SCWXXXXXXXXXXXXXXXXX + method: GET + response: + body: '{"message":"authentication is denied","method":"api_key","reason":"not_found","type":"denied_authentication"}' + headers: + Content-Length: + - "109" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Thu, 27 Apr 2023 09:09:09 GMT + Server: + - Scaleway API-Gateway + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 4765a621-1ac1-4a7f-bdb4-4602f94764eb + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/internal/namespaces/init/testdata/test-init-cl-iv2-config-no-prompt-overwrite-for-new-profile.golden b/internal/namespaces/init/testdata/test-init-cl-iv2-config-no-prompt-overwrite-for-new-profile.golden new file mode 100644 index 0000000000..0b45034930 --- /dev/null +++ b/internal/namespaces/init/testdata/test-init-cl-iv2-config-no-prompt-overwrite-for-new-profile.golden @@ -0,0 +1,8 @@ +🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 +🟩🟩🟩 STDOUT️ 🟩🟩🟩️ +βœ… Initialization completed with success. +🟩🟩🟩 JSON STDOUT 🟩🟩🟩 +{ + "message": "Initialization completed with success", + "details": "" +} diff --git a/internal/namespaces/init/testdata/test-init-cl-iv2-config-prompt-overwrite-for-existing-profile.cassette.yaml b/internal/namespaces/init/testdata/test-init-cl-iv2-config-prompt-overwrite-for-existing-profile.cassette.yaml new file mode 100644 index 0000000000..d36cb8e91e --- /dev/null +++ b/internal/namespaces/init/testdata/test-init-cl-iv2-config-prompt-overwrite-for-existing-profile.cassette.yaml @@ -0,0 +1,35 @@ +--- +version: 1 +interactions: +- request: + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.20.1; linux; amd64) cli-e2e-test + url: https://api.scaleway.com/iam/v1alpha1/api-keys/SCWXXXXXXXXXXXXXXXXX + method: GET + response: + body: '{"message":"authentication is denied","method":"api_key","reason":"not_found","type":"denied_authentication"}' + headers: + Content-Length: + - "109" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Thu, 27 Apr 2023 09:09:09 GMT + Server: + - Scaleway API-Gateway + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 314626bd-48a4-4e66-91bc-7a31b3f17210 + status: 401 Unauthorized + code: 401 + duration: "" diff --git a/internal/namespaces/init/testdata/test-init-cl-iv2-config-prompt-overwrite-for-existing-profile.golden b/internal/namespaces/init/testdata/test-init-cl-iv2-config-prompt-overwrite-for-existing-profile.golden new file mode 100644 index 0000000000..f5a59a5562 --- /dev/null +++ b/internal/namespaces/init/testdata/test-init-cl-iv2-config-prompt-overwrite-for-existing-profile.golden @@ -0,0 +1,7 @@ +🎲🎲🎲 EXIT CODE: 1 🎲🎲🎲 +πŸŸ₯πŸŸ₯πŸŸ₯ STDERR️️ πŸŸ₯πŸŸ₯πŸŸ₯️ +Initialization canceled +πŸŸ₯πŸŸ₯πŸŸ₯ JSON STDERR πŸŸ₯πŸŸ₯πŸŸ₯ +{ + "error": "initialization canceled" +}