diff --git a/client/helpers.go b/client/helpers.go index 3e18dece9..cc65f6600 100644 --- a/client/helpers.go +++ b/client/helpers.go @@ -42,7 +42,8 @@ type AwsPartition struct { } type SupportedServiceRegionsData struct { - Partitions map[string]AwsPartition `json:"partitions"` + Partitions map[string]AwsPartition `json:"partitions"` + regionVsPartition map[string]string } func readSupportedServiceRegions() *SupportedServiceRegionsData { @@ -58,12 +59,22 @@ func readSupportedServiceRegions() *SupportedServiceRegionsData { if _, err := f.Read(data); err != nil { return nil } - var result *SupportedServiceRegionsData - err = json.Unmarshal(data, &result) - if err != nil { + + var result SupportedServiceRegionsData + if err := json.Unmarshal(data, &result); err != nil { return nil } - return result + + result.regionVsPartition = make(map[string]string) + for _, p := range result.Partitions { + for _, svc := range p.Services { + for reg := range svc.Regions { + result.regionVsPartition[reg] = p.Id + } + } + } + + return &result } func isSupportedServiceForRegion(service string, region string) bool { @@ -79,7 +90,8 @@ func isSupportedServiceForRegion(service string, region string) bool { return false } - currentPartition := supportedServiceRegion.Partitions[defaultPartition] + prt, _ := regionsPartition(region) + currentPartition := supportedServiceRegion.Partitions[prt] if currentPartition.Services[service] == nil { return false @@ -107,17 +119,29 @@ func getAvailableRegions() (map[string]bool, error) { return nil, fmt.Errorf("could not found any AWS partitions") } - currentPartition := supportedServiceRegion.Partitions[defaultPartition] - - for _, service := range currentPartition.Services { - for region := range service.Regions { - regionsSet[region] = true + for _, prt := range supportedServiceRegion.Partitions { + for _, service := range prt.Services { + for region := range service.Regions { + regionsSet[region] = true + } } } return regionsSet, nil } +func regionsPartition(region string) (string, bool) { + readOnce.Do(func() { + supportedServiceRegion = readSupportedServiceRegions() + }) + + prt, ok := supportedServiceRegion.regionVsPartition[region] + if !ok { + return defaultPartition, false + } + return prt, true +} + func IgnoreAccessDeniedServiceDisabled(err error) bool { var ae smithy.APIError if errors.As(err, &ae) { @@ -162,9 +186,10 @@ func GenerateResourceARN(service, resourceType, resourceID, region, accountID st resource = fmt.Sprintf("%s/%s", resourceType, resourceID) } + p, _ := regionsPartition(region) + return arn.ARN{ - // TODO: Make this configurable in the future - Partition: "aws", + Partition: p, Service: service, Region: region, AccountID: accountID, @@ -201,8 +226,9 @@ const ( // MakeARN creates an ARN using supplied service name, account id, region name and resource id parts. // Resource id parts are concatenated using forward slash (/). func MakeARN(service AWSService, accountID, region string, idParts ...string) string { + p, _ := regionsPartition(region) return arn.ARN{ - Partition: "aws", + Partition: p, Service: string(service), Region: region, AccountID: accountID, diff --git a/client/helpers_test.go b/client/helpers_test.go index 547313946..ca1e0d191 100644 --- a/client/helpers_test.go +++ b/client/helpers_test.go @@ -70,6 +70,33 @@ func TestResolveARN(t *testing.T) { } } +func TestMakeARN(t *testing.T) { + cases := []struct { + service AWSService + region string + idParts []string + expected string + }{ + { + service: S3Service, + region: "us-east-1", + idParts: []string{"my-bucket"}, + expected: `arn:aws:s3:us-east-1:12345:my-bucket`, + }, + { + service: S3Service, + region: "cn-north-1", + //idParts: []string{"my-bucket"}, + idParts: []string{"我的桶"}, + expected: `arn:aws-cn:s3:cn-north-1:12345:我的桶`, + }, + } + for _, tc := range cases { + res := MakeARN(tc.service, "12345", tc.region, tc.idParts...) + assert.Equal(t, tc.expected, res) + } +} + func TestTagsToMap(t *testing.T) { type randomType struct { Key string