Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

Commit

Permalink
feat/ignore unsupported regions errors (#214)
Browse files Browse the repository at this point in the history
* non supported regions errors will be ignored

Co-authored-by: Ron <[email protected]>
  • Loading branch information
amanenk and roneli authored Oct 21, 2021
1 parent 4ee30e1 commit 4ab7f66
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions client/helpers.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package client

import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"regexp"
"strings"
"sync"

"github.com/aws/aws-sdk-go-v2/aws/arn"
"github.com/aws/smithy-go"
Expand All @@ -12,7 +17,91 @@ import (
//log-group:([a-zA-Z0-9/]+):
var GroupNameRegex = regexp.MustCompile("arn:aws:logs:[a-z0-9-]+:[0-9]+:log-group:([a-zA-Z0-9-/]+):")

type SupportedServicesData struct {
Prices []struct {
Attributes struct {
Region string `json:"aws:region"`
Service string `json:"aws:serviceName"`
} `json:"attributes"`
Id string `json:"id"`
} `json:"prices"`
}

// supportedServices map of the supported service-regions
var supportedServices map[string]map[string]struct{}
var getSupportedServices sync.Once

// apiErrorServiceNames stores api subdomains and service names for error decoding
var apiErrorServiceNames = map[string]string{
"mq": "Amazon MQ",
"cognito-identity": "Amazon Cognito",
"cognito-idp": "Amazon Cognito",
"ec2": "Amazon Elastic Compute Cloud (EC2)",
}

const supportedServicesLink = "https://api.regional-table.region-services.aws.a2z.com/index.json"

// downloadSupportedResourcesForRegions gets the data about AWS services and regions they are available in
func downloadSupportedResourcesForRegions() (map[string]map[string]struct{}, error) {
req, err := http.NewRequest(http.MethodGet, supportedServicesLink, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get aws supported resources for region, status code: %d", resp.StatusCode)
}

var data SupportedServicesData
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}

m := make(map[string]map[string]struct{})
for _, p := range data.Prices {
if _, ok := m[p.Attributes.Service]; !ok {
m[p.Attributes.Service] = make(map[string]struct{})
}
m[p.Attributes.Service][p.Attributes.Region] = struct{}{}
}

return m, nil
}

// ignoreUnsupportedResourceForRegionError returns true request was sent to a service that does not exist in specified region
func ignoreUnsupportedResourceForRegionError(err error) bool {
getSupportedServices.Do(func() {
supportedServices, _ = downloadSupportedResourcesForRegions()
})
var dnsErr *net.DNSError
if supportedServices != nil && errors.As(err, &dnsErr) && dnsErr.IsNotFound {
parts := strings.Split(dnsErr.Name, ".")
if len(parts) < 2 {
// usual aws domain has more than 2 parts
return false
}
apiService, ok := apiErrorServiceNames[parts[0]]
if !ok {
return false
}
region := parts[1]

_, ok = supportedServices[apiService][region]
// if service-region combination is in the map than service is supported and error should not be ignored
return ok
}
return true
}

func IgnoreAccessDeniedServiceDisabled(err error) bool {
if ignoreUnsupportedResourceForRegionError(err) {
return true
}
var ae smithy.APIError
if errors.As(err, &ae) {
switch ae.ErrorCode() {
Expand Down

0 comments on commit 4ab7f66

Please sign in to comment.