diff --git a/go.mod b/go.mod index 93bc77ee8..73e146a00 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/alecthomas/kingpin/v2 v2.4.0 github.com/aliyun/alibaba-cloud-sdk-go v1.62.771 github.com/ans-group/sdk-go v1.17.0 - github.com/aws/aws-sdk-go v1.54.4 + github.com/aws/aws-sdk-go v1.54.11 github.com/bodgit/tsig v1.2.2 github.com/cenkalti/backoff/v4 v4.3.0 github.com/civo/civogo v0.3.70 diff --git a/go.sum b/go.sum index 8731741ed..9c0559ab6 100644 --- a/go.sum +++ b/go.sum @@ -154,6 +154,8 @@ github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.54.4 h1:xZga3fPu7uxVgh83DIaQlb7r0cixFx1xKiiROTWAhpU= github.com/aws/aws-sdk-go v1.54.4/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.54.11 h1:Zxuv/R+IVS0B66yz4uezhxH9FN9/G2nbxejYqAMFjxk= +github.com/aws/aws-sdk-go v1.54.11/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 8e13d290f..658e27bcc 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -24,6 +24,7 @@ import ( "strconv" "strings" "time" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -403,6 +404,38 @@ func wildcardUnescape(s string) string { return strings.Replace(s, "\\052", "*", 1) } +// See https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DomainNameFormat.html +// convertOctalToAscii decodes inputs that contain octal escape sequences into their original ASCII characters. +// The function returns converted string where any octal escape sequences have been replaced with their corresponding ASCII characters. +func convertOctalToAscii(input string) string { + if !containsOctalSequence(input) { + return input + } + var result strings.Builder + for i := 0; i < len(input); i++ { + if input[i] == '\\' && i+3 < len(input) { + octalStr := input[i+1 : i+4] + if octal, err := strconv.ParseInt(octalStr, 8, 8); err == nil { + result.WriteByte(byte(octal)) + i += 3 // Skip the next 3 characters (the octal code) + } else { + result.WriteByte(input[i]) + } + } else { + result.WriteByte(input[i]) + } + } + return result.String() +} + +// validateDomainName checks if the domain name contains valid octal escape sequences. +func containsOctalSequence(domain string) bool { + // Pattern to match valid octal escape sequences + octalEscapePattern := `\\[0-3][0-7]{2}` + octalEscapeRegex := regexp.MustCompile(octalEscapePattern) + return octalEscapeRegex.MatchString(domain) +} + // Records returns the list of records in a given hosted zone. func (p *AWSProvider) Records(ctx context.Context) (endpoints []*endpoint.Endpoint, _ error) { zones, err := p.zones(ctx) @@ -433,8 +466,8 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*profiledZon for idx, rr := range r.ResourceRecords { targets[idx] = aws.StringValue(rr.Value) } - - ep := endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...) + escaped := convertOctalToAscii(wildcardUnescape(aws.StringValue(r.Name))) + ep := endpoint.NewEndpointWithTTL(escaped, aws.StringValue(r.Type), ttl, targets...) if aws.StringValue(r.Type) == endpoint.RecordTypeCNAME { ep = ep.WithProviderSpecific(providerSpecificAlias, "false") } @@ -583,6 +616,7 @@ func (p *AWSProvider) GetDomainFilter() endpoint.DomainFilter { // ApplyChanges applies a given set of changes in a given zone. func (p *AWSProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { + fmt.Println("586 ApplyChanges", changes) zones, err := p.zones(ctx) if err != nil { return provider.NewSoftError(fmt.Errorf("failed to list zones, not applying changes: %w", err))