From 4a560451a4dd6bd81c7489ac757413d983d0b9ad Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Thu, 22 Aug 2019 15:27:52 -0700 Subject: [PATCH 01/20] Adds STS Regional Flags --- aws/client/default_retryer.go | 6 +++--- aws/client/default_retryer_test.go | 2 +- aws/config.go | 20 ++++++++++++++++++++ aws/endpoints/endpoints.go | 11 ++++++++++- aws/endpoints/sts_legacy_regions.go | 20 ++++++++++++++++++++ aws/endpoints/v3model.go | 7 +++++++ aws/session/env_config.go | 17 ++++++++++++++--- aws/session/session.go | 7 +++++++ aws/session/shared_config.go | 10 +++++++++- private/model/api/example_test.go | 4 ++-- 10 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 aws/endpoints/sts_legacy_regions.go diff --git a/aws/client/default_retryer.go b/aws/client/default_retryer.go index 0fda42510f0..9f6af19dd45 100644 --- a/aws/client/default_retryer.go +++ b/aws/client/default_retryer.go @@ -16,11 +16,11 @@ import ( type DefaultRetryer struct { // Num max Retries is the number of max retries that will be performed. // By default, this is zero. - NumMaxRetries int + NumMaxRetries int // MinRetryDelay is the minimum retry delay after which retry will be performed. // If not set, the value is 0ns. - MinRetryDelay time.Duration + MinRetryDelay time.Duration // MinThrottleRetryDelay is the minimum retry delay when throttled. // If not set, the value is 0ns. @@ -28,7 +28,7 @@ type DefaultRetryer struct { // MaxRetryDelay is the maximum retry delay before which retry must be performed. // If not set, the value is 0ns. - MaxRetryDelay time.Duration + MaxRetryDelay time.Duration // MaxThrottleDelay is the maximum retry delay when throttled. // If not set, the value is 0ns. diff --git a/aws/client/default_retryer_test.go b/aws/client/default_retryer_test.go index 08d9ee7cdd5..b8794f3ccc8 100644 --- a/aws/client/default_retryer_test.go +++ b/aws/client/default_retryer_test.go @@ -166,7 +166,7 @@ func TestGetRetryDelay(t *testing.T) { } func TestRetryDelay(t *testing.T) { - d := DefaultRetryer{NumMaxRetries:100} + d := DefaultRetryer{NumMaxRetries: 100} r := request.Request{} for i := 0; i < 100; i++ { rTemp := r diff --git a/aws/config.go b/aws/config.go index fd1e240f6eb..99919fb1362 100644 --- a/aws/config.go +++ b/aws/config.go @@ -2,6 +2,7 @@ package aws import ( "net/http" + "strings" "time" "github.com/aws/aws-sdk-go/aws/credentials" @@ -246,6 +247,10 @@ type Config struct { // Disabling this feature is useful when you want to use local endpoints // for testing that do not support the modeled host prefix pattern. DisableEndpointHostPrefix *bool + + // STSRegionalEndpoint will enable regional or legacy endpoint resolving + // if regional true, else false + STSRegionalEndpoint *bool } // NewConfig returns a new Config pointer that can be chained with builder @@ -420,6 +425,17 @@ func (c *Config) MergeIn(cfgs ...*Config) { } } +// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag +// when resolving the endpoint for a service +func (c *Config) WithSTSRegionalEndpoint(s string) *Config { + var t bool + if strings.ToLower(s) == "regional" { + t = true + } + c.STSRegionalEndpoint = &t + return c +} + func mergeInConfig(dst *Config, other *Config) { if other == nil { return @@ -520,6 +536,10 @@ func mergeInConfig(dst *Config, other *Config) { if other.DisableEndpointHostPrefix != nil { dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix } + + if other.STSRegionalEndpoint != nil { + dst.STSRegionalEndpoint = other.STSRegionalEndpoint + } } // Copy will return a shallow copy of the Config object. If any additional diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index 9c936be6cf9..970dccda96c 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -46,6 +46,11 @@ type Options struct { // // This option is ignored if StrictMatching is enabled. ResolveUnknownService bool + + // STS Regional Endpoint flag helps with resolving the STS RIP endpoint + // It has a default value of `true` for regional endpoints, + // and can be switched to `false` for legacy endpoints. + STSRegionalEndpoint bool } // Set combines all of the option functions together. @@ -79,6 +84,10 @@ func ResolveUnknownServiceOption(o *Options) { o.ResolveUnknownService = true } +func STSRegionalEndpointOption(o *Options) { + o.STSRegionalEndpoint = true +} + // A Resolver provides the interface for functionality to resolve endpoints. // The build in Partition and DefaultResolver return value satisfy this interface. type Resolver interface { @@ -194,7 +203,7 @@ func (p Partition) ID() string { return p.id } // require the provided service and region to be known by the partition. // If the endpoint cannot be strictly resolved an error will be returned. This // mode is useful to ensure the endpoint resolved is valid. Without -// StrictMatching enabled the endpoint returned my look valid but may not work. +// StrictMatching enabled the endpoint returned may look valid but may not work. // StrictMatching requires the SDK to be updated if you want to take advantage // of new regions and services expansions. // diff --git a/aws/endpoints/sts_legacy_regions.go b/aws/endpoints/sts_legacy_regions.go new file mode 100644 index 00000000000..ce905e438bc --- /dev/null +++ b/aws/endpoints/sts_legacy_regions.go @@ -0,0 +1,20 @@ +package endpoints + +var stsLegacyGlocalRegions = map[string]struct{}{ + "ap-northeast-1": {}, + "ap-south-1": {}, + "ap-southeast-1": {}, + "ap-southeast-2": {}, + "aws-global": {}, + "ca-central-1": {}, + "eu-central-1": {}, + "eu-north-1": {}, + "eu-west-1": {}, + "eu-west-2": {}, + "eu-west-3": {}, + "sa-east-1": {}, + "us-east-1": {}, + "us-east-2": {}, + "us-west-1": {}, + "us-west-2": {}, +} diff --git a/aws/endpoints/v3model.go b/aws/endpoints/v3model.go index 523ad79ac0a..4362423fbca 100644 --- a/aws/endpoints/v3model.go +++ b/aws/endpoints/v3model.go @@ -79,6 +79,12 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) ( var opt Options opt.Set(opts...) + if service == "sts" && !opt.STSRegionalEndpoint { + if _, ok := stsLegacyGlocalRegions[region]; ok { + region = "aws-global" + } + } + s, hasService := p.Services[service] if !(hasService || opt.ResolveUnknownService) { // Only return error if the resolver will not fallback to creating @@ -92,6 +98,7 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) ( } defs := []endpoint{p.Defaults, s.Defaults} + return e.resolve(service, region, p.DNSSuffix, defs, opt), nil } diff --git a/aws/session/env_config.go b/aws/session/env_config.go index 60a6f9ce2a4..dcf501e4b75 100644 --- a/aws/session/env_config.go +++ b/aws/session/env_config.go @@ -1,12 +1,11 @@ package session import ( - "os" - "strconv" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/defaults" + "os" + "strconv" ) // EnvProviderName provides a name of the provider when config is loaded from environment. @@ -125,6 +124,12 @@ type envConfig struct { // // AWS_ROLE_SESSION_NAME=session_name RoleSessionName string + + // Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service + // + // AWS_STS_REGIONAL_ENDPOINTS =regional_endpoint + // This can take value as `regional` or `legacy` + RegionalEndpoint string } var ( @@ -179,6 +184,9 @@ var ( roleSessionNameEnvKey = []string{ "AWS_ROLE_SESSION_NAME", } + regionalEndpointKey = []string{ + "AWS_STS_REGIONAL_ENDPOINTS", + } ) // loadEnvConfig retrieves the SDK's environment configuration. @@ -264,6 +272,9 @@ func envConfigLoad(enableSharedConfig bool) envConfig { cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") + // Regional Endpoint variable + setFromEnvVal(&cfg.RegionalEndpoint, regionalEndpointKey) + return cfg } diff --git a/aws/session/session.go b/aws/session/session.go index 7b0a942e223..592d77b4c06 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -550,6 +550,13 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, } } + // Regional Endpoint flag for STS endpoint resolving + if envCfg.RegionalEndpoint != "" { + cfg.WithSTSRegionalEndpoint(envCfg.RegionalEndpoint) + } else if sharedCfg.RegionalEndpoint != "" { + cfg.WithSTSRegionalEndpoint(sharedCfg.RegionalEndpoint) + } + // Configure credentials if not already set by the user when creating the // Session. if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { diff --git a/aws/session/shared_config.go b/aws/session/shared_config.go index d91ac93a544..0e6a6fe0649 100644 --- a/aws/session/shared_config.go +++ b/aws/session/shared_config.go @@ -40,6 +40,9 @@ const ( // Web Identity Token File webIdentityTokenFileKey = `web_identity_token_file` // optional + // Additonal config fields for regional or legacy endpoints + regionalEndpointSharedKey = `sts_regional_endpoints` + // DefaultSharedConfigProfile is the default profile to be used when // loading configuration from the config files if another profile name // is not provided. @@ -82,12 +85,16 @@ type sharedConfig struct { // // endpoint_discovery_enabled = true EnableEndpointDiscovery *bool - // CSM Options CSMEnabled *bool CSMHost string CSMPort string CSMClientID string + // Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service + // + // sts_regional_endpoints = regional_endpoint + // This can take value as `regional` or `legacy` + RegionalEndpoint string } type sharedConfigFile struct { @@ -246,6 +253,7 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e updateString(&cfg.CredentialSource, section, credentialSourceKey) updateString(&cfg.Region, section, regionKey) + updateString(&cfg.RegionalEndpoint, section, regionalEndpointSharedKey) } updateString(&cfg.CredentialProcess, section, credentialProcessKey) diff --git a/private/model/api/example_test.go b/private/model/api/example_test.go index 2c7149c3752..4083ebf8abd 100644 --- a/private/model/api/example_test.go +++ b/private/model/api/example_test.go @@ -296,8 +296,8 @@ func ExampleFooService_Foo_shared00() { } ` if expected != a.ExamplesGoCode() { - t.Errorf("Expected:\n%s\nReceived:\n%s\n", expected, a.ExamplesGoCode()) - } + t.Errorf("Expected:\n%s\nReceived:\n%s\n", expected, a.ExamplesGoCode()) + } } func TestBuildShape(t *testing.T) { From bfd7ae1e628c3216ca7d8a669aa61d44937b6c09 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Thu, 22 Aug 2019 15:55:36 -0700 Subject: [PATCH 02/20] Added more tests --- aws/endpoints/v3model_test.go | 379 ++++++++++++++++++++++++++++++++++ 1 file changed, 379 insertions(+) diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 0b8b00673d7..73db092797e 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -4,7 +4,10 @@ import ( "encoding/json" "reflect" "regexp" + "strings" "testing" + + "github.com/aws/aws-sdk-go/internal/sdktesting" ) func TestUnmarshalRegionRegex(t *testing.T) { @@ -539,3 +542,379 @@ func TestResolveEndpoint_AwsGlobal(t *testing.T) { t.Errorf("expect the signing name to be derived") } } +func Test_Regional_Flag(t *testing.T) { + const v3Doc = ` +{ + "version": 3, + "partitions": [ + { + "defaults": { + "hostname": "{service}.{region}.{dnsSuffix}", + "protocols": [ + "https" + ], + "signatureVersions": [ + "v4" + ] + }, + "dnsSuffix": "amazonaws.com", + "partition": "aws", + "partitionName": "AWS Standard", + "regionRegex": "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$", + "regions": { + "ap-northeast-1": { + "description": "Asia Pacific (Tokyo)" + } + }, + "services": { + "acm": { + "endpoints": { + "ap-northeast-1": {} + } + }, + "s3": { + "endpoints": { + "ap-northeast-1": {} + } + }, + "sts" : { + "defaults" : { }, + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "sts.amazonaws.com" + }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "sts-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "sts-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "sts-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "sts-fips.us-west-2.amazonaws.com" + } + }, + "partitionEndpoint" : "aws-global" + } + } + } + ] +}` + + resolver, err := DecodeModel(strings.NewReader(v3Doc)) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + cases := map[string]struct { + service, region string + regional bool + ExpectURL, ExpectSigningMethod, ExpectSigningRegion string + ExpectSigningNameDerived bool + }{ + "acm/ap-northeast-1/regional": { + service: "acm", region: "ap-northeast-1", regional: true, ExpectURL: "https://acm.ap-northeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", + }, + "acm/ap-northeast-1/legacy": { + service: "acm", region: "ap-northeast-1", regional: false, ExpectURL: "https://acm.ap-northeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", + }, + // STS Endpoints resolver tests : + "sts/us-west-2/regional": { + service: "sts", region: "us-west-2", regional: true, ExpectURL: "https://sts.us-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-2", + }, + "sts/us-west-2/legacy": { + service: "sts", region: "us-west-2", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/ap-east-1/regional": { + service: "sts", region: "ap-east-1", regional: true, ExpectURL: "https://sts.ap-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-east-1", + }, + "sts/ap-east-1/legacy": { + service: "sts", region: "ap-east-1", regional: false, ExpectURL: "https://sts.ap-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-east-1", + }, + "sts/us-west-2-fips/regional": { + service: "sts", region: "us-west-2-fips", regional: true, ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-2", + }, + "sts/us-west-2-fips/legacy": { + service: "sts", region: "us-west-2-fips", regional: false, ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-2", + }, + "sts/aws-global/regional": { + service: "sts", region: "aws-global", regional: true, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/aws-global/legacy": { + service: "sts", region: "aws-global", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/ap-south-1/regional": { + service: "sts", region: "ap-south-1", regional: true, ExpectURL: "https://sts.ap-south-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-south-1", + }, + "sts/ap-south-1/legacy": { + service: "sts", region: "ap-south-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/ap-northeast-1/regional": { + service: "sts", region: "ap-northeast-1", regional: true, ExpectURL: "https://sts.ap-northeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", + }, + "sts/ap-northeast-1/legacy": { + service: "sts", region: "ap-northeast-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/ap-southeast-1/regional": { + service: "sts", region: "ap-southeast-1", regional: true, ExpectURL: "https://sts.ap-southeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-southeast-1", + }, + "sts/ap-southeast-1/legacy": { + service: "sts", region: "ap-southeast-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/ca-central-1/regional": { + service: "sts", region: "ca-central-1", regional: true, ExpectURL: "https://sts.ca-central-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ca-central-1", + }, + "sts/ca-central-1/legacy": { + service: "sts", region: "ca-central-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/eu-central-1/regional": { + service: "sts", region: "eu-central-1", regional: true, ExpectURL: "https://sts.eu-central-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-central-1", + }, + "sts/eu-central-1/legacy": { + service: "sts", region: "eu-central-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/eu-north-1/regional": { + service: "sts", region: "eu-north-1", regional: true, ExpectURL: "https://sts.eu-north-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-north-1", + }, + "sts/eu-north-1/legacy": { + service: "sts", region: "eu-north-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/eu-west-1/regional": { + service: "sts", region: "eu-west-1", regional: true, ExpectURL: "https://sts.eu-west-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-west-1", + }, + "sts/eu-west-1/legacy": { + service: "sts", region: "eu-west-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/eu-west-2/regional": { + service: "sts", region: "eu-west-2", regional: true, ExpectURL: "https://sts.eu-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-west-2", + }, + "sts/eu-west-2/legacy": { + service: "sts", region: "eu-west-2", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/eu-west-3/regional": { + service: "sts", region: "eu-west-3", regional: true, ExpectURL: "https://sts.eu-west-3.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-west-3", + }, + "sts/eu-west-3/legacy": { + service: "sts", region: "eu-west-3", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/sa-east-1/regional": { + service: "sts", region: "sa-east-1", regional: true, ExpectURL: "https://sts.sa-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "sa-east-1", + }, + "sts/sa-east-1/legacy": { + service: "sts", region: "sa-east-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/us-east-1/regional": { + service: "sts", region: "us-east-1", regional: true, ExpectURL: "https://sts.us-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/us-east-1/legacy": { + service: "sts", region: "us-east-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/us-east-2/regional": { + service: "sts", region: "us-east-2", regional: true, ExpectURL: "https://sts.us-east-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-2", + }, + "sts/us-east-2/legacy": { + service: "sts", region: "us-east-2", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + "sts/us-west-1/regional": { + service: "sts", region: "us-west-1", regional: true, ExpectURL: "https://sts.us-west-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-1", + }, + "sts/us-west-1/legacy": { + service: "sts", region: "us-west-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + }, + } + + for name, c := range cases { + sdktesting.StashEnv() + var optionSlice []func(o *Options) + t.Run(name, func(t *testing.T) { + if c.regional { + optionSlice = append(optionSlice, STSRegionalEndpointOption) + } + actual, err := resolver.EndpointFor(c.service, c.region, optionSlice...) + if err != nil { + t.Fatalf("failed to resolve endpoint, %v", err) + } + + if e, a := c.ExpectURL, actual.URL; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := c.ExpectSigningMethod, actual.SigningMethod; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := c.ExpectSigningNameDerived, actual.SigningNameDerived; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := c.ExpectSigningRegion, actual.SigningRegion; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + }) + } +} + +func Test_Regional_Flag_CN(t *testing.T) { + const v3Doc = ` +{ + "version": 3, + "partitions": [ + { + "defaults": { + "hostname": "{service}.{region}.{dnsSuffix}", + "protocols": [ + "https" + ], + "signatureVersions": [ + "v4" + ] + }, + "dnsSuffix": "amazonaws.com.cn", + "partition": "aws", + "partitionName": "AWS Standard", + "regionRegex": "^(cn)\\-\\w+\\-\\d+$", + "regions": { + "cn-north-1": { + "description": "China North -1" + } + }, + "services": { + "sts" : { + "defaults" : { }, + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "sts.amazonaws.com" + }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "sts-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "sts-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "sts-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "sts-fips.us-west-2.amazonaws.com" + } + }, + "partitionEndpoint" : "aws-global" + } + } + } + ] +}` + + resolver, err := DecodeModel(strings.NewReader(v3Doc)) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + cases := map[string]struct { + service, region string + regional bool + ExpectURL, ExpectSigningMethod, ExpectSigningRegion string + ExpectSigningNameDerived bool + }{ + "sts/cn-north-1/regional": { + service: "sts", region: "cn-north-1", regional: true, ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "cn-north-1", + }, + "sts/cn-north-1/legacy": { + service: "sts", region: "cn-north-1", regional: false, ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "cn-north-1", + }, + } + + for name, c := range cases { + sdktesting.StashEnv() + var optionSlice []func(o *Options) + t.Run(name, func(t *testing.T) { + if c.regional { + optionSlice = append(optionSlice, STSRegionalEndpointOption) + } + actual, err := resolver.EndpointFor(c.service, c.region, optionSlice...) + if err != nil { + t.Fatalf("failed to resolve endpoint, %v", err) + } + + if e, a := c.ExpectURL, actual.URL; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := c.ExpectSigningMethod, actual.SigningMethod; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := c.ExpectSigningNameDerived, actual.SigningNameDerived; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := c.ExpectSigningRegion, actual.SigningRegion; e != a { + t.Errorf("expect %v, got %v", e, a) + } + }) + } +} From fad5c81930bfbdb66464ffb1ed25297c81de837d Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Thu, 22 Aug 2019 16:38:22 -0700 Subject: [PATCH 03/20] Fixed linting issue with exported function STSRegionalEndpointOption --- aws/endpoints/endpoints.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index 970dccda96c..9909e02d4c9 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -84,6 +84,8 @@ func ResolveUnknownServiceOption(o *Options) { o.ResolveUnknownService = true } +// STSRegionalEndpointOption sets the STSRegionalEndpoint option. Can be used +// as a functional option when resolving endpoints. func STSRegionalEndpointOption(o *Options) { o.STSRegionalEndpoint = true } From 94e95cd96f7cc0ef87f774a6d3127b19119073d1 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Thu, 22 Aug 2019 16:47:44 -0700 Subject: [PATCH 04/20] Fixed bug to set STSRegionalEndpoint flag from client config --- aws/session/session.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aws/session/session.go b/aws/session/session.go index 592d77b4c06..7991cffa338 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -623,6 +623,9 @@ func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) ( func(opt *endpoints.Options) { opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL) opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack) + // Support for STSRegionalEndpoint where the STSRegionalEndpoint is + // provided in envconfig or sharedconfig with envconfig getting precedence. + opt.STSRegionalEndpoint = aws.BoolValue(s.Config.STSRegionalEndpoint) // Support the condition where the service is modeled but its // endpoint metadata is not available. From 37445fb72368cbdbf21963b6d602dd6b6da44f8f Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Thu, 22 Aug 2019 16:53:47 -0700 Subject: [PATCH 05/20] Added build tag for v3model_test.go to be able to use t.run for testing --- aws/endpoints/v3model_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 73db092797e..bd6d3945695 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -1,3 +1,5 @@ +// +build go1.7 + package endpoints import ( @@ -639,7 +641,6 @@ func Test_Regional_Flag(t *testing.T) { if err != nil { t.Fatalf("expected no error, got %v", err) } - cases := map[string]struct { service, region string regional bool @@ -758,7 +759,6 @@ func Test_Regional_Flag(t *testing.T) { } for name, c := range cases { - sdktesting.StashEnv() var optionSlice []func(o *Options) t.Run(name, func(t *testing.T) { if c.regional { @@ -892,7 +892,6 @@ func Test_Regional_Flag_CN(t *testing.T) { } for name, c := range cases { - sdktesting.StashEnv() var optionSlice []func(o *Options) t.Run(name, func(t *testing.T) { if c.regional { From a79ad5af29818c9b86cc96bfbee30e0a9f613fa8 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Fri, 23 Aug 2019 12:15:48 -0700 Subject: [PATCH 06/20] Modified to use enums for STS Regional Endpoints flag --- aws/config.go | 15 +- aws/endpoints/endpoints.go | 26 +- aws/endpoints/v3model.go | 2 +- aws/endpoints/v3model_shared_test.go | 69 ++++ aws/endpoints/v3model_test.go | 467 ++++++++++++++++----------- aws/session/env_config.go | 20 +- aws/session/session.go | 30 +- aws/session/shared_config.go | 20 +- 8 files changed, 425 insertions(+), 224 deletions(-) create mode 100644 aws/endpoints/v3model_shared_test.go diff --git a/aws/config.go b/aws/config.go index 99919fb1362..3b8853b1287 100644 --- a/aws/config.go +++ b/aws/config.go @@ -2,7 +2,6 @@ package aws import ( "net/http" - "strings" "time" "github.com/aws/aws-sdk-go/aws/credentials" @@ -249,10 +248,10 @@ type Config struct { DisableEndpointHostPrefix *bool // STSRegionalEndpoint will enable regional or legacy endpoint resolving - // if regional true, else false - STSRegionalEndpoint *bool + STSRegionalEndpoint endpoints.STSRegionalEndpoint } + // NewConfig returns a new Config pointer that can be chained with builder // methods to set multiple configuration values inline without using pointers. // @@ -427,12 +426,8 @@ func (c *Config) MergeIn(cfgs ...*Config) { // WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag // when resolving the endpoint for a service -func (c *Config) WithSTSRegionalEndpoint(s string) *Config { - var t bool - if strings.ToLower(s) == "regional" { - t = true - } - c.STSRegionalEndpoint = &t +func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config { + c.STSRegionalEndpoint = sre return c } @@ -537,7 +532,7 @@ func mergeInConfig(dst *Config, other *Config) { dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix } - if other.STSRegionalEndpoint != nil { + if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint { dst.STSRegionalEndpoint = other.STSRegionalEndpoint } } diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index 9909e02d4c9..cfbb1bda440 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -3,6 +3,7 @@ package endpoints import ( "fmt" "regexp" + "strings" "github.com/aws/aws-sdk-go/aws/awserr" ) @@ -50,7 +51,26 @@ type Options struct { // STS Regional Endpoint flag helps with resolving the STS RIP endpoint // It has a default value of `true` for regional endpoints, // and can be switched to `false` for legacy endpoints. - STSRegionalEndpoint bool + STSRegionalEndpoint STSRegionalEndpoint +} + +type STSRegionalEndpoint int + +const ( + UnsetSTSEndpoint STSRegionalEndpoint = iota + LegacySTSEndpoint + RegionalSTSEndpoint +) + +func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error){ + switch { + case strings.EqualFold(s, "legacy"): + return LegacySTSEndpoint, nil + case strings.EqualFold(s, "regional"): + return RegionalSTSEndpoint, nil + default: + return UnsetSTSEndpoint , fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s) + } } // Set combines all of the option functions together. @@ -87,9 +107,11 @@ func ResolveUnknownServiceOption(o *Options) { // STSRegionalEndpointOption sets the STSRegionalEndpoint option. Can be used // as a functional option when resolving endpoints. func STSRegionalEndpointOption(o *Options) { - o.STSRegionalEndpoint = true + o.STSRegionalEndpoint = RegionalSTSEndpoint } + + // A Resolver provides the interface for functionality to resolve endpoints. // The build in Partition and DefaultResolver return value satisfy this interface. type Resolver interface { diff --git a/aws/endpoints/v3model.go b/aws/endpoints/v3model.go index 4362423fbca..9531f350489 100644 --- a/aws/endpoints/v3model.go +++ b/aws/endpoints/v3model.go @@ -79,7 +79,7 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) ( var opt Options opt.Set(opts...) - if service == "sts" && !opt.STSRegionalEndpoint { + if service == "sts" && opt.STSRegionalEndpoint != RegionalSTSEndpoint { if _, ok := stsLegacyGlocalRegions[region]; ok { region = "aws-global" } diff --git a/aws/endpoints/v3model_shared_test.go b/aws/endpoints/v3model_shared_test.go new file mode 100644 index 00000000000..b0b00b14ea3 --- /dev/null +++ b/aws/endpoints/v3model_shared_test.go @@ -0,0 +1,69 @@ +package endpoints + +import "regexp" + +var testPartitions = partitions{ + partition{ + ID: "part-id", + Name: "partitionName", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "us-east-1": region{ + Description: "region description", + }, + "us-west-2": region{}, + }, + Services: services{ + "s3": service{}, + "service1": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "service1", + }, + }, + Endpoints: endpoints{ + "us-east-1": {}, + "us-west-2": { + HasDualStack: boxedTrue, + DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}", + }, + }, + }, + "service2": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "service2", + }, + }, + }, + "httpService": service{ + Defaults: endpoint{ + Protocols: []string{"http"}, + }, + }, + "globalService": service{ + IsRegionalized: boxedFalse, + PartitionEndpoint: "aws-global", + Endpoints: endpoints{ + "aws-global": endpoint{ + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Hostname: "globalService.amazonaws.com", + }, + }, + }, + }, + }, +} diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index bd6d3945695..34d9b3d3779 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -258,72 +258,6 @@ func TestEndpointMergeIn(t *testing.T) { } } -var testPartitions = partitions{ - partition{ - ID: "part-id", - Name: "partitionName", - DNSSuffix: "amazonaws.com", - RegionRegex: regionRegex{ - Regexp: func() *regexp.Regexp { - reg, _ := regexp.Compile("^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$") - return reg - }(), - }, - Defaults: endpoint{ - Hostname: "{service}.{region}.{dnsSuffix}", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - Regions: regions{ - "us-east-1": region{ - Description: "region description", - }, - "us-west-2": region{}, - }, - Services: services{ - "s3": service{}, - "service1": service{ - Defaults: endpoint{ - CredentialScope: credentialScope{ - Service: "service1", - }, - }, - Endpoints: endpoints{ - "us-east-1": {}, - "us-west-2": { - HasDualStack: boxedTrue, - DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}", - }, - }, - }, - "service2": service{ - Defaults: endpoint{ - CredentialScope: credentialScope{ - Service: "service2", - }, - }, - }, - "httpService": service{ - Defaults: endpoint{ - Protocols: []string{"http"}, - }, - }, - "globalService": service{ - IsRegionalized: boxedFalse, - PartitionEndpoint: "aws-global", - Endpoints: endpoints{ - "aws-global": endpoint{ - CredentialScope: credentialScope{ - Region: "us-east-1", - }, - Hostname: "globalService.amazonaws.com", - }, - }, - }, - }, - }, -} - func TestResolveEndpoint(t *testing.T) { resolved, err := testPartitions.EndpointFor("service2", "us-west-2") @@ -648,122 +582,341 @@ func Test_Regional_Flag(t *testing.T) { ExpectSigningNameDerived bool }{ "acm/ap-northeast-1/regional": { - service: "acm", region: "ap-northeast-1", regional: true, ExpectURL: "https://acm.ap-northeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", + service: "acm", + region: "ap-northeast-1", + regional: true, + ExpectURL: "https://acm.ap-northeast-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-northeast-1", }, "acm/ap-northeast-1/legacy": { - service: "acm", region: "ap-northeast-1", regional: false, ExpectURL: "https://acm.ap-northeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", + service: "acm", + region: "ap-northeast-1", + regional: false, + ExpectURL: "https://acm.ap-northeast-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-northeast-1", }, // STS Endpoints resolver tests : "sts/us-west-2/regional": { - service: "sts", region: "us-west-2", regional: true, ExpectURL: "https://sts.us-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-2", + service: "sts", + region: "us-west-2", + regional: true, + ExpectURL: "https://sts.us-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-2", }, "sts/us-west-2/legacy": { - service: "sts", region: "us-west-2", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "us-west-2", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/ap-east-1/regional": { - service: "sts", region: "ap-east-1", regional: true, ExpectURL: "https://sts.ap-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-east-1", + service: "sts", + region: "ap-east-1", + regional: true, + ExpectURL: "https://sts.ap-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-east-1", }, "sts/ap-east-1/legacy": { - service: "sts", region: "ap-east-1", regional: false, ExpectURL: "https://sts.ap-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-east-1", + service: "sts", + region: "ap-east-1", + regional: false, + ExpectURL: "https://sts.ap-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-east-1", }, "sts/us-west-2-fips/regional": { - service: "sts", region: "us-west-2-fips", regional: true, ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-2", + service: "sts", + region: "us-west-2-fips", + regional: true, + ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-2", }, "sts/us-west-2-fips/legacy": { - service: "sts", region: "us-west-2-fips", regional: false, ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-2", + service: "sts", + region: "us-west-2-fips", + regional: false, + ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-2", }, "sts/aws-global/regional": { - service: "sts", region: "aws-global", regional: true, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "aws-global", + regional: true, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/aws-global/legacy": { - service: "sts", region: "aws-global", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "aws-global", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/ap-south-1/regional": { - service: "sts", region: "ap-south-1", regional: true, ExpectURL: "https://sts.ap-south-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-south-1", + service: "sts", + region: "ap-south-1", + regional: true, + ExpectURL: "https://sts.ap-south-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-south-1", }, "sts/ap-south-1/legacy": { - service: "sts", region: "ap-south-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "ap-south-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/ap-northeast-1/regional": { - service: "sts", region: "ap-northeast-1", regional: true, ExpectURL: "https://sts.ap-northeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", + service: "sts", + region: "ap-northeast-1", + regional: true, + ExpectURL: "https://sts.ap-northeast-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-northeast-1", }, "sts/ap-northeast-1/legacy": { - service: "sts", region: "ap-northeast-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "ap-northeast-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/ap-southeast-1/regional": { - service: "sts", region: "ap-southeast-1", regional: true, ExpectURL: "https://sts.ap-southeast-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-southeast-1", + service: "sts", + region: "ap-southeast-1", + regional: true, + ExpectURL: "https://sts.ap-southeast-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-southeast-1", }, "sts/ap-southeast-1/legacy": { - service: "sts", region: "ap-southeast-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "ap-southeast-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/ca-central-1/regional": { - service: "sts", region: "ca-central-1", regional: true, ExpectURL: "https://sts.ca-central-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "ca-central-1", + service: "sts", + region: "ca-central-1", + regional: true, + ExpectURL: "https://sts.ca-central-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ca-central-1", }, "sts/ca-central-1/legacy": { - service: "sts", region: "ca-central-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "ca-central-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/eu-central-1/regional": { - service: "sts", region: "eu-central-1", regional: true, ExpectURL: "https://sts.eu-central-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-central-1", + service: "sts", + region: "eu-central-1", + regional: true, + ExpectURL: "https://sts.eu-central-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-central-1", }, "sts/eu-central-1/legacy": { - service: "sts", region: "eu-central-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "eu-central-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/eu-north-1/regional": { - service: "sts", region: "eu-north-1", regional: true, ExpectURL: "https://sts.eu-north-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-north-1", + service: "sts", + region: "eu-north-1", + regional: true, + ExpectURL: "https://sts.eu-north-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-north-1", }, "sts/eu-north-1/legacy": { - service: "sts", region: "eu-north-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "eu-north-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/eu-west-1/regional": { - service: "sts", region: "eu-west-1", regional: true, ExpectURL: "https://sts.eu-west-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-west-1", + service: "sts", + region: "eu-west-1", + regional: true, + ExpectURL: "https://sts.eu-west-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-west-1", }, "sts/eu-west-1/legacy": { - service: "sts", region: "eu-west-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "eu-west-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/eu-west-2/regional": { - service: "sts", region: "eu-west-2", regional: true, ExpectURL: "https://sts.eu-west-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-west-2", + service: "sts", + region: "eu-west-2", + regional: true, + ExpectURL: "https://sts.eu-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-west-2", }, "sts/eu-west-2/legacy": { - service: "sts", region: "eu-west-2", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "eu-west-2", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/eu-west-3/regional": { - service: "sts", region: "eu-west-3", regional: true, ExpectURL: "https://sts.eu-west-3.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "eu-west-3", + service: "sts", + region: "eu-west-3", + regional: true, + ExpectURL: "https://sts.eu-west-3.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-west-3", }, "sts/eu-west-3/legacy": { - service: "sts", region: "eu-west-3", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "eu-west-3", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/sa-east-1/regional": { - service: "sts", region: "sa-east-1", regional: true, ExpectURL: "https://sts.sa-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "sa-east-1", + service: "sts", + region: "sa-east-1", + regional: true, + ExpectURL: "https://sts.sa-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "sa-east-1", }, "sts/sa-east-1/legacy": { - service: "sts", region: "sa-east-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "sa-east-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/us-east-1/regional": { - service: "sts", region: "us-east-1", regional: true, ExpectURL: "https://sts.us-east-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "us-east-1", + regional: true, + ExpectURL: "https://sts.us-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/us-east-1/legacy": { - service: "sts", region: "us-east-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "us-east-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/us-east-2/regional": { - service: "sts", region: "us-east-2", regional: true, ExpectURL: "https://sts.us-east-2.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-2", + service: "sts", + region: "us-east-2", + regional: true, + ExpectURL: "https://sts.us-east-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-2", }, "sts/us-east-2/legacy": { - service: "sts", region: "us-east-2", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "us-east-2", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, "sts/us-west-1/regional": { - service: "sts", region: "us-west-1", regional: true, ExpectURL: "https://sts.us-west-1.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-west-1", + service: "sts", + region: "us-west-1", + regional: true, + ExpectURL: "https://sts.us-west-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-1", }, "sts/us-west-1/legacy": { - service: "sts", region: "us-west-1", regional: false, ExpectURL: "https://sts.amazonaws.com", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "us-east-1", + service: "sts", + region: "us-west-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", }, } for name, c := range cases { - var optionSlice []func(o *Options) t.Run(name, func(t *testing.T) { - if c.regional { - optionSlice = append(optionSlice, STSRegionalEndpointOption) - } + var optionSlice []func(o *Options) + optionSlice = append(optionSlice, func(o *Options) { + if c.regional { + o.STSRegionalEndpoint = RegionalSTSEndpoint + } + }) + actual, err := resolver.EndpointFor(c.service, c.region, optionSlice...) if err != nil { t.Fatalf("failed to resolve endpoint, %v", err) @@ -790,92 +943,8 @@ func Test_Regional_Flag(t *testing.T) { } func Test_Regional_Flag_CN(t *testing.T) { - const v3Doc = ` -{ - "version": 3, - "partitions": [ - { - "defaults": { - "hostname": "{service}.{region}.{dnsSuffix}", - "protocols": [ - "https" - ], - "signatureVersions": [ - "v4" - ] - }, - "dnsSuffix": "amazonaws.com.cn", - "partition": "aws", - "partitionName": "AWS Standard", - "regionRegex": "^(cn)\\-\\w+\\-\\d+$", - "regions": { - "cn-north-1": { - "description": "China North -1" - } - }, - "services": { - "sts" : { - "defaults" : { }, - "endpoints" : { - "ap-east-1" : { }, - "ap-northeast-1" : { }, - "ap-northeast-2" : { }, - "ap-south-1" : { }, - "ap-southeast-1" : { }, - "ap-southeast-2" : { }, - "aws-global" : { - "credentialScope" : { - "region" : "us-east-1" - }, - "hostname" : "sts.amazonaws.com" - }, - "ca-central-1" : { }, - "eu-central-1" : { }, - "eu-north-1" : { }, - "eu-west-1" : { }, - "eu-west-2" : { }, - "eu-west-3" : { }, - "sa-east-1" : { }, - "us-east-1" : { }, - "us-east-1-fips" : { - "credentialScope" : { - "region" : "us-east-1" - }, - "hostname" : "sts-fips.us-east-1.amazonaws.com" - }, - "us-east-2" : { }, - "us-east-2-fips" : { - "credentialScope" : { - "region" : "us-east-2" - }, - "hostname" : "sts-fips.us-east-2.amazonaws.com" - }, - "us-west-1" : { }, - "us-west-1-fips" : { - "credentialScope" : { - "region" : "us-west-1" - }, - "hostname" : "sts-fips.us-west-1.amazonaws.com" - }, - "us-west-2" : { }, - "us-west-2-fips" : { - "credentialScope" : { - "region" : "us-west-2" - }, - "hostname" : "sts-fips.us-west-2.amazonaws.com" - } - }, - "partitionEndpoint" : "aws-global" - } - } - } - ] -}` - resolver, err := DecodeModel(strings.NewReader(v3Doc)) - if err != nil { - t.Fatalf("expected no error, got %v", err) - } + resolver := AwsCnPartition() cases := map[string]struct { service, region string @@ -884,10 +953,22 @@ func Test_Regional_Flag_CN(t *testing.T) { ExpectSigningNameDerived bool }{ "sts/cn-north-1/regional": { - service: "sts", region: "cn-north-1", regional: true, ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "cn-north-1", + service: "sts", + region: "cn-north-1", + regional: true, + ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "cn-north-1", }, "sts/cn-north-1/legacy": { - service: "sts", region: "cn-north-1", regional: false, ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", ExpectSigningMethod: "v4", ExpectSigningNameDerived: true, ExpectSigningRegion: "cn-north-1", + service: "sts", + region: "cn-north-1", + regional: false, + ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "cn-north-1", }, } diff --git a/aws/session/env_config.go b/aws/session/env_config.go index dcf501e4b75..cab888ab605 100644 --- a/aws/session/env_config.go +++ b/aws/session/env_config.go @@ -4,6 +4,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/endpoints" "os" "strconv" ) @@ -127,9 +128,9 @@ type envConfig struct { // Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service // - // AWS_STS_REGIONAL_ENDPOINTS =regional_endpoint + // AWS_STS_REGIONAL_ENDPOINTS =sts_regional_endpoint // This can take value as `regional` or `legacy` - RegionalEndpoint string + STSRegionalEndpoint endpoints.STSRegionalEndpoint } var ( @@ -184,7 +185,7 @@ var ( roleSessionNameEnvKey = []string{ "AWS_ROLE_SESSION_NAME", } - regionalEndpointKey = []string{ + stsRegionalEndpointKey = []string{ "AWS_STS_REGIONAL_ENDPOINTS", } ) @@ -272,15 +273,22 @@ func envConfigLoad(enableSharedConfig bool) envConfig { cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") - // Regional Endpoint variable - setFromEnvVal(&cfg.RegionalEndpoint, regionalEndpointKey) + // STS Regional Endpoint variable + for _, k := range stsRegionalEndpointKey { + if v := os.Getenv(k); len(v) != 0 { + STSRegionalEndpoint, err := endpoints.GetSTSRegionalEndpoint(v) + if err == nil { + cfg.STSRegionalEndpoint = STSRegionalEndpoint + } + } + } return cfg } func setFromEnvVal(dst *string, keys []string) { for _, k := range keys { - if v := os.Getenv(k); len(v) > 0 { + if v := os.Getenv(k); len(v) != 0 { *dst = v break } diff --git a/aws/session/session.go b/aws/session/session.go index 7991cffa338..14ac44fbd48 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -25,6 +25,12 @@ const ( // ErrCodeSharedConfig represents an error that occurs in the shared // configuration logic ErrCodeSharedConfig = "SharedConfigErr" + + // `Legacy` STSRegionalEndpoint represents the endpoint for legacy global endpoints + Legacy = "legacy" + + // `Regional` STSRegionalEndpoint represents the endpoint for regional sts endpoints + ) // ErrSharedConfigSourceCollision will be returned if a section contains both @@ -551,11 +557,7 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, } // Regional Endpoint flag for STS endpoint resolving - if envCfg.RegionalEndpoint != "" { - cfg.WithSTSRegionalEndpoint(envCfg.RegionalEndpoint) - } else if sharedCfg.RegionalEndpoint != "" { - cfg.WithSTSRegionalEndpoint(sharedCfg.RegionalEndpoint) - } + mergeSTSRegionalEndpointConfig(cfg, envCfg, sharedCfg) // Configure credentials if not already set by the user when creating the // Session. @@ -570,6 +572,22 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, return nil } +// mergeSTSRegionalEndpointConfig function merges the STSRegionalEndpoint into cfg from +// envConfig and SharedConfig with envConfig being given precedence over SharedConfig +func mergeSTSRegionalEndpointConfig(cfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig) error { + + cfg.STSRegionalEndpoint = envCfg.STSRegionalEndpoint + + if cfg.STSRegionalEndpoint == endpoints.UnsetSTSEndpoint { + cfg.STSRegionalEndpoint = sharedCfg.STSRegionalEndpoint + } + + if cfg.STSRegionalEndpoint == endpoints.UnsetSTSEndpoint { + cfg.STSRegionalEndpoint = endpoints.LegacySTSEndpoint + } + return nil +} + func initHandlers(s *Session) { // Add the Validate parameter handler if it is not disabled. s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) @@ -625,7 +643,7 @@ func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) ( opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack) // Support for STSRegionalEndpoint where the STSRegionalEndpoint is // provided in envconfig or sharedconfig with envconfig getting precedence. - opt.STSRegionalEndpoint = aws.BoolValue(s.Config.STSRegionalEndpoint) + opt.STSRegionalEndpoint = s.Config.STSRegionalEndpoint // Support the condition where the service is modeled but its // endpoint metadata is not available. diff --git a/aws/session/shared_config.go b/aws/session/shared_config.go index 0e6a6fe0649..d4abd951198 100644 --- a/aws/session/shared_config.go +++ b/aws/session/shared_config.go @@ -2,6 +2,7 @@ package session import ( "fmt" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" @@ -41,7 +42,7 @@ const ( webIdentityTokenFileKey = `web_identity_token_file` // optional // Additonal config fields for regional or legacy endpoints - regionalEndpointSharedKey = `sts_regional_endpoints` + stsRegionalEndpointSharedKey = `sts_regional_endpoints` // DefaultSharedConfigProfile is the default profile to be used when // loading configuration from the config files if another profile name @@ -92,9 +93,9 @@ type sharedConfig struct { CSMClientID string // Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service // - // sts_regional_endpoints = regional_endpoint - // This can take value as `regional` or `legacy` - RegionalEndpoint string + // sts_regional_endpoints = sts_regional_endpoint + // This can take value as `LegacySTSEndpoint` or `RegionalSTSEndpoint` + STSRegionalEndpoint endpoints.STSRegionalEndpoint } type sharedConfigFile struct { @@ -251,9 +252,16 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e updateString(&cfg.RoleSessionName, section, roleSessionNameKey) updateString(&cfg.SourceProfileName, section, sourceProfileKey) updateString(&cfg.CredentialSource, section, credentialSourceKey) - updateString(&cfg.Region, section, regionKey) - updateString(&cfg.RegionalEndpoint, section, regionalEndpointSharedKey) + + if v := section.String(stsRegionalEndpointSharedKey); len(v) != 0 { + STSRegionalEndpoint, err := endpoints.GetSTSRegionalEndpoint(v) + if err != nil { + return fmt.Errorf("failed to load %s from shared config, %s, %v", + stsRegionalEndpointKey, file.Filename, err) + } + cfg.STSRegionalEndpoint = STSRegionalEndpoint + } } updateString(&cfg.CredentialProcess, section, credentialProcessKey) From 02276614d309e7c8380b907f33b18288ce4f3a85 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Fri, 23 Aug 2019 13:27:58 -0700 Subject: [PATCH 07/20] Added error handling and formatted files --- aws/config.go | 1 - aws/endpoints/endpoints.go | 8 +++----- aws/session/env_config.go | 14 ++++++++------ aws/session/env_config_test.go | 17 ++++++++++++++--- aws/session/session.go | 16 +++++++++++++--- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/aws/config.go b/aws/config.go index 3b8853b1287..8a7699b9619 100644 --- a/aws/config.go +++ b/aws/config.go @@ -251,7 +251,6 @@ type Config struct { STSRegionalEndpoint endpoints.STSRegionalEndpoint } - // NewConfig returns a new Config pointer that can be chained with builder // methods to set multiple configuration values inline without using pointers. // diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index cfbb1bda440..80cefb38830 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -62,14 +62,14 @@ const ( RegionalSTSEndpoint ) -func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error){ - switch { +func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) { + switch { case strings.EqualFold(s, "legacy"): return LegacySTSEndpoint, nil case strings.EqualFold(s, "regional"): return RegionalSTSEndpoint, nil default: - return UnsetSTSEndpoint , fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s) + return UnsetSTSEndpoint, fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s) } } @@ -110,8 +110,6 @@ func STSRegionalEndpointOption(o *Options) { o.STSRegionalEndpoint = RegionalSTSEndpoint } - - // A Resolver provides the interface for functionality to resolve endpoints. // The build in Partition and DefaultResolver return value satisfy this interface. type Resolver interface { diff --git a/aws/session/env_config.go b/aws/session/env_config.go index cab888ab605..0802815b294 100644 --- a/aws/session/env_config.go +++ b/aws/session/env_config.go @@ -1,6 +1,7 @@ package session import ( + "fmt" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/defaults" @@ -196,7 +197,7 @@ var ( // If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value // the shared SDK config will be loaded in addition to the SDK's specific // configuration values. -func loadEnvConfig() envConfig { +func loadEnvConfig() (envConfig, error) { enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) return envConfigLoad(enableSharedConfig) } @@ -207,11 +208,11 @@ func loadEnvConfig() envConfig { // Loads the shared configuration in addition to the SDK's specific configuration. // This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` // environment variable is set. -func loadSharedEnvConfig() envConfig { +func loadSharedEnvConfig() (envConfig, error) { return envConfigLoad(true) } -func envConfigLoad(enableSharedConfig bool) envConfig { +func envConfigLoad(enableSharedConfig bool) (envConfig, error) { cfg := envConfig{} cfg.EnableSharedConfig = enableSharedConfig @@ -277,13 +278,14 @@ func envConfigLoad(enableSharedConfig bool) envConfig { for _, k := range stsRegionalEndpointKey { if v := os.Getenv(k); len(v) != 0 { STSRegionalEndpoint, err := endpoints.GetSTSRegionalEndpoint(v) - if err == nil { - cfg.STSRegionalEndpoint = STSRegionalEndpoint + if err != nil { + return cfg, fmt.Errorf("failed to load from env config, %v", err) } + cfg.STSRegionalEndpoint = STSRegionalEndpoint } } - return cfg + return cfg, nil } func setFromEnvVal(dst *string, keys []string) { diff --git a/aws/session/env_config_test.go b/aws/session/env_config_test.go index 03e4b4949e5..f210b614287 100644 --- a/aws/session/env_config_test.go +++ b/aws/session/env_config_test.go @@ -3,6 +3,7 @@ package session import ( + "fmt" "os" "reflect" "strconv" @@ -84,7 +85,10 @@ func TestLoadEnvConfig_Creds(t *testing.T) { os.Setenv(k, v) } - cfg := loadEnvConfig() + cfg, err := loadEnvConfig() + if err != nil { + fmt.Errorf("failed to load env config, %v", err) + } if !reflect.DeepEqual(c.Val, cfg.Creds) { t.Errorf("expect credentials to match.\n%s", awstesting.SprintExpectActual(c.Val, cfg.Creds)) @@ -279,10 +283,17 @@ func TestLoadEnvConfig(t *testing.T) { } var cfg envConfig + var err error if c.UseSharedConfigCall { - cfg = loadSharedEnvConfig() + cfg, err = loadSharedEnvConfig() + if err != nil { + fmt.Errorf("failed to load shared env config, %v", err) + } } else { - cfg = loadEnvConfig() + cfg, err = loadEnvConfig() + if err != nil { + fmt.Errorf("failed to load env config, %v", err) + } } if !reflect.DeepEqual(c.Config, cfg) { diff --git a/aws/session/session.go b/aws/session/session.go index 14ac44fbd48..abcfb6689d4 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -79,7 +79,10 @@ type Session struct { // func is called instead of waiting to receive an error until a request is made. func New(cfgs ...*aws.Config) *Session { // load initial config from environment - envCfg := loadEnvConfig() + envCfg, err := loadEnvConfig() + if err != nil { + fmt.Errorf("failed to load env config, %v", err) + } if envCfg.EnableSharedConfig { var cfg aws.Config @@ -285,10 +288,17 @@ type Options struct { // })) func NewSessionWithOptions(opts Options) (*Session, error) { var envCfg envConfig + var err error if opts.SharedConfigState == SharedConfigEnable { - envCfg = loadSharedEnvConfig() + envCfg, err = loadSharedEnvConfig() + if err != nil { + fmt.Errorf("failed to load environment from shared config, %v", err) + } } else { - envCfg = loadEnvConfig() + envCfg, err = loadEnvConfig() + if err != nil { + fmt.Errorf("failed to load environment from env config, %v", err) + } } if len(opts.Profile) != 0 { From 2c7365db402542aea79734ff22bcd394f544bf0a Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Fri, 23 Aug 2019 13:53:57 -0700 Subject: [PATCH 08/20] Fixed linting issues --- aws/endpoints/endpoints.go | 17 +++++++++++++++-- aws/session/session.go | 6 ------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index 80cefb38830..7d580ce319d 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -49,19 +49,32 @@ type Options struct { ResolveUnknownService bool // STS Regional Endpoint flag helps with resolving the STS RIP endpoint - // It has a default value of `true` for regional endpoints, - // and can be switched to `false` for legacy endpoints. STSRegionalEndpoint STSRegionalEndpoint } +// STSRegionalEndpoint is an enum type alias for int +// It is used internally by the core sdk as STS Regional Endpoint flag value type STSRegionalEndpoint int const ( + + // UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified. UnsetSTSEndpoint STSRegionalEndpoint = iota + + // LegacySTSEndpoint represents when STS Regional Endpoint flag is specified + // to use legacy endpoints. LegacySTSEndpoint + + // RegionalSTSEndpoint represents when STS Regional Endpoint flag is specified + // to use regional endpoints. RegionalSTSEndpoint ) +// GetSTSRegionalEndpoint function returns the STSRegionalEndpointFlag based +// on the input string provided in env config or shared config by the user. +// +// `legacy`, `regional` are the only case-insensitive valid strings for +// resolving the STS regional Endpoint flag. func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) { switch { case strings.EqualFold(s, "legacy"): diff --git a/aws/session/session.go b/aws/session/session.go index abcfb6689d4..e3e2b78d064 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -25,12 +25,6 @@ const ( // ErrCodeSharedConfig represents an error that occurs in the shared // configuration logic ErrCodeSharedConfig = "SharedConfigErr" - - // `Legacy` STSRegionalEndpoint represents the endpoint for legacy global endpoints - Legacy = "legacy" - - // `Regional` STSRegionalEndpoint represents the endpoint for regional sts endpoints - ) // ErrSharedConfigSourceCollision will be returned if a section contains both From 5f967cf71576675aa97d6ace8d9846fc331de2a4 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Fri, 23 Aug 2019 14:03:19 -0700 Subject: [PATCH 09/20] Fixes failing error handling when loading env config --- aws/endpoints/v3model_test.go | 2 -- aws/session/csm_test.go | 5 ++++- aws/session/shared_config.go | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 34d9b3d3779..7f1174262ed 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -8,8 +8,6 @@ import ( "regexp" "strings" "testing" - - "github.com/aws/aws-sdk-go/internal/sdktesting" ) func TestUnmarshalRegionRegex(t *testing.T) { diff --git a/aws/session/csm_test.go b/aws/session/csm_test.go index 0ed1c03a37b..7a0552a0cf0 100644 --- a/aws/session/csm_test.go +++ b/aws/session/csm_test.go @@ -101,7 +101,10 @@ func TestSession_loadCSMConfig(t *testing.T) { os.Setenv(name, v) } - envCfg := loadEnvConfig() + envCfg, err := loadEnvConfig() + if err != nil { + t.Errorf("failed to load the envcfg, %v", err) + } csmCfg, err := loadCSMConfig(envCfg, c.ConfigFiles) if len(c.Err) != 0 { if err == nil { diff --git a/aws/session/shared_config.go b/aws/session/shared_config.go index d4abd951198..117b1f48ad2 100644 --- a/aws/session/shared_config.go +++ b/aws/session/shared_config.go @@ -2,6 +2,7 @@ package session import ( "fmt" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/awserr" @@ -91,6 +92,7 @@ type sharedConfig struct { CSMHost string CSMPort string CSMClientID string + // Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service // // sts_regional_endpoints = sts_regional_endpoint From 09dde2f4237eb7570a0459bb4b39e8b142cf5dba Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Sat, 24 Aug 2019 00:42:27 -0700 Subject: [PATCH 10/20] Fixed error handling --- aws/session/env_config_test.go | 7 +++---- aws/session/session.go | 37 +++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/aws/session/env_config_test.go b/aws/session/env_config_test.go index f210b614287..d3769fbb1a9 100644 --- a/aws/session/env_config_test.go +++ b/aws/session/env_config_test.go @@ -3,7 +3,6 @@ package session import ( - "fmt" "os" "reflect" "strconv" @@ -87,7 +86,7 @@ func TestLoadEnvConfig_Creds(t *testing.T) { cfg, err := loadEnvConfig() if err != nil { - fmt.Errorf("failed to load env config, %v", err) + t.Errorf("failed to load env config, %v", err) } if !reflect.DeepEqual(c.Val, cfg.Creds) { t.Errorf("expect credentials to match.\n%s", @@ -287,12 +286,12 @@ func TestLoadEnvConfig(t *testing.T) { if c.UseSharedConfigCall { cfg, err = loadSharedEnvConfig() if err != nil { - fmt.Errorf("failed to load shared env config, %v", err) + t.Errorf("failed to load shared env config, %v", err) } } else { cfg, err = loadEnvConfig() if err != nil { - fmt.Errorf("failed to load env config, %v", err) + t.Errorf("failed to load env config, %v", err) } } diff --git a/aws/session/session.go b/aws/session/session.go index e3e2b78d064..a651b0002af 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -73,10 +73,7 @@ type Session struct { // func is called instead of waiting to receive an error until a request is made. func New(cfgs ...*aws.Config) *Session { // load initial config from environment - envCfg, err := loadEnvConfig() - if err != nil { - fmt.Errorf("failed to load env config, %v", err) - } + envCfg, envErr := loadEnvConfig() if envCfg.EnableSharedConfig { var cfg aws.Config @@ -96,17 +93,17 @@ func New(cfgs ...*aws.Config) *Session { // Session creation failed, need to report the error and prevent // any requests from succeeding. s = &Session{Config: defaults.Config()} - s.Config.MergeIn(cfgs...) - s.Config.Logger.Log("ERROR:", msg, "Error:", err) - s.Handlers.Validate.PushBack(func(r *request.Request) { - r.Error = err - }) + s.errorLogHelper(msg, err, cfgs) } return s } s := deprecatedNewSession(cfgs...) + if envErr != nil { + msg := "failed to load env config" + s.errorLogHelper(msg, envErr, cfgs) + } if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil { if l := s.Config.Logger; l != nil { @@ -115,11 +112,8 @@ func New(cfgs ...*aws.Config) *Session { } else if csmCfg.Enabled { err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger) if err != nil { - err = fmt.Errorf("failed to enable CSM, %v", err) - s.Config.Logger.Log("ERROR:", err.Error()) - s.Handlers.Validate.PushBack(func(r *request.Request) { - r.Error = err - }) + msg := "failed to enable CSM" + s.errorLogHelper(msg, err, cfgs) } } @@ -286,12 +280,12 @@ func NewSessionWithOptions(opts Options) (*Session, error) { if opts.SharedConfigState == SharedConfigEnable { envCfg, err = loadSharedEnvConfig() if err != nil { - fmt.Errorf("failed to load environment from shared config, %v", err) + return nil, fmt.Errorf("failed to load environment from shared config, %v", err) } } else { envCfg, err = loadEnvConfig() if err != nil { - fmt.Errorf("failed to load environment from env config, %v", err) + return nil, fmt.Errorf("failed to load environment from env config, %v", err) } } @@ -690,3 +684,14 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf SigningName: resolved.SigningName, } } + +// errorLogHelper function enables error handling for session +func (s *Session) errorLogHelper(msg string, err error, cfgs []*aws.Config) { + // Session creation failed, need to report the error and prevent + // any requests from succeeding. + s.Config.MergeIn(cfgs...) + s.Config.Logger.Log("ERROR:", msg, "Error:", err) + s.Handlers.Validate.PushBack(func(r *request.Request) { + r.Error = err + }) +} From bb56c940429c383b02383e1ec842f281c148f350 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Sat, 24 Aug 2019 10:45:52 -0700 Subject: [PATCH 11/20] Adds aws/endpoints/Test_Regional_Flag support for updated STS model by using AwsPartition resolver for testing --- aws/endpoints/v3model_test.go | 102 ++-------------------------------- 1 file changed, 5 insertions(+), 97 deletions(-) diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 7f1174262ed..2ff66a31685 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -6,7 +6,6 @@ import ( "encoding/json" "reflect" "regexp" - "strings" "testing" ) @@ -477,102 +476,10 @@ func TestResolveEndpoint_AwsGlobal(t *testing.T) { } } func Test_Regional_Flag(t *testing.T) { - const v3Doc = ` -{ - "version": 3, - "partitions": [ - { - "defaults": { - "hostname": "{service}.{region}.{dnsSuffix}", - "protocols": [ - "https" - ], - "signatureVersions": [ - "v4" - ] - }, - "dnsSuffix": "amazonaws.com", - "partition": "aws", - "partitionName": "AWS Standard", - "regionRegex": "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$", - "regions": { - "ap-northeast-1": { - "description": "Asia Pacific (Tokyo)" - } - }, - "services": { - "acm": { - "endpoints": { - "ap-northeast-1": {} - } - }, - "s3": { - "endpoints": { - "ap-northeast-1": {} - } - }, - "sts" : { - "defaults" : { }, - "endpoints" : { - "ap-east-1" : { }, - "ap-northeast-1" : { }, - "ap-northeast-2" : { }, - "ap-south-1" : { }, - "ap-southeast-1" : { }, - "ap-southeast-2" : { }, - "aws-global" : { - "credentialScope" : { - "region" : "us-east-1" - }, - "hostname" : "sts.amazonaws.com" - }, - "ca-central-1" : { }, - "eu-central-1" : { }, - "eu-north-1" : { }, - "eu-west-1" : { }, - "eu-west-2" : { }, - "eu-west-3" : { }, - "sa-east-1" : { }, - "us-east-1" : { }, - "us-east-1-fips" : { - "credentialScope" : { - "region" : "us-east-1" - }, - "hostname" : "sts-fips.us-east-1.amazonaws.com" - }, - "us-east-2" : { }, - "us-east-2-fips" : { - "credentialScope" : { - "region" : "us-east-2" - }, - "hostname" : "sts-fips.us-east-2.amazonaws.com" - }, - "us-west-1" : { }, - "us-west-1-fips" : { - "credentialScope" : { - "region" : "us-west-1" - }, - "hostname" : "sts-fips.us-west-1.amazonaws.com" - }, - "us-west-2" : { }, - "us-west-2-fips" : { - "credentialScope" : { - "region" : "us-west-2" - }, - "hostname" : "sts-fips.us-west-2.amazonaws.com" - } - }, - "partitionEndpoint" : "aws-global" - } - } - } - ] -}` - - resolver, err := DecodeModel(strings.NewReader(v3Doc)) - if err != nil { - t.Fatalf("expected no error, got %v", err) - } + + // AwsPartition resolver for STS regional endpoints in AWS Partition + resolver := AwsPartition() + cases := map[string]struct { service, region string regional bool @@ -942,6 +849,7 @@ func Test_Regional_Flag(t *testing.T) { func Test_Regional_Flag_CN(t *testing.T) { + // AwsCnPartition resolver for STS regional endpoints in AWS-CN Partition resolver := AwsCnPartition() cases := map[string]struct { From 4e1ae0afe6bc8bf3602c31932569ffeb619842cc Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Sat, 24 Aug 2019 11:15:24 -0700 Subject: [PATCH 12/20] Added entry to CHANGELOG_PENDING.md --- CHANGELOG_PENDING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 8a1927a39ca..f5d0920ec44 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,5 +1,8 @@ ### SDK Features ### SDK Enhancements +* `aws/endpoints`: Adds support for STS Regional Flags ([#2779](https://github.com/aws/aws-sdk-go/pull/2779)) + * Adds unit test cases for STS Regional flags to test STS endpoint resolver when flag is set to `legacy` or `regional` or is `unset`. + * Adds error handling when loading environment config from sharedConfig or envConfig. ### SDK Bugs From 6ea7587b9e33d6f71869185c7770a06b8175a536 Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Mon, 26 Aug 2019 09:48:42 -0700 Subject: [PATCH 13/20] Fixes linting --- aws/endpoints/sts_legacy_regions.go | 2 +- aws/endpoints/v3model.go | 2 +- aws/session/env_config.go | 5 +++-- aws/session/shared_config.go | 3 +-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/endpoints/sts_legacy_regions.go b/aws/endpoints/sts_legacy_regions.go index ce905e438bc..68ed2d9e25f 100644 --- a/aws/endpoints/sts_legacy_regions.go +++ b/aws/endpoints/sts_legacy_regions.go @@ -1,6 +1,6 @@ package endpoints -var stsLegacyGlocalRegions = map[string]struct{}{ +var stsLegacyGlobalRegions = map[string]struct{}{ "ap-northeast-1": {}, "ap-south-1": {}, "ap-southeast-1": {}, diff --git a/aws/endpoints/v3model.go b/aws/endpoints/v3model.go index 9531f350489..49a3a398847 100644 --- a/aws/endpoints/v3model.go +++ b/aws/endpoints/v3model.go @@ -80,7 +80,7 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) ( opt.Set(opts...) if service == "sts" && opt.STSRegionalEndpoint != RegionalSTSEndpoint { - if _, ok := stsLegacyGlocalRegions[region]; ok { + if _, ok := stsLegacyGlobalRegions[region]; ok { region = "aws-global" } } diff --git a/aws/session/env_config.go b/aws/session/env_config.go index 0802815b294..6e7cb7ed76a 100644 --- a/aws/session/env_config.go +++ b/aws/session/env_config.go @@ -2,12 +2,13 @@ package session import ( "fmt" + "os" + "strconv" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/endpoints" - "os" - "strconv" ) // EnvProviderName provides a name of the provider when config is loaded from environment. diff --git a/aws/session/shared_config.go b/aws/session/shared_config.go index 117b1f48ad2..b6cd1827189 100644 --- a/aws/session/shared_config.go +++ b/aws/session/shared_config.go @@ -3,10 +3,9 @@ package session import ( "fmt" - "github.com/aws/aws-sdk-go/aws/endpoints" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/internal/ini" ) From 48a90b12d45f057dabcb0af1dc2d53c1aa7b97aa Mon Sep 17 00:00:00 2001 From: Kotambkar Date: Mon, 26 Aug 2019 15:22:29 -0700 Subject: [PATCH 14/20] Adds suggested changes --- aws/endpoints/endpoints.go | 3 +++ aws/endpoints/v3model_test.go | 4 ++-- aws/session/csm_test.go | 2 +- aws/session/env_config.go | 2 +- aws/session/env_config_test.go | 2 +- aws/session/session.go | 14 +++++++------- aws/session/shared_config.go | 2 +- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index 7d580ce319d..bb3f3ef1996 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -119,6 +119,9 @@ func ResolveUnknownServiceOption(o *Options) { // STSRegionalEndpointOption sets the STSRegionalEndpoint option. Can be used // as a functional option when resolving endpoints. +// +// STSRegionalEndpointOption enables the STS endpoint resolver behavior to resolve +// STS endpoint to their regional endpoint, instead of the global endpoint. func STSRegionalEndpointOption(o *Options) { o.STSRegionalEndpoint = RegionalSTSEndpoint } diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 2ff66a31685..2c523762141 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -475,8 +475,8 @@ func TestResolveEndpoint_AwsGlobal(t *testing.T) { t.Errorf("expect the signing name to be derived") } } -func Test_Regional_Flag(t *testing.T) { +func TestEndpointFor_RegionalFlag(t *testing.T) { // AwsPartition resolver for STS regional endpoints in AWS Partition resolver := AwsPartition() @@ -847,7 +847,7 @@ func Test_Regional_Flag(t *testing.T) { } } -func Test_Regional_Flag_CN(t *testing.T) { +func TestEndpointFor_RegionalFlagCN(t *testing.T) { // AwsCnPartition resolver for STS regional endpoints in AWS-CN Partition resolver := AwsCnPartition() diff --git a/aws/session/csm_test.go b/aws/session/csm_test.go index 7a0552a0cf0..90da22bc700 100644 --- a/aws/session/csm_test.go +++ b/aws/session/csm_test.go @@ -103,7 +103,7 @@ func TestSession_loadCSMConfig(t *testing.T) { envCfg, err := loadEnvConfig() if err != nil { - t.Errorf("failed to load the envcfg, %v", err) + t.Fatalf("failed to load the envcfg, %v", err) } csmCfg, err := loadCSMConfig(envCfg, c.ConfigFiles) if len(c.Err) != 0 { diff --git a/aws/session/env_config.go b/aws/session/env_config.go index 6e7cb7ed76a..530cc3a9c06 100644 --- a/aws/session/env_config.go +++ b/aws/session/env_config.go @@ -280,7 +280,7 @@ func envConfigLoad(enableSharedConfig bool) (envConfig, error) { if v := os.Getenv(k); len(v) != 0 { STSRegionalEndpoint, err := endpoints.GetSTSRegionalEndpoint(v) if err != nil { - return cfg, fmt.Errorf("failed to load from env config, %v", err) + return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err) } cfg.STSRegionalEndpoint = STSRegionalEndpoint } diff --git a/aws/session/env_config_test.go b/aws/session/env_config_test.go index d3769fbb1a9..5d5e37ae49d 100644 --- a/aws/session/env_config_test.go +++ b/aws/session/env_config_test.go @@ -86,7 +86,7 @@ func TestLoadEnvConfig_Creds(t *testing.T) { cfg, err := loadEnvConfig() if err != nil { - t.Errorf("failed to load env config, %v", err) + t.Fatalf("failed to load env config, %v", err) } if !reflect.DeepEqual(c.Val, cfg.Creds) { t.Errorf("expect credentials to match.\n%s", diff --git a/aws/session/session.go b/aws/session/session.go index a651b0002af..245a5fb1bac 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -93,7 +93,7 @@ func New(cfgs ...*aws.Config) *Session { // Session creation failed, need to report the error and prevent // any requests from succeeding. s = &Session{Config: defaults.Config()} - s.errorLogHelper(msg, err, cfgs) + s.logDeprecatedNewSessionError(msg, err, cfgs) } return s @@ -102,7 +102,7 @@ func New(cfgs ...*aws.Config) *Session { s := deprecatedNewSession(cfgs...) if envErr != nil { msg := "failed to load env config" - s.errorLogHelper(msg, envErr, cfgs) + s.logDeprecatedNewSessionError(msg, envErr, cfgs) } if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil { @@ -113,7 +113,7 @@ func New(cfgs ...*aws.Config) *Session { err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger) if err != nil { msg := "failed to enable CSM" - s.errorLogHelper(msg, err, cfgs) + s.logDeprecatedNewSessionError(msg, err, cfgs) } } @@ -280,12 +280,12 @@ func NewSessionWithOptions(opts Options) (*Session, error) { if opts.SharedConfigState == SharedConfigEnable { envCfg, err = loadSharedEnvConfig() if err != nil { - return nil, fmt.Errorf("failed to load environment from shared config, %v", err) + return nil, fmt.Errorf("failed to load shared config, %v", err) } } else { envCfg, err = loadEnvConfig() if err != nil { - return nil, fmt.Errorf("failed to load environment from env config, %v", err) + return nil, fmt.Errorf("failed to load environment config, %v", err) } } @@ -685,8 +685,8 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf } } -// errorLogHelper function enables error handling for session -func (s *Session) errorLogHelper(msg string, err error, cfgs []*aws.Config) { +// logDeprecatedNewSessionError function enables error handling for session +func (s *Session) logDeprecatedNewSessionError(msg string, err error, cfgs []*aws.Config) { // Session creation failed, need to report the error and prevent // any requests from succeeding. s.Config.MergeIn(cfgs...) diff --git a/aws/session/shared_config.go b/aws/session/shared_config.go index b6cd1827189..2a23755c5a3 100644 --- a/aws/session/shared_config.go +++ b/aws/session/shared_config.go @@ -41,7 +41,7 @@ const ( // Web Identity Token File webIdentityTokenFileKey = `web_identity_token_file` // optional - // Additonal config fields for regional or legacy endpoints + // Additional config fields for regional or legacy endpoints stsRegionalEndpointSharedKey = `sts_regional_endpoints` // DefaultSharedConfigProfile is the default profile to be used when From e55aeac0fe2557728af23795de0fb3d903b74e87 Mon Sep 17 00:00:00 2001 From: skotambkar Date: Tue, 27 Aug 2019 10:04:08 -0700 Subject: [PATCH 15/20] Adds suggested change --- aws/endpoints/endpoints.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index bb3f3ef1996..801f8b6ca7d 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -117,9 +117,6 @@ func ResolveUnknownServiceOption(o *Options) { o.ResolveUnknownService = true } -// STSRegionalEndpointOption sets the STSRegionalEndpoint option. Can be used -// as a functional option when resolving endpoints. -// // STSRegionalEndpointOption enables the STS endpoint resolver behavior to resolve // STS endpoint to their regional endpoint, instead of the global endpoint. func STSRegionalEndpointOption(o *Options) { From 3803dd9cb38632bfbeb8aa8739cd77bc4babdb25 Mon Sep 17 00:00:00 2001 From: Shantanu Kotambkar <52007797+skotambkar@users.noreply.github.com> Date: Wed, 28 Aug 2019 15:12:57 -0700 Subject: [PATCH 16/20] Updated with suggested change --- aws/endpoints/endpoints.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/endpoints/endpoints.go b/aws/endpoints/endpoints.go index 801f8b6ca7d..c06901efa43 100644 --- a/aws/endpoints/endpoints.go +++ b/aws/endpoints/endpoints.go @@ -48,7 +48,7 @@ type Options struct { // This option is ignored if StrictMatching is enabled. ResolveUnknownService bool - // STS Regional Endpoint flag helps with resolving the STS RIP endpoint + // STS Regional Endpoint flag helps with resolving the STS endpoint STSRegionalEndpoint STSRegionalEndpoint } From 6b8a8d20246fc015d27aa85385cbcb07a24ae406 Mon Sep 17 00:00:00 2001 From: skotambkar Date: Fri, 4 Oct 2019 10:30:37 -0700 Subject: [PATCH 17/20] adds mock sts regional model for testing --- aws/endpoints/v3model_sts_regional_test.go | 583 +++++++++++++++++++++ aws/endpoints/v3model_test.go | 367 +------------ 2 files changed, 584 insertions(+), 366 deletions(-) create mode 100644 aws/endpoints/v3model_sts_regional_test.go diff --git a/aws/endpoints/v3model_sts_regional_test.go b/aws/endpoints/v3model_sts_regional_test.go new file mode 100644 index 00000000000..556fcf1ace0 --- /dev/null +++ b/aws/endpoints/v3model_sts_regional_test.go @@ -0,0 +1,583 @@ +// +build go1.7 + +package endpoints + +import ( + "regexp" + "testing" +) + +func TestEndpointFor_STSRegionalFlag(t *testing.T) { + + // mock STS regional endpoints model + mockSTSModelPartition := partition{ + ID: "aws", + Name: "AWS Standard", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^(us|eu|ap|sa|ca|me)\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "ap-east-1": region{ + Description: "Asia Pacific (Hong Kong)", + }, + "ap-northeast-1": region{ + Description: "Asia Pacific (Tokyo)", + }, + "ap-northeast-2": region{ + Description: "Asia Pacific (Seoul)", + }, + "ap-south-1": region{ + Description: "Asia Pacific (Mumbai)", + }, + "ap-southeast-1": region{ + Description: "Asia Pacific (Singapore)", + }, + "ap-southeast-2": region{ + Description: "Asia Pacific (Sydney)", + }, + "ca-central-1": region{ + Description: "Canada (Central)", + }, + "eu-central-1": region{ + Description: "EU (Frankfurt)", + }, + "eu-north-1": region{ + Description: "EU (Stockholm)", + }, + "eu-west-1": region{ + Description: "EU (Ireland)", + }, + "eu-west-2": region{ + Description: "EU (London)", + }, + "eu-west-3": region{ + Description: "EU (Paris)", + }, + "me-south-1": region{ + Description: "Middle East (Bahrain)", + }, + "sa-east-1": region{ + Description: "South America (Sao Paulo)", + }, + "us-east-1": region{ + Description: "US East (N. Virginia)", + }, + "us-east-2": region{ + Description: "US East (Ohio)", + }, + "us-west-1": region{ + Description: "US West (N. California)", + }, + "us-west-2": region{ + Description: "US West (Oregon)", + }, + }, + Services: services{ + "sts": service{ + PartitionEndpoint: "aws-global", + Defaults: endpoint{}, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "aws-global": endpoint{ + Hostname: "sts.amazonaws.com", + CredentialScope : credentialScope { + Region : "us-east-1", + }, + }, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "sts-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "sts-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "sts-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "sts-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + }, + } + + // resolver for mock STS regional endpoints model + resolver := mockSTSModelPartition + + cases := map[string]struct { + service, region string + regional bool + ExpectURL, ExpectSigningMethod, ExpectSigningRegion string + ExpectSigningNameDerived bool + }{ + // STS Endpoints resolver tests : + "sts/us-west-2/regional": { + service: "sts", + region: "us-west-2", + regional: true, + ExpectURL: "https://sts.us-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-2", + }, + "sts/us-west-2/legacy": { + service: "sts", + region: "us-west-2", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/ap-east-1/regional": { + service: "sts", + region: "ap-east-1", + regional: true, + ExpectURL: "https://sts.ap-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-east-1", + }, + "sts/ap-east-1/legacy": { + service: "sts", + region: "ap-east-1", + regional: false, + ExpectURL: "https://sts.ap-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-east-1", + }, + "sts/us-west-2-fips/regional": { + service: "sts", + region: "us-west-2-fips", + regional: true, + ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-2", + }, + "sts/us-west-2-fips/legacy": { + service: "sts", + region: "us-west-2-fips", + regional: false, + ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-2", + }, + "sts/aws-global/regional": { + service: "sts", + region: "aws-global", + regional: true, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/aws-global/legacy": { + service: "sts", + region: "aws-global", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/ap-south-1/regional": { + service: "sts", + region: "ap-south-1", + regional: true, + ExpectURL: "https://sts.ap-south-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-south-1", + }, + "sts/ap-south-1/legacy": { + service: "sts", + region: "ap-south-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/ap-northeast-1/regional": { + service: "sts", + region: "ap-northeast-1", + regional: true, + ExpectURL: "https://sts.ap-northeast-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-northeast-1", + }, + "sts/ap-northeast-1/legacy": { + service: "sts", + region: "ap-northeast-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/ap-southeast-1/regional": { + service: "sts", + region: "ap-southeast-1", + regional: true, + ExpectURL: "https://sts.ap-southeast-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ap-southeast-1", + }, + "sts/ap-southeast-1/legacy": { + service: "sts", + region: "ap-southeast-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/ca-central-1/regional": { + service: "sts", + region: "ca-central-1", + regional: true, + ExpectURL: "https://sts.ca-central-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "ca-central-1", + }, + "sts/ca-central-1/legacy": { + service: "sts", + region: "ca-central-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/eu-central-1/regional": { + service: "sts", + region: "eu-central-1", + regional: true, + ExpectURL: "https://sts.eu-central-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-central-1", + }, + "sts/eu-central-1/legacy": { + service: "sts", + region: "eu-central-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/eu-north-1/regional": { + service: "sts", + region: "eu-north-1", + regional: true, + ExpectURL: "https://sts.eu-north-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-north-1", + }, + "sts/eu-north-1/legacy": { + service: "sts", + region: "eu-north-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/eu-west-1/regional": { + service: "sts", + region: "eu-west-1", + regional: true, + ExpectURL: "https://sts.eu-west-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-west-1", + }, + "sts/eu-west-1/legacy": { + service: "sts", + region: "eu-west-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/eu-west-2/regional": { + service: "sts", + region: "eu-west-2", + regional: true, + ExpectURL: "https://sts.eu-west-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-west-2", + }, + "sts/eu-west-2/legacy": { + service: "sts", + region: "eu-west-2", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/eu-west-3/regional": { + service: "sts", + region: "eu-west-3", + regional: true, + ExpectURL: "https://sts.eu-west-3.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "eu-west-3", + }, + "sts/eu-west-3/legacy": { + service: "sts", + region: "eu-west-3", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/sa-east-1/regional": { + service: "sts", + region: "sa-east-1", + regional: true, + ExpectURL: "https://sts.sa-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "sa-east-1", + }, + "sts/sa-east-1/legacy": { + service: "sts", + region: "sa-east-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/us-east-1/regional": { + service: "sts", + region: "us-east-1", + regional: true, + ExpectURL: "https://sts.us-east-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/us-east-1/legacy": { + service: "sts", + region: "us-east-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/us-east-2/regional": { + service: "sts", + region: "us-east-2", + regional: true, + ExpectURL: "https://sts.us-east-2.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-2", + }, + "sts/us-east-2/legacy": { + service: "sts", + region: "us-east-2", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + "sts/us-west-1/regional": { + service: "sts", + region: "us-west-1", + regional: true, + ExpectURL: "https://sts.us-west-1.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-west-1", + }, + "sts/us-west-1/legacy": { + service: "sts", + region: "us-west-1", + regional: false, + ExpectURL: "https://sts.amazonaws.com", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "us-east-1", + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + var optionSlice []func(o *Options) + optionSlice = append(optionSlice, func(o *Options) { + if c.regional { + o.STSRegionalEndpoint = RegionalSTSEndpoint + } + }) + + actual, err := resolver.EndpointFor(c.service, c.region, optionSlice...) + if err != nil { + t.Fatalf("failed to resolve endpoint, %v", err) + } + + if e, a := c.ExpectURL, actual.URL; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := c.ExpectSigningMethod, actual.SigningMethod; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := c.ExpectSigningNameDerived, actual.SigningNameDerived; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + if e, a := c.ExpectSigningRegion, actual.SigningRegion; e != a { + t.Errorf("expect %v, got %v", e, a) + } + + }) + } +} + +func TestSTSRegionalEndpoint_CNPartition(t *testing.T) { + mockSTSCNPartition := partition{ + ID: "aws-cn", + Name: "AWS China", + DNSSuffix: "amazonaws.com.cn", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^cn\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "cn-north-1": region{ + Description: "China (Beijing)", + }, + "cn-northwest-1": region{ + Description: "China (Ningxia)", + }, + }, + Services: services{ + "sts": service{ + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + }, + } + + resolver := mockSTSCNPartition + + cases := map[string]struct { + service, region string + regional bool + ExpectURL, ExpectSigningMethod, ExpectSigningRegion string + ExpectSigningNameDerived bool + }{ + "sts/cn-north-1/regional": { + service: "sts", + region: "cn-north-1", + regional: true, + ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "cn-north-1", + }, + "sts/cn-north-1/legacy": { + service: "sts", + region: "cn-north-1", + regional: false, + ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", + ExpectSigningMethod: "v4", + ExpectSigningNameDerived: true, + ExpectSigningRegion: "cn-north-1", + }, + } + + for name, c := range cases { + var optionSlice []func(o *Options) + t.Run(name, func(t *testing.T) { + if c.regional { + optionSlice = append(optionSlice, STSRegionalEndpointOption) + } + actual, err := resolver.EndpointFor(c.service, c.region, optionSlice...) + if err != nil { + t.Fatalf("failed to resolve endpoint, %v", err) + } + + if e, a := c.ExpectURL, actual.URL; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := c.ExpectSigningMethod, actual.SigningMethod; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := c.ExpectSigningNameDerived, actual.SigningNameDerived; e != a { + t.Errorf("expect %v, got %v", e, a) + } + if e, a := c.ExpectSigningRegion, actual.SigningRegion; e != a { + t.Errorf("expect %v, got %v", e, a) + } + }) + } + +} + diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 2c523762141..35ad692a123 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -504,313 +504,6 @@ func TestEndpointFor_RegionalFlag(t *testing.T) { ExpectSigningNameDerived: true, ExpectSigningRegion: "ap-northeast-1", }, - // STS Endpoints resolver tests : - "sts/us-west-2/regional": { - service: "sts", - region: "us-west-2", - regional: true, - ExpectURL: "https://sts.us-west-2.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-west-2", - }, - "sts/us-west-2/legacy": { - service: "sts", - region: "us-west-2", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/ap-east-1/regional": { - service: "sts", - region: "ap-east-1", - regional: true, - ExpectURL: "https://sts.ap-east-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "ap-east-1", - }, - "sts/ap-east-1/legacy": { - service: "sts", - region: "ap-east-1", - regional: false, - ExpectURL: "https://sts.ap-east-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "ap-east-1", - }, - "sts/us-west-2-fips/regional": { - service: "sts", - region: "us-west-2-fips", - regional: true, - ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-west-2", - }, - "sts/us-west-2-fips/legacy": { - service: "sts", - region: "us-west-2-fips", - regional: false, - ExpectURL: "https://sts-fips.us-west-2.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-west-2", - }, - "sts/aws-global/regional": { - service: "sts", - region: "aws-global", - regional: true, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/aws-global/legacy": { - service: "sts", - region: "aws-global", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/ap-south-1/regional": { - service: "sts", - region: "ap-south-1", - regional: true, - ExpectURL: "https://sts.ap-south-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "ap-south-1", - }, - "sts/ap-south-1/legacy": { - service: "sts", - region: "ap-south-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/ap-northeast-1/regional": { - service: "sts", - region: "ap-northeast-1", - regional: true, - ExpectURL: "https://sts.ap-northeast-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "ap-northeast-1", - }, - "sts/ap-northeast-1/legacy": { - service: "sts", - region: "ap-northeast-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/ap-southeast-1/regional": { - service: "sts", - region: "ap-southeast-1", - regional: true, - ExpectURL: "https://sts.ap-southeast-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "ap-southeast-1", - }, - "sts/ap-southeast-1/legacy": { - service: "sts", - region: "ap-southeast-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/ca-central-1/regional": { - service: "sts", - region: "ca-central-1", - regional: true, - ExpectURL: "https://sts.ca-central-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "ca-central-1", - }, - "sts/ca-central-1/legacy": { - service: "sts", - region: "ca-central-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/eu-central-1/regional": { - service: "sts", - region: "eu-central-1", - regional: true, - ExpectURL: "https://sts.eu-central-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "eu-central-1", - }, - "sts/eu-central-1/legacy": { - service: "sts", - region: "eu-central-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/eu-north-1/regional": { - service: "sts", - region: "eu-north-1", - regional: true, - ExpectURL: "https://sts.eu-north-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "eu-north-1", - }, - "sts/eu-north-1/legacy": { - service: "sts", - region: "eu-north-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/eu-west-1/regional": { - service: "sts", - region: "eu-west-1", - regional: true, - ExpectURL: "https://sts.eu-west-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "eu-west-1", - }, - "sts/eu-west-1/legacy": { - service: "sts", - region: "eu-west-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/eu-west-2/regional": { - service: "sts", - region: "eu-west-2", - regional: true, - ExpectURL: "https://sts.eu-west-2.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "eu-west-2", - }, - "sts/eu-west-2/legacy": { - service: "sts", - region: "eu-west-2", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/eu-west-3/regional": { - service: "sts", - region: "eu-west-3", - regional: true, - ExpectURL: "https://sts.eu-west-3.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "eu-west-3", - }, - "sts/eu-west-3/legacy": { - service: "sts", - region: "eu-west-3", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/sa-east-1/regional": { - service: "sts", - region: "sa-east-1", - regional: true, - ExpectURL: "https://sts.sa-east-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "sa-east-1", - }, - "sts/sa-east-1/legacy": { - service: "sts", - region: "sa-east-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/us-east-1/regional": { - service: "sts", - region: "us-east-1", - regional: true, - ExpectURL: "https://sts.us-east-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/us-east-1/legacy": { - service: "sts", - region: "us-east-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/us-east-2/regional": { - service: "sts", - region: "us-east-2", - regional: true, - ExpectURL: "https://sts.us-east-2.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-2", - }, - "sts/us-east-2/legacy": { - service: "sts", - region: "us-east-2", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, - "sts/us-west-1/regional": { - service: "sts", - region: "us-west-1", - regional: true, - ExpectURL: "https://sts.us-west-1.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-west-1", - }, - "sts/us-west-1/legacy": { - service: "sts", - region: "us-west-1", - regional: false, - ExpectURL: "https://sts.amazonaws.com", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "us-east-1", - }, } for name, c := range cases { @@ -845,62 +538,4 @@ func TestEndpointFor_RegionalFlag(t *testing.T) { }) } -} - -func TestEndpointFor_RegionalFlagCN(t *testing.T) { - - // AwsCnPartition resolver for STS regional endpoints in AWS-CN Partition - resolver := AwsCnPartition() - - cases := map[string]struct { - service, region string - regional bool - ExpectURL, ExpectSigningMethod, ExpectSigningRegion string - ExpectSigningNameDerived bool - }{ - "sts/cn-north-1/regional": { - service: "sts", - region: "cn-north-1", - regional: true, - ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "cn-north-1", - }, - "sts/cn-north-1/legacy": { - service: "sts", - region: "cn-north-1", - regional: false, - ExpectURL: "https://sts.cn-north-1.amazonaws.com.cn", - ExpectSigningMethod: "v4", - ExpectSigningNameDerived: true, - ExpectSigningRegion: "cn-north-1", - }, - } - - for name, c := range cases { - var optionSlice []func(o *Options) - t.Run(name, func(t *testing.T) { - if c.regional { - optionSlice = append(optionSlice, STSRegionalEndpointOption) - } - actual, err := resolver.EndpointFor(c.service, c.region, optionSlice...) - if err != nil { - t.Fatalf("failed to resolve endpoint, %v", err) - } - - if e, a := c.ExpectURL, actual.URL; e != a { - t.Errorf("expect %v, got %v", e, a) - } - if e, a := c.ExpectSigningMethod, actual.SigningMethod; e != a { - t.Errorf("expect %v, got %v", e, a) - } - if e, a := c.ExpectSigningNameDerived, actual.SigningNameDerived; e != a { - t.Errorf("expect %v, got %v", e, a) - } - if e, a := c.ExpectSigningRegion, actual.SigningRegion; e != a { - t.Errorf("expect %v, got %v", e, a) - } - }) - } -} +} \ No newline at end of file From 33c11c7108995833768826c9f59a356435f8fd77 Mon Sep 17 00:00:00 2001 From: skotambkar Date: Fri, 4 Oct 2019 14:36:49 -0700 Subject: [PATCH 18/20] fix go fmt --- aws/endpoints/v3model_sts_regional_test.go | 27 +++++++++++----------- aws/endpoints/v3model_test.go | 2 +- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/aws/endpoints/v3model_sts_regional_test.go b/aws/endpoints/v3model_sts_regional_test.go index 556fcf1ace0..aa6784a897a 100644 --- a/aws/endpoints/v3model_sts_regional_test.go +++ b/aws/endpoints/v3model_sts_regional_test.go @@ -84,7 +84,7 @@ func TestEndpointFor_STSRegionalFlag(t *testing.T) { Services: services{ "sts": service{ PartitionEndpoint: "aws-global", - Defaults: endpoint{}, + Defaults: endpoint{}, Endpoints: endpoints{ "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, @@ -92,21 +92,21 @@ func TestEndpointFor_STSRegionalFlag(t *testing.T) { "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, - "aws-global": endpoint{ + "aws-global": endpoint{ Hostname: "sts.amazonaws.com", - CredentialScope : credentialScope { - Region : "us-east-1", + CredentialScope: credentialScope{ + Region: "us-east-1", }, }, - "ca-central-1": endpoint{}, - "eu-central-1": endpoint{}, - "eu-north-1": endpoint{}, - "eu-west-1": endpoint{}, - "eu-west-2": endpoint{}, - "eu-west-3": endpoint{}, - "me-south-1": endpoint{}, - "sa-east-1": endpoint{}, - "us-east-1": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, "us-east-1-fips": endpoint{ Hostname: "sts-fips.us-east-1.amazonaws.com", CredentialScope: credentialScope{ @@ -580,4 +580,3 @@ func TestSTSRegionalEndpoint_CNPartition(t *testing.T) { } } - diff --git a/aws/endpoints/v3model_test.go b/aws/endpoints/v3model_test.go index 35ad692a123..fc782a26717 100644 --- a/aws/endpoints/v3model_test.go +++ b/aws/endpoints/v3model_test.go @@ -538,4 +538,4 @@ func TestEndpointFor_RegionalFlag(t *testing.T) { }) } -} \ No newline at end of file +} From 9ade444a0328b8f42dd1ca63a4d555e5acd1f137 Mon Sep 17 00:00:00 2001 From: skotambkar Date: Tue, 8 Oct 2019 11:01:26 -0700 Subject: [PATCH 19/20] Adds suggested changes --- CHANGELOG_PENDING.md | 20 +++++++++++++++++++- aws/session/shared_config.go | 4 ++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index f5d0920ec44..df0fd9c4635 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,7 +2,25 @@ ### SDK Enhancements * `aws/endpoints`: Adds support for STS Regional Flags ([#2779](https://github.com/aws/aws-sdk-go/pull/2779)) - * Adds unit test cases for STS Regional flags to test STS endpoint resolver when flag is set to `legacy` or `regional` or is `unset`. + * STS will default to use the STS global endpoint for most regions when STS regional flag is not set to `regional`. + * The regions that default to the STS global endpoint are: + * ap-northeast-1 + * ap-south-1 + * ap-southeast-1 + * ap-southeast-2 + * aws-global + * ca-central-1 + * eu-central-1 + * eu-north-1 + * eu-west-1 + * eu-west-2 + * eu-west-3 + * sa-east-1 + * us-east-1 + * us-east-2 + * us-west-1 + * us-west-2 + * Adds unit test cases for STS Regional flags to test STS endpoint resolver when flag is set to `legacy` or `regional`. Also adds test to verify behavior when STS Regional Flag is not set. * Adds error handling when loading environment config from sharedConfig or envConfig. ### SDK Bugs diff --git a/aws/session/shared_config.go b/aws/session/shared_config.go index 2a23755c5a3..8574668960b 100644 --- a/aws/session/shared_config.go +++ b/aws/session/shared_config.go @@ -256,12 +256,12 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e updateString(&cfg.Region, section, regionKey) if v := section.String(stsRegionalEndpointSharedKey); len(v) != 0 { - STSRegionalEndpoint, err := endpoints.GetSTSRegionalEndpoint(v) + sre, err := endpoints.GetSTSRegionalEndpoint(v) if err != nil { return fmt.Errorf("failed to load %s from shared config, %s, %v", stsRegionalEndpointKey, file.Filename, err) } - cfg.STSRegionalEndpoint = STSRegionalEndpoint + cfg.STSRegionalEndpoint = sre } } From abc2db0fc8fe606c8cd05c6d72c35d832e4cfe38 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Wed, 23 Oct 2019 10:13:57 -0700 Subject: [PATCH 20/20] Update CHANGELOG_PENDING.md --- CHANGELOG_PENDING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index df0fd9c4635..621f7210248 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -2,8 +2,10 @@ ### SDK Enhancements * `aws/endpoints`: Adds support for STS Regional Flags ([#2779](https://github.com/aws/aws-sdk-go/pull/2779)) - * STS will default to use the STS global endpoint for most regions when STS regional flag is not set to `regional`. - * The regions that default to the STS global endpoint are: + * Implements STS regional flag, with support for `legacy` and `regional` options. Defaults to `legacy`. Legacy, will force all regions specified in aws/endpoints/sts_legacy_regions.go to resolve to the STS global endpoint, sts.amazonaws.com. This is the SDK's current behavior. + * When the flag's value is `regional` the SDK will resolve the endpoint based on the endpoints.json model. This allows STS to update their service's modeled endpoints to be regionalized for all regions. When `regional` turned on use `aws-global` as the region to use the global endpoint. + * `AWS_STS_REGIONAL_ENDPOINTS=regional` for environment, or `sts_regional_endpoints=regional` in shared config file. + * The regions the SDK defaults to the STS global endpoint in `legacy` mode are: * ap-northeast-1 * ap-south-1 * ap-southeast-1 @@ -20,7 +22,5 @@ * us-east-2 * us-west-1 * us-west-2 - * Adds unit test cases for STS Regional flags to test STS endpoint resolver when flag is set to `legacy` or `regional`. Also adds test to verify behavior when STS Regional Flag is not set. - * Adds error handling when loading environment config from sharedConfig or envConfig. ### SDK Bugs