diff --git a/internal/cmd/root.go b/internal/cmd/root.go index c09feab57..62a5b0b6e 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -60,8 +60,13 @@ func NewRootCmd(version, date string, p *print.Printer) *cobra.Command { if err != nil { return fmt.Errorf("get profile: %w", err) } - if activeProfile == "" { - activeProfile = "(no active profile, the default profile configuration will be used)" + + profileExists, err := config.ProfileExists(activeProfile) + if err != nil { + return fmt.Errorf("check if profile exists: %w", err) + } + if !profileExists { + p.Warn("active profile does not exist, the default profile configuration will be used\n") } p.Debug(print.DebugLevel, "active configuration profile: %s", activeProfile) diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 9ca50bccb..b6ab86ea3 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -41,7 +41,8 @@ const ( ) const ( - configFolder = "stackit" + configFolder = "stackit" + defaultProfileName = "default" configFileName = "cli-config" configFileExtension = "json" @@ -92,7 +93,7 @@ func InitConfig() { cobra.CheckErr(err) configFolderPath = defaultConfigFolderPath - if configProfile != "" { + if configProfile != defaultProfileName { configFolderPath = filepath.Join(configFolderPath, profileRootFolder, configProfile) // If a profile is set, use the profile config folder } diff --git a/internal/pkg/config/profiles.go b/internal/pkg/config/profiles.go index 833176ae1..9723c3862 100644 --- a/internal/pkg/config/profiles.go +++ b/internal/pkg/config/profiles.go @@ -18,7 +18,7 @@ const ProfileEnvVar = "STACKIT_CLI_PROFILE" // The profile is determined by the value of the STACKIT_CLI_PROFILE environment variable, or, if not set, // by the contents of the profile file in the CLI config folder. // -// If the environment variable is not set and the profile file does not exist, it returns an empty string. +// If the profile is not set (env var or profile file) or is set but does not exist, it falls back to the default profile. // // If the profile is not valid, it returns an error. func GetProfile() (string, error) { @@ -29,7 +29,7 @@ func GetProfile() (string, error) { return "", fmt.Errorf("read profile from file: %w", err) } if !exists { - return "", nil + return defaultProfileName, nil } profile = contents } @@ -40,7 +40,7 @@ func GetProfile() (string, error) { return "", fmt.Errorf("check if profile exists: %w", err) } if !profileExists { - return "", &errors.SetInexistentProfile{Profile: profile} + return defaultProfileName, nil } err = ValidateProfile(profile) @@ -67,6 +67,13 @@ func CreateProfile(p *print.Printer, profile string, setProfile, emptyProfile bo return fmt.Errorf("validate profile: %w", err) } + // Cannot create a profile with the default name + if profile == defaultProfileName { + return &errors.InvalidProfileNameError{ + Profile: profile, + } + } + configFolderPath = filepath.Join(defaultConfigFolderPath, profileRootFolder, profile) // Error if the profile already exists @@ -81,19 +88,18 @@ func CreateProfile(p *print.Printer, profile string, setProfile, emptyProfile bo } p.Debug(print.DebugLevel, "created folder for the new profile: %s", configFolderPath) - currentProfile, err := GetProfile() - if err != nil { - // Cleanup created directory - cleanupErr := os.RemoveAll(configFolderPath) - if cleanupErr != nil { - return fmt.Errorf("get active profile: %w, cleanup directories: %w", err, cleanupErr) + if !emptyProfile { + currentProfile, err := GetProfile() + if err != nil { + // Cleanup created directory + cleanupErr := os.RemoveAll(configFolderPath) + if cleanupErr != nil { + return fmt.Errorf("get active profile: %w, cleanup directories: %w", err, cleanupErr) + } + return fmt.Errorf("get active profile: %w", err) } - return fmt.Errorf("get active profile: %w", err) - } - - p.Debug(print.DebugLevel, "current active profile: %q", currentProfile) - if !emptyProfile { + p.Debug(print.DebugLevel, "current active profile: %q", currentProfile) p.Debug(print.DebugLevel, "duplicating profile configuration from %q to new profile %q", currentProfile, profile) err = DuplicateProfileConfiguration(p, currentProfile, profile) if err != nil { @@ -122,8 +128,8 @@ func CreateProfile(p *print.Printer, profile string, setProfile, emptyProfile bo // If the new profile already exists, it will be overwritten. func DuplicateProfileConfiguration(p *print.Printer, currentProfile, newProfile string) error { var currentConfigFilePath string - // If the current profile is empty, its the default profile - if currentProfile == "" { + + if currentProfile == defaultProfileName { currentConfigFilePath = filepath.Join(defaultConfigFolderPath, fmt.Sprintf("%s.%s", configFileName, configFileExtension)) } else { currentConfigFilePath = filepath.Join(defaultConfigFolderPath, profileRootFolder, currentProfile, fmt.Sprintf("%s.%s", configFileName, configFileExtension)) @@ -154,7 +160,7 @@ func SetProfile(p *print.Printer, profile string) error { } if !profileExists { - return fmt.Errorf("profile %q does not exist", profile) + return &errors.SetInexistentProfile{Profile: profile} } err = os.WriteFile(profileFilePath, []byte(profile), os.ModePerm) diff --git a/internal/pkg/errors/errors.go b/internal/pkg/errors/errors.go index e32cc5bae..4839698ae 100644 --- a/internal/pkg/errors/errors.go +++ b/internal/pkg/errors/errors.go @@ -38,7 +38,10 @@ Please double check if they are correctly configured. For more details run: $ stackit auth activate-service-account -h` - SET_INEXISTENT_PROFILE = `the configuration profile %[1]q does not exist. + SET_INEXISTENT_PROFILE = `the active configuration profile %[1]q does not exist. + +To unset it, run: + $ stackit config profile unset To create it, run: $ stackit config profile create %[1]q` @@ -122,7 +125,7 @@ For more details on the available storages for the configured flavor (%[3]s), ru INVALID_PROFILE_NAME = `the profile name %q is invalid. -The profile name can only contain letters, numbers, and "-" and cannot be empty.` +The profile name can only contain letters, numbers, and "-" and cannot be empty or "default".` USAGE_TIP = `For usage help, run: $ %s --help` diff --git a/internal/pkg/fileutils/file_utils.go b/internal/pkg/fileutils/file_utils.go index c9f6770be..b20bb7779 100644 --- a/internal/pkg/fileutils/file_utils.go +++ b/internal/pkg/fileutils/file_utils.go @@ -30,7 +30,7 @@ func WriteToFile(outputFileName, content string) (err error) { } // ReadFileIfExists reads the contents of a file and returns it as a string, along with a boolean indicating if the file exists. -// If the file does not exist, it returns an empty string and no error. +// If the file does not exist, it returns an empty string, false and no error. // If the file exists but cannot be read, it returns an error. func ReadFileIfExists(filePath string) (contents string, exists bool, err error) { _, err = os.Stat(filePath)