From 9aaebc0b721536256040ccfb7cf51555c9c2ecc6 Mon Sep 17 00:00:00 2001 From: Kemal Hadimli Date: Wed, 4 May 2022 11:02:11 +0100 Subject: [PATCH 1/3] feat: Support AWS partitions --- client/helpers.go | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/client/helpers.go b/client/helpers.go index 3e18dece9..4a8edf838 100644 --- a/client/helpers.go +++ b/client/helpers.go @@ -45,6 +45,18 @@ type SupportedServiceRegionsData struct { Partitions map[string]AwsPartition `json:"partitions"` } +func (s *SupportedServiceRegionsData) RegionsPartition(region string) (string, bool) { + for _, p := range s.Partitions { + for _, svc := range p.Services { + if _, ok := svc.Regions[region]; ok { + return p.Id, true + } + } + } + + return defaultPartition, false +} + func readSupportedServiceRegions() *SupportedServiceRegionsData { f, err := supportedServiceRegionFile.Open(PartitionServiceRegionFile) if err != nil { @@ -79,7 +91,8 @@ func isSupportedServiceForRegion(service string, region string) bool { return false } - currentPartition := supportedServiceRegion.Partitions[defaultPartition] + prt, _ := supportedServiceRegion.RegionsPartition(region) + currentPartition := supportedServiceRegion.Partitions[prt] if currentPartition.Services[service] == nil { return false @@ -107,11 +120,11 @@ 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 + } } } @@ -162,9 +175,10 @@ func GenerateResourceARN(service, resourceType, resourceID, region, accountID st resource = fmt.Sprintf("%s/%s", resourceType, resourceID) } + p, _ := supportedServiceRegion.RegionsPartition(region) + return arn.ARN{ - // TODO: Make this configurable in the future - Partition: "aws", + Partition: p, Service: service, Region: region, AccountID: accountID, @@ -201,8 +215,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, _ := supportedServiceRegion.RegionsPartition(region) return arn.ARN{ - Partition: "aws", + Partition: p, Service: string(service), Region: region, AccountID: accountID, From a6db3beac808566f9ea60bb8468a454941de4234 Mon Sep 17 00:00:00 2001 From: Kemal Hadimli Date: Wed, 4 May 2022 11:33:04 +0100 Subject: [PATCH 2/3] Fix --- client/helpers.go | 51 ++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/client/helpers.go b/client/helpers.go index 4a8edf838..cc65f6600 100644 --- a/client/helpers.go +++ b/client/helpers.go @@ -42,19 +42,8 @@ type AwsPartition struct { } type SupportedServiceRegionsData struct { - Partitions map[string]AwsPartition `json:"partitions"` -} - -func (s *SupportedServiceRegionsData) RegionsPartition(region string) (string, bool) { - for _, p := range s.Partitions { - for _, svc := range p.Services { - if _, ok := svc.Regions[region]; ok { - return p.Id, true - } - } - } - - return defaultPartition, false + Partitions map[string]AwsPartition `json:"partitions"` + regionVsPartition map[string]string } func readSupportedServiceRegions() *SupportedServiceRegionsData { @@ -70,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 { @@ -91,7 +90,7 @@ func isSupportedServiceForRegion(service string, region string) bool { return false } - prt, _ := supportedServiceRegion.RegionsPartition(region) + prt, _ := regionsPartition(region) currentPartition := supportedServiceRegion.Partitions[prt] if currentPartition.Services[service] == nil { @@ -131,6 +130,18 @@ func getAvailableRegions() (map[string]bool, error) { 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) { @@ -175,7 +186,7 @@ func GenerateResourceARN(service, resourceType, resourceID, region, accountID st resource = fmt.Sprintf("%s/%s", resourceType, resourceID) } - p, _ := supportedServiceRegion.RegionsPartition(region) + p, _ := regionsPartition(region) return arn.ARN{ Partition: p, @@ -215,7 +226,7 @@ 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, _ := supportedServiceRegion.RegionsPartition(region) + p, _ := regionsPartition(region) return arn.ARN{ Partition: p, Service: string(service), From 8ba91d0db79ac45b5acc3f8886b843be0af9882d Mon Sep 17 00:00:00 2001 From: Kemal Hadimli Date: Thu, 5 May 2022 09:57:22 +0100 Subject: [PATCH 3/3] Add arn maker test --- client/helpers_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) 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