From 9eae132d1e8263f5a2cc6e2adb929dde9026423d Mon Sep 17 00:00:00 2001 From: Matthew John Date: Thu, 25 Jan 2024 06:51:30 +0000 Subject: [PATCH 1/6] Add okta profile configuration, in preparation to support multiple seperate configuration sections --- cmd/root/root.go | 7 ++++++ internal/config/config.go | 49 +++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/cmd/root/root.go b/cmd/root/root.go index 662ab41..3123d1d 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -101,6 +101,13 @@ func init() { usage: "AWS Profile", envVar: config.ProfileEnvVar, }, + { + name: config.OktaProfileFlag, + short: "t", + value: "", + usage: "Okta Config Profile", + envVar: config.OktaProfileEnvVar, + }, { name: config.FormatFlag, short: "f", diff --git a/internal/config/config.go b/internal/config/config.go index 0f3776f..13eb912 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -62,6 +62,8 @@ const ( OrgDomainFlag = "org-domain" // ProfileFlag cli flag const ProfileFlag = "profile" + // OktaProfileFlag cli flag const + OktaProfileFlag = "okta-profile" // QRCodeFlag cli flag const QRCodeFlag = "qr-code" // SessionDurationFlag cli flag const @@ -95,6 +97,8 @@ const ( OpenBrowserEnvVar = "OKTA_AWSCLI_OPEN_BROWSER" // ProfileEnvVar env var const ProfileEnvVar = "OKTA_AWSCLI_PROFILE" + // OktaProfileEnvVar env var const + OktaProfileEnvVar = "OKTA_AWSCLI_OKTA_PROFILE" // QRCodeEnvVar env var const QRCodeEnvVar = "OKTA_AWSCLI_QR_CODE" // WriteAWSCredentialsEnvVar env var const @@ -234,26 +238,35 @@ func NewConfig(attrs Attributes) (*Config, error) { return cfg, nil } +func getFlagNameFromProfile(oktaProfile string, flag string) string { + if oktaProfile == "" { + return flag + } + return fmt.Sprintf("%s.%s", oktaProfile, flag) +} + func readConfig() (Attributes, error) { + oktaProfile := viper.GetString(OktaProfileFlag) + attrs := Attributes{ - AWSCredentials: viper.GetString(AWSCredentialsFlag), - AWSIAMIdP: viper.GetString(AWSIAMIdPFlag), - AWSIAMRole: viper.GetString(AWSIAMRoleFlag), - AWSSessionDuration: viper.GetInt64(SessionDurationFlag), - Debug: viper.GetBool(DebugFlag), - DebugAPICalls: viper.GetBool(DebugAPICallsFlag), - DebugConfig: viper.GetBool(DebugConfigFlag), - FedAppID: viper.GetString(AWSAcctFedAppIDFlag), - Format: viper.GetString(FormatFlag), - LegacyAWSVariables: viper.GetBool(LegacyAWSVariablesFlag), - ExpiryAWSVariables: viper.GetBool(ExpiryAWSVariablesFlag), - CacheAccessToken: viper.GetBool(CacheAccessTokenFlag), - OIDCAppID: viper.GetString(OIDCClientIDFlag), - OpenBrowser: viper.GetBool(OpenBrowserFlag), - OrgDomain: viper.GetString(OrgDomainFlag), - Profile: viper.GetString(ProfileFlag), - QRCode: viper.GetBool(QRCodeFlag), - WriteAWSCredentials: viper.GetBool(WriteAWSCredentialsFlag), + AWSCredentials: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSCredentialsFlag)), + AWSIAMIdP: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSIAMIdPFlag)), + AWSIAMRole: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSIAMRoleFlag)), + AWSSessionDuration: viper.GetInt64(getFlagNameFromProfile(oktaProfile, SessionDurationFlag)), + Debug: viper.GetBool(getFlagNameFromProfile(oktaProfile, DebugFlag)), + DebugAPICalls: viper.GetBool(getFlagNameFromProfile(oktaProfile, DebugAPICallsFlag)), + DebugConfig: viper.GetBool(getFlagNameFromProfile(oktaProfile, DebugConfigFlag)), + FedAppID: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSAcctFedAppIDFlag)), + Format: viper.GetString(getFlagNameFromProfile(oktaProfile, FormatFlag)), + LegacyAWSVariables: viper.GetBool(getFlagNameFromProfile(oktaProfile, LegacyAWSVariablesFlag)), + ExpiryAWSVariables: viper.GetBool(getFlagNameFromProfile(oktaProfile, ExpiryAWSVariablesFlag)), + CacheAccessToken: viper.GetBool(getFlagNameFromProfile(oktaProfile, CacheAccessTokenFlag)), + OIDCAppID: viper.GetString(getFlagNameFromProfile(oktaProfile, OIDCClientIDFlag)), + OpenBrowser: viper.GetBool(getFlagNameFromProfile(oktaProfile, OpenBrowserFlag)), + OrgDomain: viper.GetString(getFlagNameFromProfile(oktaProfile, OrgDomainFlag)), + Profile: viper.GetString(getFlagNameFromProfile(oktaProfile, ProfileFlag)), + QRCode: viper.GetBool(getFlagNameFromProfile(oktaProfile, QRCodeFlag)), + WriteAWSCredentials: viper.GetBool(getFlagNameFromProfile(oktaProfile, WriteAWSCredentialsFlag)), } if attrs.Format == "" { attrs.Format = EnvVarFormat From 8f06f59240097160619532182e552e716be42236 Mon Sep 17 00:00:00 2001 From: Matthew John Date: Thu, 25 Jan 2024 06:56:49 +0000 Subject: [PATCH 2/6] Add support for yaml config in user's home directory, containing multiple okta profiles --- cmd/root/root.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cmd/root/root.go b/cmd/root/root.go index 3123d1d..535dfb2 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "os" + "os/user" "path/filepath" "strings" @@ -241,6 +242,28 @@ to collect a proper IAM role for the AWS CLI operator.`, _ = os.Setenv(awsRegionEnvVar, vipAwsRegion) } } + + // Check if .okta-aws-cli/conifg.yml exists + usr, err := user.Current() + if err == nil { + oktaConfig := filepath.Join(usr.HomeDir, ".okta-aws-cli", "config.yml") + if _, err := os.Stat(oktaConfig); err == nil || !errors.Is(err, os.ErrNotExist) { + viper.AddConfigPath(filepath.Join(usr.HomeDir, ".okta-aws-cli")) + viper.SetConfigName("config.yml") + viper.SetConfigType("yml") + + _ = viper.ReadInConfig() + + // After viper reads in the dotenv file check if AWS_REGION is set + // there. The value will be keyed by lower case name. If it is, set + // AWS_REGION as an ENV VAR if it hasn't already been. + awsRegionEnvVar := "AWS_REGION" + vipAwsRegion := viper.GetString(strings.ToLower(awsRegionEnvVar)) + if vipAwsRegion != "" && os.Getenv(awsRegionEnvVar) == "" { + _ = os.Setenv(awsRegionEnvVar, vipAwsRegion) + } + } + } viper.AutomaticEnv() // bind cli flags From 67f28be0d777d32c0ea96475d0e12831453be3b8 Mon Sep 17 00:00:00 2001 From: Matthew John Date: Thu, 25 Jan 2024 06:57:57 +0000 Subject: [PATCH 3/6] Update to only use .okta-aws-cli config if .env is not present in current directory to avoid mixing configurations --- cmd/root/root.go | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/cmd/root/root.go b/cmd/root/root.go index 535dfb2..60533f1 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -241,26 +241,26 @@ to collect a proper IAM role for the AWS CLI operator.`, if vipAwsRegion != "" && os.Getenv(awsRegionEnvVar) == "" { _ = os.Setenv(awsRegionEnvVar, vipAwsRegion) } - } - - // Check if .okta-aws-cli/conifg.yml exists - usr, err := user.Current() - if err == nil { - oktaConfig := filepath.Join(usr.HomeDir, ".okta-aws-cli", "config.yml") - if _, err := os.Stat(oktaConfig); err == nil || !errors.Is(err, os.ErrNotExist) { - viper.AddConfigPath(filepath.Join(usr.HomeDir, ".okta-aws-cli")) - viper.SetConfigName("config.yml") - viper.SetConfigType("yml") + } else { + // Check if .okta-aws-cli/conifg.yml exists + usr, err := user.Current() + if err == nil { + oktaConfig := filepath.Join(usr.HomeDir, ".okta-aws-cli", "config.yml") + if _, err := os.Stat(oktaConfig); err == nil || !errors.Is(err, os.ErrNotExist) { + viper.AddConfigPath(filepath.Join(usr.HomeDir, ".okta-aws-cli")) + viper.SetConfigName("config.yml") + viper.SetConfigType("yml") - _ = viper.ReadInConfig() + _ = viper.ReadInConfig() - // After viper reads in the dotenv file check if AWS_REGION is set - // there. The value will be keyed by lower case name. If it is, set - // AWS_REGION as an ENV VAR if it hasn't already been. - awsRegionEnvVar := "AWS_REGION" - vipAwsRegion := viper.GetString(strings.ToLower(awsRegionEnvVar)) - if vipAwsRegion != "" && os.Getenv(awsRegionEnvVar) == "" { - _ = os.Setenv(awsRegionEnvVar, vipAwsRegion) + // After viper reads in the dotenv file check if AWS_REGION is set + // there. The value will be keyed by lower case name. If it is, set + // AWS_REGION as an ENV VAR if it hasn't already been. + awsRegionEnvVar := "AWS_REGION" + vipAwsRegion := viper.GetString(strings.ToLower(awsRegionEnvVar)) + if vipAwsRegion != "" && os.Getenv(awsRegionEnvVar) == "" { + _ = os.Setenv(awsRegionEnvVar, vipAwsRegion) + } } } } From 201f375a1cef9aa156d36be1cd6a5aa7c015b41f Mon Sep 17 00:00:00 2001 From: Matthew John Date: Thu, 25 Jan 2024 19:01:36 +0000 Subject: [PATCH 4/6] Remove new okta profile and Update new YML config to be keyed by the AWS config. Search for available configurations based on AWS profile dict in config before falling back to the root version of the config. This also allows common configurations (such as Okta domain) to be specified in the config outside of a profile --- cmd/root/root.go | 7 ----- internal/config/config.go | 56 ++++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/cmd/root/root.go b/cmd/root/root.go index 60533f1..68df4f9 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -102,13 +102,6 @@ func init() { usage: "AWS Profile", envVar: config.ProfileEnvVar, }, - { - name: config.OktaProfileFlag, - short: "t", - value: "", - usage: "Okta Config Profile", - envVar: config.OktaProfileEnvVar, - }, { name: config.FormatFlag, short: "f", diff --git a/internal/config/config.go b/internal/config/config.go index 13eb912..2bb7ac3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -62,8 +62,8 @@ const ( OrgDomainFlag = "org-domain" // ProfileFlag cli flag const ProfileFlag = "profile" - // OktaProfileFlag cli flag const - OktaProfileFlag = "okta-profile" + // awsProfileFlag cli flag const + awsProfileFlag = "okta-profile" // QRCodeFlag cli flag const QRCodeFlag = "qr-code" // SessionDurationFlag cli flag const @@ -97,8 +97,8 @@ const ( OpenBrowserEnvVar = "OKTA_AWSCLI_OPEN_BROWSER" // ProfileEnvVar env var const ProfileEnvVar = "OKTA_AWSCLI_PROFILE" - // OktaProfileEnvVar env var const - OktaProfileEnvVar = "OKTA_AWSCLI_OKTA_PROFILE" + // awsProfileEnvVar env var const + awsProfileEnvVar = "OKTA_AWSCLI_OKTA_PROFILE" // QRCodeEnvVar env var const QRCodeEnvVar = "OKTA_AWSCLI_QR_CODE" // WriteAWSCredentialsEnvVar env var const @@ -238,35 +238,37 @@ func NewConfig(attrs Attributes) (*Config, error) { return cfg, nil } -func getFlagNameFromProfile(oktaProfile string, flag string) string { - if oktaProfile == "" { - return flag +func getFlagNameFromProfile(awsProfile string, flag string) string { + profileKey := fmt.Sprintf("%s.%s", awsProfile, flag) + if awsProfile != "" && viper.IsSet(profileKey) == true { + return profileKey } - return fmt.Sprintf("%s.%s", oktaProfile, flag) + return flag } func readConfig() (Attributes, error) { - oktaProfile := viper.GetString(OktaProfileFlag) + awsProfile := viper.GetString(ProfileFlag) + fmt.Printf("AWS PRofile: %v\n", awsProfile) attrs := Attributes{ - AWSCredentials: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSCredentialsFlag)), - AWSIAMIdP: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSIAMIdPFlag)), - AWSIAMRole: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSIAMRoleFlag)), - AWSSessionDuration: viper.GetInt64(getFlagNameFromProfile(oktaProfile, SessionDurationFlag)), - Debug: viper.GetBool(getFlagNameFromProfile(oktaProfile, DebugFlag)), - DebugAPICalls: viper.GetBool(getFlagNameFromProfile(oktaProfile, DebugAPICallsFlag)), - DebugConfig: viper.GetBool(getFlagNameFromProfile(oktaProfile, DebugConfigFlag)), - FedAppID: viper.GetString(getFlagNameFromProfile(oktaProfile, AWSAcctFedAppIDFlag)), - Format: viper.GetString(getFlagNameFromProfile(oktaProfile, FormatFlag)), - LegacyAWSVariables: viper.GetBool(getFlagNameFromProfile(oktaProfile, LegacyAWSVariablesFlag)), - ExpiryAWSVariables: viper.GetBool(getFlagNameFromProfile(oktaProfile, ExpiryAWSVariablesFlag)), - CacheAccessToken: viper.GetBool(getFlagNameFromProfile(oktaProfile, CacheAccessTokenFlag)), - OIDCAppID: viper.GetString(getFlagNameFromProfile(oktaProfile, OIDCClientIDFlag)), - OpenBrowser: viper.GetBool(getFlagNameFromProfile(oktaProfile, OpenBrowserFlag)), - OrgDomain: viper.GetString(getFlagNameFromProfile(oktaProfile, OrgDomainFlag)), - Profile: viper.GetString(getFlagNameFromProfile(oktaProfile, ProfileFlag)), - QRCode: viper.GetBool(getFlagNameFromProfile(oktaProfile, QRCodeFlag)), - WriteAWSCredentials: viper.GetBool(getFlagNameFromProfile(oktaProfile, WriteAWSCredentialsFlag)), + AWSCredentials: viper.GetString(getFlagNameFromProfile(awsProfile, AWSCredentialsFlag)), + AWSIAMIdP: viper.GetString(getFlagNameFromProfile(awsProfile, AWSIAMIdPFlag)), + AWSIAMRole: viper.GetString(getFlagNameFromProfile(awsProfile, AWSIAMRoleFlag)), + AWSSessionDuration: viper.GetInt64(getFlagNameFromProfile(awsProfile, SessionDurationFlag)), + Debug: viper.GetBool(getFlagNameFromProfile(awsProfile, DebugFlag)), + DebugAPICalls: viper.GetBool(getFlagNameFromProfile(awsProfile, DebugAPICallsFlag)), + DebugConfig: viper.GetBool(getFlagNameFromProfile(awsProfile, DebugConfigFlag)), + FedAppID: viper.GetString(getFlagNameFromProfile(awsProfile, AWSAcctFedAppIDFlag)), + Format: viper.GetString(getFlagNameFromProfile(awsProfile, FormatFlag)), + LegacyAWSVariables: viper.GetBool(getFlagNameFromProfile(awsProfile, LegacyAWSVariablesFlag)), + ExpiryAWSVariables: viper.GetBool(getFlagNameFromProfile(awsProfile, ExpiryAWSVariablesFlag)), + CacheAccessToken: viper.GetBool(getFlagNameFromProfile(awsProfile, CacheAccessTokenFlag)), + OIDCAppID: viper.GetString(getFlagNameFromProfile(awsProfile, OIDCClientIDFlag)), + OpenBrowser: viper.GetBool(getFlagNameFromProfile(awsProfile, OpenBrowserFlag)), + OrgDomain: viper.GetString(getFlagNameFromProfile(awsProfile, OrgDomainFlag)), + Profile: awsProfile, + QRCode: viper.GetBool(getFlagNameFromProfile(awsProfile, QRCodeFlag)), + WriteAWSCredentials: viper.GetBool(getFlagNameFromProfile(awsProfile, WriteAWSCredentialsFlag)), } if attrs.Format == "" { attrs.Format = EnvVarFormat From 2a47fce72595bdab7c1570bcb3ee3a6e93eb77af Mon Sep 17 00:00:00 2001 From: Matthew John Date: Mon, 12 Feb 2024 15:11:47 +0000 Subject: [PATCH 5/6] Remove unused argument flags --- internal/config/config.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index a5347e2..e25285f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -88,8 +88,6 @@ const ( KeyIDFlag = "key-id" // ProfileFlag cli flag const ProfileFlag = "profile" - // awsProfileFlag cli flag const - awsProfileFlag = "okta-profile" // QRCodeFlag cli flag const QRCodeFlag = "qr-code" // SessionDurationFlag cli flag const @@ -155,8 +153,6 @@ const ( KeyIDEnvVar = "OKTA_AWSCLI_KEY_ID" // ProfileEnvVar env var const ProfileEnvVar = "OKTA_AWSCLI_PROFILE" - // awsProfileEnvVar env var const - awsProfileEnvVar = "OKTA_AWSCLI_OKTA_PROFILE" // QRCodeEnvVar env var const QRCodeEnvVar = "OKTA_AWSCLI_QR_CODE" // WriteAWSCredentialsEnvVar env var const From 2bdd95a4e3dba3357674913185b6a651106c10e7 Mon Sep 17 00:00:00 2001 From: Matthew John Date: Mon, 12 Feb 2024 15:12:09 +0000 Subject: [PATCH 6/6] Remove debug --- internal/config/config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/config/config.go b/internal/config/config.go index e25285f..14321bc 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -320,7 +320,6 @@ func getFlagNameFromProfile(awsProfile string, flag string) string { func readConfig() (Attributes, error) { awsProfile := viper.GetString(ProfileFlag) - fmt.Printf("AWS PRofile: %v\n", awsProfile) attrs := Attributes{ AllProfiles: viper.GetBool(getFlagNameFromProfile(awsProfile, AllProfilesFlag)),