Skip to content

Commit

Permalink
aws/endpoints: Fix SDK resolving endpoint without region
Browse files Browse the repository at this point in the history
Fixes the SDK's endpoint resolve incorrectly resolving endpoints for a
service when the region is empty. Also fixes the SDK attempting to
resolve a service when the service value is empty.

Related to: aws/aws-sdk-go#2911
  • Loading branch information
jasdel committed Oct 25, 2019
1 parent 88921a9 commit d1931a0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
17 changes: 15 additions & 2 deletions aws/endpoints/v3model.go
Expand Up @@ -74,16 +74,29 @@ func (p partition) canResolveEndpoint(service, region string, strictMatch bool)
return p.RegionRegex.MatchString(region)
}

func allowLegacyEmptyRegion(service string) bool {
legacy := map[string]struct{}{
"ec2metadata": {},
}

_, allowed := legacy[service]
return allowed
}

func (p partition) EndpointFor(service, region string, opts ResolveOptions) (resolved aws.Endpoint, err error) {
s, hasService := p.Services[service]
if !hasService && opts.StrictMatching {
if len(service) == 0 || (!hasService && opts.StrictMatching) {
// Only return error if the resolver will not fallback to creating
// endpoint based on service endpoint ID passed in.
return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services))
}

if len(region) == 0 && allowLegacyEmptyRegion(service) && len(s.PartitionEndpoint) != 0 {
region = s.PartitionEndpoint
}

e, hasEndpoint := s.endpointForRegion(region)
if !hasEndpoint && opts.StrictMatching {
if len(region) == 0 || (!hasEndpoint && opts.StrictMatching) {
return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints))
}

Expand Down
44 changes: 44 additions & 0 deletions aws/endpoints/v3model_test.go
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"reflect"
"regexp"
"strings"
"testing"
)

Expand Down Expand Up @@ -522,3 +523,46 @@ func TestResolveEndpoint_AwsGlobal(t *testing.T) {
t.Errorf("expect the signing name to be derived")
}
}

func TestEndpointFor_EmptyRegion(t *testing.T) {
cases := map[string]struct {
Service string
Region string
RealRegion string
ExpectErr string
}{
// Legacy services that previous accepted empty region
"ec2metadata": {Service: "ec2metadata", RealRegion: "aws-global"},

// Other services
"s3": {Service: "s3", Region: "us-east-1", RealRegion: "us-east-1"},
"s3 no region": {Service: "s3", ExpectErr: "could not resolve endpoint"},
}

for name, c := range cases {
t.Run(name, func(t *testing.T) {
actual, err := NewDefaultResolver().ResolveEndpoint(c.Service, c.Region)
if len(c.ExpectErr) != 0 {
if e, a := c.ExpectErr, err.Error(); !strings.Contains(a, e) {
t.Errorf("expect %q error in %q", e, a)
}
return
}
if err != nil {
t.Fatalf("expect no error got, %v", err)
}

expect, err := NewDefaultResolver().ResolveEndpoint(c.Service, c.RealRegion)
if err != nil {
t.Fatalf("failed to get endpoint for default resolver")
}
if e, a := expect.URL, actual.URL; e != a {
t.Errorf("expect %v URL, got %v", e, a)
}
if e, a := expect.SigningRegion, actual.SigningRegion; e != a {
t.Errorf("expect %v signing region, got %v", e, a)
}

})
}
}

0 comments on commit d1931a0

Please sign in to comment.