From ff70a0e44e9ebce01630dd30e4e4656f08f0712b Mon Sep 17 00:00:00 2001 From: Julien Le Goff Date: Thu, 23 Feb 2023 12:06:00 +0100 Subject: [PATCH 1/2] Updated and fixed tests using current PowerDNS version --- client.go | 3 +-- client_test.go | 6 +++--- docker-compose.yml | 22 ++-------------------- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/client.go b/client.go index 199facc..3b7e2fe 100644 --- a/client.go +++ b/client.go @@ -114,8 +114,7 @@ func removeRecords(rRSet zones.ResourceRecordSet, culls []libdns.Record) zones.R recs := rRSet.Records for i := len(recs) - 1; i >= 0; i-- { if recs[i].Content == item { - copy(recs[i:], recs[:i+1]) - recs = recs[:len(recs)-1] + recs = append(recs[:i], recs[i+1:]...) } } return recs diff --git a/client_test.go b/client_test.go index 44fb9bd..abd0af8 100644 --- a/client_test.go +++ b/client_test.go @@ -222,10 +222,10 @@ func TestPDNSClient(t *testing.T) { { Name: "2", Type: "A", - Value: "127.0.0.7", + Value: "127.0.0.5", }, }, - want: []string{"1:127.0.0.1", "1:127.0.0.2", "1:127.0.0.3", "2:127.0.0.4", "2:127.0.0.5", "2:127.0.0.6"}, + want: []string{"1:127.0.0.1", "1:127.0.0.2", "1:127.0.0.3", "2:127.0.0.4", "2:127.0.0.6", "2:127.0.0.7"}, }, { name: "Test Append and Add Zone", @@ -245,7 +245,7 @@ func TestPDNSClient(t *testing.T) { }, }, want: []string{"1:127.0.0.1", "1:127.0.0.2", "1:127.0.0.3", - "2:127.0.0.4", "2:127.0.0.5", "2:127.0.0.6", "2:127.0.0.8", + "2:127.0.0.4", "2:127.0.0.6", "2:127.0.0.7", "2:127.0.0.8", "3:127.0.0.9"}, }, { diff --git a/docker-compose.yml b/docker-compose.yml index 5d1d8f5..70c2faf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,30 +1,12 @@ version: "3" services: - mysql: - image: mariadb:10.6 - environment: - MYSQL_ROOT_PASSWORD: immelting - MYSQL_USER: powerdns - MYSQL_PASSWORD: secret - MYSQL_DATABASE: powerdns - volumes: - - database:/var/lib/mysql - networks: - - backend powerdns: - image: psitrax/powerdns - environment: - MYSQL_HOST: mysql - MYSQL_USER: powerdns - MYSQL_PASS: secret - MYSQL_DB: powerdns + image: powerdns/pdns-auth-47 networks: - backend volumes: - - ./.docker/pdns:/etc/pdns/conf.d + - ./.docker/pdns:/etc/powerdns/pdns.d ports: - 8081:8081 -volumes: - database: {} networks: backend: {} From 74685541d8cbc7da3445361dd531abddb5639528 Mon Sep 17 00:00:00 2001 From: Julien Le Goff Date: Thu, 23 Feb 2023 12:33:58 +0100 Subject: [PATCH 2/2] Added support for MX and SRV records --- client.go | 37 ++++++++- client_test.go | 200 ++++++++++++++++++++++++++++++++++++++++++++++++- provider.go | 4 +- 3 files changed, 234 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index 3b7e2fe..47fb492 100644 --- a/client.go +++ b/client.go @@ -3,12 +3,14 @@ package powerdns import ( "context" "fmt" - "github.com/libdns/powerdns/txtsanitize" "io" "io/ioutil" + "regexp" + "strconv" "strings" "github.com/libdns/libdns" + "github.com/libdns/powerdns/txtsanitize" pdns "github.com/mittwald/go-powerdns" "github.com/mittwald/go-powerdns/apis/zones" ) @@ -74,7 +76,7 @@ func mergeRRecs(fullZone *zones.Zone, records []libdns.Record) ([]zones.Resource for _, rec := range recs { if !dupes[rec.Value] { rr.Records = append(rr.Records, zones.Record{ - Content: rec.Value, + Content: formatPdnsRecordContent(rec), }) dupes[rec.Value] = true } @@ -120,7 +122,7 @@ func removeRecords(rRSet zones.ResourceRecordSet, culls []libdns.Record) zones.R return recs } for _, c := range culls { - rRSet.Records = deleteItem(c.Value) + rRSet.Records = deleteItem(formatPdnsRecordContent(c)) } return rRSet } @@ -140,7 +142,7 @@ func convertLDHash(inHash map[string][]libdns.Record) []zones.ResourceRecordSet } for _, rec := range recs { rr.Records = append(rr.Records, zones.Record{ - Content: rec.Value, + Content: formatPdnsRecordContent(rec), }) } rrsets = append(rrsets, rr) @@ -211,3 +213,30 @@ func convertNamesToAbsolute(zone string, records []libdns.Record) []libdns.Recor } return out } + +func formatPdnsRecordContent(record libdns.Record) string { + switch record.Type { + case "MX", "SRV": + return fmt.Sprintf("%d %s", record.Priority, record.Value) + } + + return record.Value +} + +func getPriorityFromPdnsRecordContent(content string) int { + priority, err := strconv.Atoi(strings.Split(content, " ")[0]) + + if err != nil { + return 0 + } + + return priority +} + +func getValueFromPdnsRecordContent(content string) string { + if match, _ := regexp.MatchString("^\\d+ ", content); match { + return strings.Join(strings.Split(content, " ")[1:], " ") + } + + return content +} diff --git a/client_test.go b/client_test.go index abd0af8..feeb18a 100644 --- a/client_test.go +++ b/client_test.go @@ -91,6 +91,26 @@ func TestPDNSClient(t *testing.T) { }, }, }, + { + Name: "example.org.", + Type: "MX", + TTL: 60, + Records: []zones.Record{ + { + Content: "10 mx1.example.org.", + }, + }, + }, + { + Name: "_https._tcp.example.org.", + Type: "SRV", + TTL: 60, + Records: []zones.Record{ + { + Content: "100 1 443 https.example.org.", + }, + }, + }, }, Serial: 1, Nameservers: []string{ @@ -213,6 +233,39 @@ func TestPDNSClient(t *testing.T) { `1:"ç is equal to \195\167"`, }, }, + { + name: "Test Delete Zone TXT record with embedded quotes", + operation: "delete", + zone: "example.org.", + Type: "TXT", + records: []libdns.Record{ + { + Name: "1", + Type: "TXT", + Value: `This is some weird text that "has embedded quoting"`, + }, + }, + want: []string{`1:"This is text"`, `1:"This is also some text"`, + `1:"This is some weird text that isn't quoted"`, + `1:"ç is equal to \195\167"`, + }, + }, + { + name: "Test Delete Zone TXT record with unicode", + operation: "delete", + zone: "example.org.", + Type: "TXT", + records: []libdns.Record{ + { + Name: "1", + Type: "TXT", + Value: `ç is equal to \195\167`, + }, + }, + want: []string{`1:"This is text"`, `1:"This is also some text"`, + `1:"This is some weird text that isn't quoted"`, + }, + }, { name: "Test Delete Zone", operation: "delete", @@ -267,6 +320,145 @@ func TestPDNSClient(t *testing.T) { }, want: []string{"1:127.0.0.1", "2:127.0.0.1", "3:127.0.0.9"}, }, + { + name: "Test Get Zone MX records", + operation: "records", + zone: "example.org.", + records: nil, + Type: "MX", + want: []string{":mx1.example.org.:10"}, + }, + { + name: "Test Append Zone MX record", + operation: "append", + zone: "example.org.", + Type: "MX", + records: []libdns.Record{ + { + Name: "", + Type: "MX", + Value: "mx2.example.org.", + Priority: 20, + }, + { + Name: "", + Type: "MX", + Value: "mx3.example.org.", + Priority: 30, + }, + }, + want: []string{ + ":mx1.example.org.:10", + ":mx2.example.org.:20", + ":mx3.example.org.:30", + }, + }, + { + name: "Test Delete Zone MX record", + operation: "delete", + zone: "example.org.", + Type: "MX", + records: []libdns.Record{ + { + Name: "", + Type: "MX", + Value: "mx2.example.org.", + Priority: 20, + }, + }, + want: []string{ + ":mx1.example.org.:10", + ":mx3.example.org.:30", + }, + }, + { + name: "Test Set Zone MX record", + operation: "set", + zone: "example.org.", + Type: "MX", + records: []libdns.Record{ + { + Name: "", + Type: "MX", + Value: "mx2.example.org.", + Priority: 20, + }, + }, + want: []string{ + ":mx2.example.org.:20", + }, + }, + { + name: "Test Get Zone SRV records", + operation: "records", + zone: "example.org.", + records: nil, + Type: "SRV", + want: []string{ + "_https._tcp:1 443 https.example.org.:100", + }, + }, + { + name: "Test Append Zone SRV record", + operation: "append", + zone: "example.org.", + Type: "SRV", + records: []libdns.Record{ + { + Name: "_imaps._tcp", + Type: "SRV", + Value: "1 993 imaps.example.org.", + Priority: 200, + }, + { + Name: "_pop3s._tcp", + Type: "SRV", + Value: "1 995 pop3s.example.org.", + Priority: 300, + }, + }, + want: []string{ + "_https._tcp:1 443 https.example.org.:100", + "_imaps._tcp:1 993 imaps.example.org.:200", + "_pop3s._tcp:1 995 pop3s.example.org.:300", + }, + }, + { + name: "Test Delete Zone SRV record", + operation: "delete", + zone: "example.org.", + Type: "SRV", + records: []libdns.Record{ + { + Name: "_imaps._tcp", + Type: "SRV", + Value: "1 993 imaps.example.org.", + Priority: 200, + }, + }, + want: []string{ + "_https._tcp:1 443 https.example.org.:100", + "_pop3s._tcp:1 995 pop3s.example.org.:300", + }, + }, + { + name: "Test Set Zone SRV record", + operation: "set", + zone: "example.org.", + Type: "SRV", + records: []libdns.Record{ + { + Name: "_https._tcp", + Type: "SRV", + Value: "1 8443 https-alt.example.org.", + Priority: 50, + }, + }, + want: []string{ + "_https._tcp:1 8443 https-alt.example.org.:50", + "_pop3s._tcp:1 995 pop3s.example.org.:300", + }, + }, } { t.Run(table.name, func(t *testing.T) { var err error @@ -297,7 +489,13 @@ func TestPDNSClient(t *testing.T) { if rr.Type != table.Type { continue } - have = append(have, fmt.Sprintf("%s:%s", rr.Name, rr.Value)) + + switch rr.Type { + case "MX", "SRV": + have = append(have, fmt.Sprintf("%s:%s:%d", rr.Name, rr.Value, rr.Priority)) + default: + have = append(have, fmt.Sprintf("%s:%s", rr.Name, rr.Value)) + } } sort.Strings(have) diff --git a/provider.go b/provider.go index 885749d..df153e2 100644 --- a/provider.go +++ b/provider.go @@ -51,9 +51,9 @@ func (p *Provider) GetRecords(ctx context.Context, zone string) ([]libdns.Record ID: prec.ID, Type: rec.Type, Name: libdns.RelativeName(rec.Name, zone), - Value: v.Content, + Value: getValueFromPdnsRecordContent(v.Content), TTL: time.Second * time.Duration(rec.TTL), - Priority: 0, + Priority: getPriorityFromPdnsRecordContent(v.Content), }) } }