From f2090b6d1ed40bf167298f8f52d6e9afc05528e0 Mon Sep 17 00:00:00 2001 From: Daniel Muehlbachler-Pietrzykowski Date: Thu, 9 Nov 2023 08:07:41 +0100 Subject: [PATCH] feat: support arbitrary TXT records; fix #13 --- internal/adguard/provider.go | 27 +++++++++++++++++++-------- internal/adguard/provider_test.go | 9 +++++++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/internal/adguard/provider.go b/internal/adguard/provider.go index c40d5a8..fa58656 100644 --- a/internal/adguard/provider.go +++ b/internal/adguard/provider.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "regexp" "strings" log "github.com/sirupsen/logrus" @@ -179,7 +178,14 @@ func (p *Provider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) { func endpointSupported(e *endpoint.Endpoint) bool { // Adguard does not have any restriction, and we can allow all upstream/external-dns ones - return e.RecordType == endpoint.RecordTypeA || e.RecordType == endpoint.RecordTypeTXT || e.RecordType == endpoint.RecordTypeAAAA || e.RecordType == endpoint.RecordTypeCNAME || e.RecordType == endpoint.RecordTypeSRV || e.RecordType == endpoint.RecordTypeNS || e.RecordType == endpoint.RecordTypePTR || e.RecordType == endpoint.RecordTypeMX + return e.RecordType == endpoint.RecordTypeA || + e.RecordType == endpoint.RecordTypeTXT || + e.RecordType == endpoint.RecordTypeAAAA || + e.RecordType == endpoint.RecordTypeCNAME || + e.RecordType == endpoint.RecordTypeSRV || + e.RecordType == endpoint.RecordTypeNS || + e.RecordType == endpoint.RecordTypePTR || + e.RecordType == endpoint.RecordTypeMX } func deserializeToEndpoint(rule string) (*endpoint.Endpoint, error) { @@ -189,17 +195,22 @@ func deserializeToEndpoint(rule string) (*endpoint.Endpoint, error) { } // format: "||DNS.NAME^dnsrewrite=NOERROR;RECORD_TYPE;TARGET #MANAGED_BY_TEXT" - re := regexp.MustCompile(`[(||)(\^$);( #)]+`) - p := re.Split(rule, -1) - if len(p) != 6 { + p := strings.SplitN(rule, ";", 3) + if len(p) != 3 { return nil, fmt.Errorf("invalid rule: %s", rule) } + t := strings.TrimSuffix(p[2], fmt.Sprintf(" #%s", managedBy)) + dp := strings.SplitN(p[0], "^", 2) + if len(dp) != 2 { + return nil, fmt.Errorf("invalid rule: %s", rule) + } + d := strings.TrimPrefix(dp[0], "||") // see serializeToString for the format r := &endpoint.Endpoint{ - RecordType: p[3], - DNSName: p[1], - Targets: endpoint.Targets{p[4]}, + RecordType: p[1], + DNSName: d, + Targets: endpoint.Targets{t}, } return r, nil diff --git a/internal/adguard/provider_test.go b/internal/adguard/provider_test.go index f676b96..9e25635 100644 --- a/internal/adguard/provider_test.go +++ b/internal/adguard/provider_test.go @@ -152,6 +152,11 @@ func TestDeserializeToEndpoint(t *testing.T) { text: fmt.Sprintf("||domain.com^$dnsrewrite=NOERROR;TXT;external-dns-txt #%s", managedBy), endpoint: &endpoint.Endpoint{DNSName: "domain.com", RecordType: endpoint.RecordTypeTXT, Targets: []string{"external-dns-txt"}}, }, + { + name: "long TXT record", + text: fmt.Sprintf("||domain.com^$dnsrewrite=NOERROR;TXT;\"external-dns-txt; d=abc; v=...\" #%s", managedBy), + endpoint: &endpoint.Endpoint{DNSName: "domain.com", RecordType: endpoint.RecordTypeTXT, Targets: []string{"\"external-dns-txt; d=abc; v=...\""}}, + }, { name: "CNAME record", text: fmt.Sprintf("||domain.com^$dnsrewrite=NOERROR;CNAME;other.org #%s", managedBy), @@ -336,7 +341,7 @@ func TestRecords(t *testing.T) { domainFilter: endpoint.DomainFilter{}, filteringRules: getFilteringRules{ UserRules: []string{ - fmt.Sprintf("||domain.com^$dnsrewrite=NOERROR;A;1.1.1.1 whatever #%s", managedBy), + fmt.Sprintf("||domain.com$dnsrewrite=NOERROR;A;1.1.1.1 whatever #%s", managedBy), }, }, }, @@ -620,7 +625,7 @@ func TestApplyChanges(t *testing.T) { domainFilter: endpoint.DomainFilter{}, filteringRules: getFilteringRules{ UserRules: []string{ - fmt.Sprintf("||domain.com^$dnsrewrite=NOERROR;A;2.2.2.2 whatever #%s", managedBy), + fmt.Sprintf("||domain.com$dnsrewrite=NOERROR;A;2.2.2.2 whatever #%s", managedBy), }, }, changes: &plan.Changes{