From d2311e33670ae9df9b3582a1005c740d2af76669 Mon Sep 17 00:00:00 2001 From: Eugene Chen Date: Wed, 24 Jan 2024 13:51:17 -0800 Subject: [PATCH 1/6] Initial commit --- cmd/root/root.go | 7 +++++++ internal/aws/aws.go | 1 + internal/config/config.go | 19 ++++++++++++++++++- internal/output/aws_credentials_file.go | 17 +++++++++++++++-- internal/sessiontoken/sessiontoken.go | 12 +++++++----- 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/cmd/root/root.go b/cmd/root/root.go index 662ab41..e294d1c 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -87,6 +87,13 @@ func init() { usage: "Preset IAM Role ARN", envVar: config.AWSIAMRoleEnvVar, }, + { + name: config.AWSRegionFlag, + short: "", + value: "", + usage: "Preset AWS Region", + envVar: config.AWSRegionEnvVar, + }, { name: config.SessionDurationFlag, short: "s", diff --git a/internal/aws/aws.go b/internal/aws/aws.go index c7cde96..ae23233 100644 --- a/internal/aws/aws.go +++ b/internal/aws/aws.go @@ -21,4 +21,5 @@ type Credential struct { AccessKeyID string `ini:"aws_access_key_id"` SecretAccessKey string `ini:"aws_secret_access_key"` SessionToken string `ini:"aws_session_token"` + Region string `ini:"region"` } diff --git a/internal/config/config.go b/internal/config/config.go index 0f3776f..af911e9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -31,7 +31,7 @@ import ( const ( // Version app version - Version = "1.2.2" + Version = "1.2.3" // AWSCredentialsFormat format const AWSCredentialsFormat = "aws-credentials" @@ -46,6 +46,8 @@ const ( AWSIAMIdPFlag = "aws-iam-idp" // AWSIAMRoleFlag cli flag const AWSIAMRoleFlag = "aws-iam-role" + // AWSRegion cli flag const + AWSRegionFlag = "aws-region" // DebugFlag cli flag const DebugFlag = "debug" // DebugAPICallsFlag cli flag const @@ -83,6 +85,8 @@ const ( AWSIAMRoleEnvVar = "OKTA_AWSCLI_IAM_ROLE" // AWSSessionDurationEnvVar env var const AWSSessionDurationEnvVar = "OKTA_AWSCLI_SESSION_DURATION" + // AWSRegionEnvVar env var const + AWSRegionEnvVar = "OKTA_AWSCLI_AWS_REGION" // FormatEnvVar env var const FormatEnvVar = "OKTA_AWSCLI_FORMAT" // OktaOIDCClientIDEnvVar env var const @@ -131,6 +135,7 @@ type Config struct { awsIAMIdP string awsIAMRole string awsSessionDuration int64 + awsRegion string format string profile string qrCode bool @@ -162,6 +167,7 @@ type Attributes struct { AWSIAMIdP string AWSIAMRole string AWSSessionDuration int64 + AWSRegion string Format string Profile string QRCode bool @@ -195,6 +201,7 @@ func NewConfig(attrs Attributes) (*Config, error) { fedAppID: attrs.FedAppID, awsIAMIdP: attrs.AWSIAMIdP, awsIAMRole: attrs.AWSIAMRole, + awsRegion: attrs.AWSRegion, format: attrs.Format, profile: attrs.Profile, qrCode: attrs.QRCode, @@ -240,6 +247,7 @@ func readConfig() (Attributes, error) { AWSIAMIdP: viper.GetString(AWSIAMIdPFlag), AWSIAMRole: viper.GetString(AWSIAMRoleFlag), AWSSessionDuration: viper.GetInt64(SessionDurationFlag), + AWSRegion: viper.GetString(AWSRegionFlag), Debug: viper.GetBool(DebugFlag), DebugAPICalls: viper.GetBool(DebugAPICallsFlag), DebugConfig: viper.GetBool(DebugConfigFlag), @@ -421,6 +429,15 @@ func (c *Config) SetAWSIAMRole(role string) error { return nil } +func (c *Config) SetAWSRegion(region string) error { + c.awsRegion = region + return nil +} + +func (c *Config) AWSRegion() string { + return c.awsRegion +} + // AWSSessionDuration -- func (c *Config) AWSSessionDuration() int64 { return c.awsSessionDuration diff --git a/internal/output/aws_credentials_file.go b/internal/output/aws_credentials_file.go index f01d583..dd161a6 100644 --- a/internal/output/aws_credentials_file.go +++ b/internal/output/aws_credentials_file.go @@ -64,7 +64,7 @@ func ensureConfigExists(filename string, profile string) error { return nil } -func saveProfile(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string) error { +func saveProfile(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string, regionVar bool) error { config, err := updateConfig(filename, profile, awsCreds, legacyVars, expiryVars, expiry) if err != nil { return err @@ -90,6 +90,8 @@ func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars return } + awsCreds.Region = "us-east-1" + builder := dynamicstruct.ExtendStruct(aws.Credential{}) if expiryVars { @@ -102,6 +104,7 @@ func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars reflect.ValueOf(instance).Elem().FieldByName("AccessKeyID").SetString(awsCreds.AccessKeyID) reflect.ValueOf(instance).Elem().FieldByName("SecretAccessKey").SetString(awsCreds.SecretAccessKey) reflect.ValueOf(instance).Elem().FieldByName("SessionToken").SetString(awsCreds.SessionToken) + reflect.ValueOf(instance).Elem().FieldByName("Region").SetString(awsCreds.Region) if expiryVars { reflect.ValueOf(instance).Elem().FieldByName(ExpirationField).SetString(expiry) @@ -132,6 +135,9 @@ func updateINI(config *ini.File, profile string, legacyVars bool, expiryVars boo if expiryVars { ignore = append(ignore, "x_security_token_expires") } + if true { + ignore = append(ignore, "region") + } section := config.Section(profile) comments := []string{} for _, name := range section.KeyStrings() { @@ -171,6 +177,7 @@ type AWSCredentialsFile struct { LegacyAWSVariables bool ExpiryAWSVariables bool Expiry string + Region string } // NewAWSCredentialsFile Creates a new @@ -219,6 +226,12 @@ aws_session_token = %s credArgs = append(credArgs, e.Expiry) } + fmt.Println("hello") + if c.AWSRegion() != "" { + creds = fmt.Sprintf("%sregion = %%s\n", creds) + credArgs = append(credArgs, c.AWSRegion()) + } + creds = fmt.Sprintf(creds, credArgs...) _, err = f.WriteString(creds) @@ -241,7 +254,7 @@ func (e *AWSCredentialsFile) writeConfig(c *config.Config, ac *aws.Credential) e return err } - return saveProfile(filename, profile, ac, e.LegacyAWSVariables, e.ExpiryAWSVariables, e.Expiry) + return saveProfile(filename, profile, ac, e.LegacyAWSVariables, e.ExpiryAWSVariables, e.Expiry, e.Region) } func contains(ignore []string, name string) bool { diff --git a/internal/sessiontoken/sessiontoken.go b/internal/sessiontoken/sessiontoken.go index 9bb1c8e..c831408 100644 --- a/internal/sessiontoken/sessiontoken.go +++ b/internal/sessiontoken/sessiontoken.go @@ -135,8 +135,9 @@ type apiError struct { // idpAndRole IdP and role pairs type idpAndRole struct { - idp string - role string + idp string + role string + region string } var stderrIsOutAskOpt = func(options *survey.AskOptions) error { @@ -192,7 +193,7 @@ func (s *SessionToken) EstablishToken() error { } if s.config.FedAppID() != "" { // Alternate path when operator knows their AWS Fed app ID - err = s.establishTokenWithFedAppID(clientID, s.config.FedAppID(), at) + err = s.establishTokenWithFedAppID(clientID, s.config.FedAppID(), at, s.config.AWSRegion()) if at != nil && err != nil { // possible bad cached access token, retry at = nil @@ -238,7 +239,7 @@ AWS Federation App with --aws-acct-fed-app-id FED_APP_ID } } - return s.establishTokenWithFedAppID(clientID, fedAppID, at) + return s.establishTokenWithFedAppID(clientID, fedAppID, at, ) } // choiceFriendlyLabelIDP returns a friendly choice for pretty printing IDP @@ -307,7 +308,7 @@ func (s *SessionToken) selectFedApp(apps []*oktaApplication) (string, error) { return idps[selected].ID, nil } -func (s *SessionToken) establishTokenWithFedAppID(clientID, fedAppID string, at *accessToken) error { +func (s *SessionToken) establishTokenWithFedAppID(clientID, fedAppID string, at *accessToken, region string) error { at, err := s.fetchSSOWebToken(clientID, fedAppID, at) if err != nil { return err @@ -327,6 +328,7 @@ func (s *SessionToken) establishTokenWithFedAppID(clientID, fedAppID string, at if err != nil { return err } + iar.region = region ac, err := s.fetchAWSCredentialWithSAMLRole(iar, assertion) if err != nil { From 05a968f08dc26ac80904687edb3cc4b5cce402ee Mon Sep 17 00:00:00 2001 From: euchen-circle Date: Wed, 24 Jan 2024 22:03:22 +0000 Subject: [PATCH 2/6] Updating code --- internal/output/aws_credentials_file.go | 4 +--- internal/sessiontoken/sessiontoken.go | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/output/aws_credentials_file.go b/internal/output/aws_credentials_file.go index dd161a6..b1afda1 100644 --- a/internal/output/aws_credentials_file.go +++ b/internal/output/aws_credentials_file.go @@ -64,7 +64,7 @@ func ensureConfigExists(filename string, profile string) error { return nil } -func saveProfile(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string, regionVar bool) error { +func saveProfile(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string, regionVar string) error { config, err := updateConfig(filename, profile, awsCreds, legacyVars, expiryVars, expiry) if err != nil { return err @@ -90,8 +90,6 @@ func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars return } - awsCreds.Region = "us-east-1" - builder := dynamicstruct.ExtendStruct(aws.Credential{}) if expiryVars { diff --git a/internal/sessiontoken/sessiontoken.go b/internal/sessiontoken/sessiontoken.go index c831408..f03bc76 100644 --- a/internal/sessiontoken/sessiontoken.go +++ b/internal/sessiontoken/sessiontoken.go @@ -239,7 +239,7 @@ AWS Federation App with --aws-acct-fed-app-id FED_APP_ID } } - return s.establishTokenWithFedAppID(clientID, fedAppID, at, ) + return s.establishTokenWithFedAppID(clientID, fedAppID, at, s.config.AWSRegion()) } // choiceFriendlyLabelIDP returns a friendly choice for pretty printing IDP From 4b080db8383af4baf88f9111f94e43517a5b73fa Mon Sep 17 00:00:00 2001 From: euchen-circle Date: Wed, 24 Jan 2024 22:15:40 +0000 Subject: [PATCH 3/6] testing region --- internal/output/aws_credentials_file.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/output/aws_credentials_file.go b/internal/output/aws_credentials_file.go index b1afda1..08bc1a6 100644 --- a/internal/output/aws_credentials_file.go +++ b/internal/output/aws_credentials_file.go @@ -65,7 +65,7 @@ func ensureConfigExists(filename string, profile string) error { } func saveProfile(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string, regionVar string) error { - config, err := updateConfig(filename, profile, awsCreds, legacyVars, expiryVars, expiry) + config, err := updateConfig(filename, profile, awsCreds, legacyVars, expiryVars, expiry, regionVar) if err != nil { return err } @@ -79,7 +79,7 @@ func saveProfile(filename, profile string, awsCreds *aws.Credential, legacyVars, return nil } -func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string) (config *ini.File, err error) { +func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars, expiryVars bool, expiry string, region string) (config *ini.File, err error) { config, err = ini.Load(filename) if err != nil { return @@ -102,7 +102,9 @@ func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars reflect.ValueOf(instance).Elem().FieldByName("AccessKeyID").SetString(awsCreds.AccessKeyID) reflect.ValueOf(instance).Elem().FieldByName("SecretAccessKey").SetString(awsCreds.SecretAccessKey) reflect.ValueOf(instance).Elem().FieldByName("SessionToken").SetString(awsCreds.SessionToken) - reflect.ValueOf(instance).Elem().FieldByName("Region").SetString(awsCreds.Region) + if region != "" { + reflect.ValueOf(instance).Elem().FieldByName("Region").SetString(region) + } if expiryVars { reflect.ValueOf(instance).Elem().FieldByName(ExpirationField).SetString(expiry) @@ -224,7 +226,6 @@ aws_session_token = %s credArgs = append(credArgs, e.Expiry) } - fmt.Println("hello") if c.AWSRegion() != "" { creds = fmt.Sprintf("%sregion = %%s\n", creds) credArgs = append(credArgs, c.AWSRegion()) @@ -252,7 +253,7 @@ func (e *AWSCredentialsFile) writeConfig(c *config.Config, ac *aws.Credential) e return err } - return saveProfile(filename, profile, ac, e.LegacyAWSVariables, e.ExpiryAWSVariables, e.Expiry, e.Region) + return saveProfile(filename, profile, ac, e.LegacyAWSVariables, e.ExpiryAWSVariables, e.Expiry, c.AWSRegion()) } func contains(ignore []string, name string) bool { From 0f315a0271619a79fbdd21c74b9b145624197d99 Mon Sep 17 00:00:00 2001 From: euchen-circle Date: Wed, 24 Jan 2024 22:22:27 +0000 Subject: [PATCH 4/6] Fix force vars, and confirmed region var is working --- internal/output/aws_credentials_file.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/output/aws_credentials_file.go b/internal/output/aws_credentials_file.go index 08bc1a6..0d026b7 100644 --- a/internal/output/aws_credentials_file.go +++ b/internal/output/aws_credentials_file.go @@ -118,12 +118,12 @@ func updateConfig(filename, profile string, awsCreds *aws.Credential, legacyVars return } - return updateINI(config, profile, legacyVars, expiryVars) + return updateINI(config, profile, legacyVars, expiryVars, region) } // updateIni will comment out any keys that are not "aws_access_key_id", // "aws_secret_access_key", or "aws_session_token" -func updateINI(config *ini.File, profile string, legacyVars bool, expiryVars bool) (*ini.File, error) { +func updateINI(config *ini.File, profile string, legacyVars bool, expiryVars bool, region string) (*ini.File, error) { ignore := []string{ "aws_access_key_id", "aws_secret_access_key", @@ -135,7 +135,7 @@ func updateINI(config *ini.File, profile string, legacyVars bool, expiryVars boo if expiryVars { ignore = append(ignore, "x_security_token_expires") } - if true { + if region != "" { ignore = append(ignore, "region") } section := config.Section(profile) From 10e1554a005cec208362bdb414284af0fb317faf Mon Sep 17 00:00:00 2001 From: Mike Mondragon Date: Fri, 9 Feb 2024 16:28:39 -0800 Subject: [PATCH 5/6] changelog liner notes --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fdc15e..d13c5a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,13 @@ TBD +### ENHANCEMENTS + +* Explicitly set AWS Region with CLI flag `--aws-region` [#174](https://github.com/okta/okta-aws-cli/pull/174), thanks [@euchen-circle](https://github.com/euchen-circle), [@igaskin](https://github.com/igaskin)! + ### BUG FIXES -* Process credentials format was not emitting JSON correctly when `--write-aws-credentials` flag is present [#NNN](https://github.com/okta/okta-aws-cli/pull/NNN), thanks [@monde](https://github.com/monde)! +* Process credentials format was not emitting JSON correctly when `--write-aws-credentials` flag is present [#177](https://github.com/okta/okta-aws-cli/pull/177), thanks [@monde](https://github.com/monde)! * Open browser and open browser command behavior was fouled in v2 release [#172](https://github.com/okta/okta-aws-cli/pull/172), thanks [@monde](https://github.com/monde)! ## 2.0.1 (January 31, 2024) From 32f6a8cce3a9b2ff411f0b80309f402a39126ead Mon Sep 17 00:00:00 2001 From: Mike Mondragon Date: Fri, 9 Feb 2024 16:36:03 -0800 Subject: [PATCH 6/6] QC --- internal/config/config.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index b3ed3ce..7d035c9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -62,7 +62,7 @@ const ( AWSIAMIdPFlag = "aws-iam-idp" // AWSIAMRoleFlag cli flag const AWSIAMRoleFlag = "aws-iam-role" - // AWSRegion cli flag const + // AWSRegionFlag cli flag const AWSRegionFlag = "aws-region" // CustomScopeFlag cli flag const CustomScopeFlag = "custom-scope" @@ -557,15 +557,17 @@ func (c *Config) SetAWSIAMRole(role string) error { return nil } +// AWSRegion -- +func (c *Config) AWSRegion() string { + return c.awsRegion +} + +// SetAWSRegion -- func (c *Config) SetAWSRegion(region string) error { c.awsRegion = region return nil } -func (c *Config) AWSRegion() string { - return c.awsRegion -} - // AWSSessionDuration -- func (c *Config) AWSSessionDuration() int64 { return c.awsSessionDuration