From 0efdfb3488cb19267f5fb15b71a35a1e8012b4cd Mon Sep 17 00:00:00 2001 From: angeloxx Date: Sun, 25 Feb 2024 16:27:02 +0100 Subject: [PATCH 1/8] Initial support to PTR --- provider/rfc2136/rfc2136.go | 45 ++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index c0671c9948..f70d591c1c 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -177,6 +177,9 @@ OuterLoop: case dns.TypeNS: rrValues = []string{rr.(*dns.NS).Ns} rrType = "NS" + case dns.TypePTR: + rrValues = []string{rr.(*dns.PTR).Ptr} + rrType = "PTR" default: continue // Unhandled record type } @@ -247,6 +250,40 @@ func (r rfc2136Provider) List() ([]dns.RR, error) { return records, nil } +func (r rfc2136Provider) AddReverseRecord(ip string, hostname string) error { + changes := r.GenerateReverseRecord(ip, hostname) + return r.ApplyChanges(context.Background(), &plan.Changes{Create: changes}) +} + +func (r rfc2136Provider) RemoveReverseRecord(ip string, hostname string) error { + changes := r.GenerateReverseRecord(ip, hostname) + return r.ApplyChanges(context.Background(), &plan.Changes{Delete: changes}) +} + +func (r rfc2136Provider) GenerateReverseRecord(ip string, hostname string) []*endpoint.Endpoint { + // Find the zone for the PTR record + // zone := findMsgZone(&endpoint.Endpoint{DNSName: ip}, p.ptrZoneNames) + // Generate PTR notation record starting from the IP address + var records []*endpoint.Endpoint + + log.Debugf("Reverse zone is: %s %s", ip, dns.Fqdn(ip)) + reverseAddress, _ := dns.ReverseAddr(ip) + + // Create the PTR record + rr := fmt.Sprintf("%s %d %s %s", reverseAddress, r.minTTL, "PTR", hostname) + log.Infof("Adding RR: %s", rr) + + // PTR + records = append(records, &endpoint.Endpoint{ + DNSName: reverseAddress[:len(reverseAddress)-1], + RecordType: "PTR", + Targets: endpoint.Targets{hostname}, + }) + + return records + +} + // ApplyChanges applies a given set of changes in a given zone. func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { log.Debugf("ApplyChanges (Create: %d, UpdateOld: %d, UpdateNew: %d, Delete: %d)", len(changes.Create), len(changes.UpdateOld), len(changes.UpdateNew), len(changes.Delete)) @@ -271,8 +308,11 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes zone := findMsgZone(ep, r.zoneNames) r.krb5Realm = strings.ToUpper(zone) m[zone].SetUpdate(zone) - r.AddRecord(m[zone], ep) + + if ep.RecordType == "A" || ep.RecordType == "AAAA" { + r.AddReverseRecord(ep.Targets[0], ep.DNSName) + } } // only send if there are records available @@ -342,6 +382,9 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes m[zone].SetUpdate(zone) r.RemoveRecord(m[zone], ep) + if ep.RecordType == "A" || ep.RecordType == "AAAA" { + r.RemoveReverseRecord(ep.Targets[0], ep.DNSName) + } } // only send if there are records available From 5c01e953b43fdee5b25857ef329f7dc3caa25b2c Mon Sep 17 00:00:00 2001 From: angeloxx Date: Sun, 25 Feb 2024 17:55:57 +0100 Subject: [PATCH 2/8] Useless test removed, test with AD and sync mode --- provider/rfc2136/rfc2136.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index f70d591c1c..39428f51e3 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -269,10 +269,6 @@ func (r rfc2136Provider) GenerateReverseRecord(ip string, hostname string) []*en log.Debugf("Reverse zone is: %s %s", ip, dns.Fqdn(ip)) reverseAddress, _ := dns.ReverseAddr(ip) - // Create the PTR record - rr := fmt.Sprintf("%s %d %s %s", reverseAddress, r.minTTL, "PTR", hostname) - log.Infof("Adding RR: %s", rr) - // PTR records = append(records, &endpoint.Endpoint{ DNSName: reverseAddress[:len(reverseAddress)-1], From 940899b7583fa670ee57df9bc3aeecf39c55836f Mon Sep 17 00:00:00 2001 From: angeloxx Date: Sun, 25 Feb 2024 18:40:12 +0100 Subject: [PATCH 3/8] Add command line parameter and update helm --- docs/tutorials/rfc2136.md | 10 ++++++++++ main.go | 2 +- pkg/apis/externaldns/types.go | 2 ++ pkg/apis/externaldns/validation/validation_test.go | 1 + provider/rfc2136/rfc2136.go | 8 +++++--- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/rfc2136.md b/docs/tutorials/rfc2136.md index ca9ff4a61a..6a9d9f219d 100644 --- a/docs/tutorials/rfc2136.md +++ b/docs/tutorials/rfc2136.md @@ -132,6 +132,16 @@ A default TTL for all records can be set using the the flag with a time in secon There are other annotation that can affect the generation of DNS records, but these are beyond the scope of this tutorial and are covered in the main documentation. +### Generate reverse DNS records + +If you want to generate reverse DNS records for your services, you have to enable the functionality using the `--rfc2136-manageptr` +flag. You have also to add the zone to the list of zones managed by ExternalDNS via the `--rfc2136-zone` and `--domain-filter` flags. +An example of a valid configuration is the following: + +```--domain-filter=157.168.192.in-addr.arpa --rfc2136-zone=157.168.192.in-addr.arpa``` + +PTR record tracking is managed by the A/AAAA record so you can't create PTR records for already generated A/AAAA records. + ### Test with external-dns installed on local machine (optional) You may install external-dns and test on a local machine by running: ```external-dns --txt-owner-id k8s --provider rfc2136 --rfc2136-host=192.168.0.1 --rfc2136-port=53 --rfc2136-zone=k8s.example.org --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= --rfc2136-tsig-secret-alg=hmac-sha256 --rfc2136-tsig-keyname=externaldns-key --rfc2136-tsig-axfr --source ingress --once --domain-filter=k8s.example.org --dry-run``` diff --git a/main.go b/main.go index f5c165339e..b12207a700 100644 --- a/main.go +++ b/main.go @@ -371,7 +371,7 @@ func main() { p, err = oci.NewOCIProvider(*config, domainFilter, zoneIDFilter, cfg.OCIZoneScope, cfg.DryRun) } case "rfc2136": - p, err = rfc2136.NewRfc2136Provider(cfg.RFC2136Host, cfg.RFC2136Port, cfg.RFC2136Zone, cfg.RFC2136Insecure, cfg.RFC2136TSIGKeyName, cfg.RFC2136TSIGSecret, cfg.RFC2136TSIGSecretAlg, cfg.RFC2136TAXFR, domainFilter, cfg.DryRun, cfg.RFC2136MinTTL, cfg.RFC2136GSSTSIG, cfg.RFC2136KerberosUsername, cfg.RFC2136KerberosPassword, cfg.RFC2136KerberosRealm, cfg.RFC2136BatchChangeSize, nil) + p, err = rfc2136.NewRfc2136Provider(cfg.RFC2136Host, cfg.RFC2136Port, cfg.RFC2136Zone, cfg.RFC2136Insecure, cfg.RFC2136TSIGKeyName, cfg.RFC2136TSIGSecret, cfg.RFC2136TSIGSecretAlg, cfg.RFC2136TAXFR, domainFilter, cfg.DryRun, cfg.RFC2136MinTTL, cfg.RFC2136ManagePTR, cfg.RFC2136GSSTSIG, cfg.RFC2136KerberosUsername, cfg.RFC2136KerberosPassword, cfg.RFC2136KerberosRealm, cfg.RFC2136BatchChangeSize, nil) case "ns1": p, err = ns1.NewNS1Provider( ns1.NS1Config{ diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index a7e80476fd..5656e0ef99 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -183,6 +183,7 @@ type Config struct { RFC2136Zone []string RFC2136Insecure bool RFC2136GSSTSIG bool + RFC2136ManagePTR bool RFC2136KerberosRealm string RFC2136KerberosUsername string RFC2136KerberosPassword string `secure:"yes"` @@ -579,6 +580,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("rfc2136-host", "When using the RFC2136 provider, specify the host of the DNS server").Default(defaultConfig.RFC2136Host).StringVar(&cfg.RFC2136Host) app.Flag("rfc2136-port", "When using the RFC2136 provider, specify the port of the DNS server").Default(strconv.Itoa(defaultConfig.RFC2136Port)).IntVar(&cfg.RFC2136Port) app.Flag("rfc2136-zone", "When using the RFC2136 provider, specify zone entries of the DNS server to use").StringsVar(&cfg.RFC2136Zone) + app.Flag("rfc2136-manageptr", "When using the RFC2136 provider, enable PTR management").Default(strconv.FormatBool(defaultConfig.RFC2136ManagePTR)).BoolVar(&cfg.RFC2136ManagePTR) app.Flag("rfc2136-insecure", "When using the RFC2136 provider, specify whether to attach TSIG or not (default: false, requires --rfc2136-tsig-keyname and rfc2136-tsig-secret)").Default(strconv.FormatBool(defaultConfig.RFC2136Insecure)).BoolVar(&cfg.RFC2136Insecure) app.Flag("rfc2136-tsig-keyname", "When using the RFC2136 provider, specify the TSIG key to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGKeyName).StringVar(&cfg.RFC2136TSIGKeyName) app.Flag("rfc2136-tsig-secret", "When using the RFC2136 provider, specify the TSIG (base64) value to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGSecret).StringVar(&cfg.RFC2136TSIGSecret) diff --git a/pkg/apis/externaldns/validation/validation_test.go b/pkg/apis/externaldns/validation/validation_test.go index 8573aa6cf1..1209afd2c7 100644 --- a/pkg/apis/externaldns/validation/validation_test.go +++ b/pkg/apis/externaldns/validation/validation_test.go @@ -132,6 +132,7 @@ func TestValidateBadRfc2136Config(t *testing.T) { cfg.Sources = []string{"test-source"} cfg.Provider = "rfc2136" cfg.RFC2136MinTTL = -1 + cfg.ManagePTR = false cfg.RFC2136BatchChangeSize = 50 err := ValidateConfig(cfg) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index 39428f51e3..3e89d33bdf 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -54,6 +54,7 @@ type rfc2136Provider struct { axfr bool minTTL time.Duration batchChangeSize int + managePTR bool // options specific to rfc3645 gss-tsig support gssTsig bool @@ -82,7 +83,7 @@ type rfc2136Actions interface { } // NewRfc2136Provider is a factory function for OpenStack rfc2136 providers -func NewRfc2136Provider(host string, port int, zoneNames []string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, gssTsig bool, krb5Username string, krb5Password string, krb5Realm string, batchChangeSize int, actions rfc2136Actions) (provider.Provider, error) { +func NewRfc2136Provider(host string, port int, zoneNames []string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, managePTR bool, gssTsig bool, krb5Username string, krb5Password string, krb5Realm string, batchChangeSize int, actions rfc2136Actions) (provider.Provider, error) { secretAlgChecked, ok := tsigAlgs[secretAlg] if !ok && !insecure && !gssTsig { return nil, errors.Errorf("%s is not supported TSIG algorithm", secretAlg) @@ -103,6 +104,7 @@ func NewRfc2136Provider(host string, port int, zoneNames []string, insecure bool zoneNames: zoneNames, insecure: insecure, gssTsig: gssTsig, + managePTR: managePTR, krb5Username: krb5Username, krb5Password: krb5Password, krb5Realm: strings.ToUpper(krb5Realm), @@ -306,7 +308,7 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes m[zone].SetUpdate(zone) r.AddRecord(m[zone], ep) - if ep.RecordType == "A" || ep.RecordType == "AAAA" { + if r.managePTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { r.AddReverseRecord(ep.Targets[0], ep.DNSName) } } @@ -378,7 +380,7 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes m[zone].SetUpdate(zone) r.RemoveRecord(m[zone], ep) - if ep.RecordType == "A" || ep.RecordType == "AAAA" { + if r.managePTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { r.RemoveReverseRecord(ep.Targets[0], ep.DNSName) } } From b083e34dfb8b27a699108294a6a10c806f73c27f Mon Sep 17 00:00:00 2001 From: angeloxx Date: Sun, 25 Feb 2024 18:50:35 +0100 Subject: [PATCH 4/8] Rename option with --rfc2136-create-ptr, similar to infoblox option --- docs/tutorials/rfc2136.md | 2 +- main.go | 2 +- pkg/apis/externaldns/types.go | 4 ++-- pkg/apis/externaldns/validation/validation_test.go | 2 +- provider/rfc2136/rfc2136.go | 10 +++++----- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/tutorials/rfc2136.md b/docs/tutorials/rfc2136.md index 6a9d9f219d..7442881f4b 100644 --- a/docs/tutorials/rfc2136.md +++ b/docs/tutorials/rfc2136.md @@ -134,7 +134,7 @@ tutorial and are covered in the main documentation. ### Generate reverse DNS records -If you want to generate reverse DNS records for your services, you have to enable the functionality using the `--rfc2136-manageptr` +If you want to generate reverse DNS records for your services, you have to enable the functionality using the `--rfc2136-create-ptr` flag. You have also to add the zone to the list of zones managed by ExternalDNS via the `--rfc2136-zone` and `--domain-filter` flags. An example of a valid configuration is the following: diff --git a/main.go b/main.go index b12207a700..d914dbf432 100644 --- a/main.go +++ b/main.go @@ -371,7 +371,7 @@ func main() { p, err = oci.NewOCIProvider(*config, domainFilter, zoneIDFilter, cfg.OCIZoneScope, cfg.DryRun) } case "rfc2136": - p, err = rfc2136.NewRfc2136Provider(cfg.RFC2136Host, cfg.RFC2136Port, cfg.RFC2136Zone, cfg.RFC2136Insecure, cfg.RFC2136TSIGKeyName, cfg.RFC2136TSIGSecret, cfg.RFC2136TSIGSecretAlg, cfg.RFC2136TAXFR, domainFilter, cfg.DryRun, cfg.RFC2136MinTTL, cfg.RFC2136ManagePTR, cfg.RFC2136GSSTSIG, cfg.RFC2136KerberosUsername, cfg.RFC2136KerberosPassword, cfg.RFC2136KerberosRealm, cfg.RFC2136BatchChangeSize, nil) + p, err = rfc2136.NewRfc2136Provider(cfg.RFC2136Host, cfg.RFC2136Port, cfg.RFC2136Zone, cfg.RFC2136Insecure, cfg.RFC2136TSIGKeyName, cfg.RFC2136TSIGSecret, cfg.RFC2136TSIGSecretAlg, cfg.RFC2136TAXFR, domainFilter, cfg.DryRun, cfg.RFC2136MinTTL, cfg.RFC2136CreatePTR, cfg.RFC2136GSSTSIG, cfg.RFC2136KerberosUsername, cfg.RFC2136KerberosPassword, cfg.RFC2136KerberosRealm, cfg.RFC2136BatchChangeSize, nil) case "ns1": p, err = ns1.NewNS1Provider( ns1.NS1Config{ diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 5656e0ef99..759f97def2 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -183,7 +183,7 @@ type Config struct { RFC2136Zone []string RFC2136Insecure bool RFC2136GSSTSIG bool - RFC2136ManagePTR bool + RFC2136CreatePTR bool RFC2136KerberosRealm string RFC2136KerberosUsername string RFC2136KerberosPassword string `secure:"yes"` @@ -580,7 +580,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("rfc2136-host", "When using the RFC2136 provider, specify the host of the DNS server").Default(defaultConfig.RFC2136Host).StringVar(&cfg.RFC2136Host) app.Flag("rfc2136-port", "When using the RFC2136 provider, specify the port of the DNS server").Default(strconv.Itoa(defaultConfig.RFC2136Port)).IntVar(&cfg.RFC2136Port) app.Flag("rfc2136-zone", "When using the RFC2136 provider, specify zone entries of the DNS server to use").StringsVar(&cfg.RFC2136Zone) - app.Flag("rfc2136-manageptr", "When using the RFC2136 provider, enable PTR management").Default(strconv.FormatBool(defaultConfig.RFC2136ManagePTR)).BoolVar(&cfg.RFC2136ManagePTR) + app.Flag("rfc2136-create-ptr", "When using the RFC2136 provider, enable PTR management").Default(strconv.FormatBool(defaultConfig.RFC2136CreatePTR)).BoolVar(&cfg.RFC2136CreatePTR) app.Flag("rfc2136-insecure", "When using the RFC2136 provider, specify whether to attach TSIG or not (default: false, requires --rfc2136-tsig-keyname and rfc2136-tsig-secret)").Default(strconv.FormatBool(defaultConfig.RFC2136Insecure)).BoolVar(&cfg.RFC2136Insecure) app.Flag("rfc2136-tsig-keyname", "When using the RFC2136 provider, specify the TSIG key to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGKeyName).StringVar(&cfg.RFC2136TSIGKeyName) app.Flag("rfc2136-tsig-secret", "When using the RFC2136 provider, specify the TSIG (base64) value to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGSecret).StringVar(&cfg.RFC2136TSIGSecret) diff --git a/pkg/apis/externaldns/validation/validation_test.go b/pkg/apis/externaldns/validation/validation_test.go index 1209afd2c7..b917468634 100644 --- a/pkg/apis/externaldns/validation/validation_test.go +++ b/pkg/apis/externaldns/validation/validation_test.go @@ -132,7 +132,7 @@ func TestValidateBadRfc2136Config(t *testing.T) { cfg.Sources = []string{"test-source"} cfg.Provider = "rfc2136" cfg.RFC2136MinTTL = -1 - cfg.ManagePTR = false + cfg.CreatePTR = false cfg.RFC2136BatchChangeSize = 50 err := ValidateConfig(cfg) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index 3e89d33bdf..9692c91526 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -54,7 +54,7 @@ type rfc2136Provider struct { axfr bool minTTL time.Duration batchChangeSize int - managePTR bool + createPTR bool // options specific to rfc3645 gss-tsig support gssTsig bool @@ -83,7 +83,7 @@ type rfc2136Actions interface { } // NewRfc2136Provider is a factory function for OpenStack rfc2136 providers -func NewRfc2136Provider(host string, port int, zoneNames []string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, managePTR bool, gssTsig bool, krb5Username string, krb5Password string, krb5Realm string, batchChangeSize int, actions rfc2136Actions) (provider.Provider, error) { +func NewRfc2136Provider(host string, port int, zoneNames []string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, createPTR bool, gssTsig bool, krb5Username string, krb5Password string, krb5Realm string, batchChangeSize int, actions rfc2136Actions) (provider.Provider, error) { secretAlgChecked, ok := tsigAlgs[secretAlg] if !ok && !insecure && !gssTsig { return nil, errors.Errorf("%s is not supported TSIG algorithm", secretAlg) @@ -104,7 +104,7 @@ func NewRfc2136Provider(host string, port int, zoneNames []string, insecure bool zoneNames: zoneNames, insecure: insecure, gssTsig: gssTsig, - managePTR: managePTR, + createPTR: createPTR, krb5Username: krb5Username, krb5Password: krb5Password, krb5Realm: strings.ToUpper(krb5Realm), @@ -308,7 +308,7 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes m[zone].SetUpdate(zone) r.AddRecord(m[zone], ep) - if r.managePTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { + if r.createPTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { r.AddReverseRecord(ep.Targets[0], ep.DNSName) } } @@ -380,7 +380,7 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes m[zone].SetUpdate(zone) r.RemoveRecord(m[zone], ep) - if r.managePTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { + if r.createPTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { r.RemoveReverseRecord(ep.Targets[0], ep.DNSName) } } From bab7a84f11189d817749fb8dbd8609162cef78e2 Mon Sep 17 00:00:00 2001 From: angeloxx Date: Mon, 26 Feb 2024 22:15:46 +0100 Subject: [PATCH 5/8] Fix test coverage --- pkg/apis/externaldns/validation/validation_test.go | 2 +- provider/rfc2136/rfc2136.go | 6 ++++++ provider/rfc2136/rfc2136_test.go | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/apis/externaldns/validation/validation_test.go b/pkg/apis/externaldns/validation/validation_test.go index b917468634..b0efbf7d68 100644 --- a/pkg/apis/externaldns/validation/validation_test.go +++ b/pkg/apis/externaldns/validation/validation_test.go @@ -132,7 +132,7 @@ func TestValidateBadRfc2136Config(t *testing.T) { cfg.Sources = []string{"test-source"} cfg.Provider = "rfc2136" cfg.RFC2136MinTTL = -1 - cfg.CreatePTR = false + cfg.RFC2136CreatePTR = false cfg.RFC2136BatchChangeSize = 50 err := ValidateConfig(cfg) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index 9692c91526..27934485d6 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -262,6 +262,12 @@ func (r rfc2136Provider) RemoveReverseRecord(ip string, hostname string) error { return r.ApplyChanges(context.Background(), &plan.Changes{Delete: changes}) } +// @TODO: Implement UpdateReverseRecord +func (r rfc2136Provider) UpdateReverseRecord(ip string, hostname string) error { + changes := r.GenerateReverseRecord(ip, hostname) + return r.ApplyChanges(context.Background(), &plan.Changes{UpdateNew: changes}) +} + func (r rfc2136Provider) GenerateReverseRecord(ip string, hostname string) []*endpoint.Endpoint { // Find the zone for the PTR record // zone := findMsgZone(&endpoint.Endpoint{DNSName: ip}, p.ptrZoneNames) diff --git a/provider/rfc2136/rfc2136_test.go b/provider/rfc2136/rfc2136_test.go index a143ef7b0c..97278f044a 100644 --- a/provider/rfc2136/rfc2136_test.go +++ b/provider/rfc2136/rfc2136_test.go @@ -118,17 +118,17 @@ func (r *rfc2136Stub) IncomeTransfer(m *dns.Msg, a string) (env chan *dns.Envelo } func createRfc2136StubProvider(stub *rfc2136Stub) (provider.Provider, error) { - return NewRfc2136Provider("", 0, nil, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, "", "", "", 50, stub) + return NewRfc2136Provider("", 0, nil, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, false, "", "", "", 50, stub) } func createRfc2136StubProviderWithZones(stub *rfc2136Stub) (provider.Provider, error) { zones := []string{"foo.com", "foobar.com"} - return NewRfc2136Provider("", 0, zones, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, "", "", "", 50, stub) + return NewRfc2136Provider("", 0, zones, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, false, "", "", "", 50, stub) } func createRfc2136StubProviderWithZonesFilters(stub *rfc2136Stub) (provider.Provider, error) { zones := []string{"foo.com", "foobar.com"} - return NewRfc2136Provider("", 0, zones, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{Filters: zones}, false, 300*time.Second, false, "", "", "", 50, stub) + return NewRfc2136Provider("", 0, zones, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{Filters: zones}, false, 300*time.Second, false, false, "", "", "", 50, stub) } func extractUpdateSectionFromMessage(msg fmt.Stringer) []string { From 2f7f6390d003b3f1508ba95f88db587609e57725 Mon Sep 17 00:00:00 2001 From: angeloxx Date: Mon, 26 Feb 2024 22:27:13 +0100 Subject: [PATCH 6/8] Update implemented. --- provider/rfc2136/rfc2136.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index 27934485d6..27d71d8418 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -262,12 +262,6 @@ func (r rfc2136Provider) RemoveReverseRecord(ip string, hostname string) error { return r.ApplyChanges(context.Background(), &plan.Changes{Delete: changes}) } -// @TODO: Implement UpdateReverseRecord -func (r rfc2136Provider) UpdateReverseRecord(ip string, hostname string) error { - changes := r.GenerateReverseRecord(ip, hostname) - return r.ApplyChanges(context.Background(), &plan.Changes{UpdateNew: changes}) -} - func (r rfc2136Provider) GenerateReverseRecord(ip string, hostname string) []*endpoint.Endpoint { // Find the zone for the PTR record // zone := findMsgZone(&endpoint.Endpoint{DNSName: ip}, p.ptrZoneNames) @@ -352,6 +346,10 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes m[zone].SetUpdate(zone) r.UpdateRecord(m[zone], changes.UpdateOld[i], ep) + if r.createPTR && (ep.RecordType == "A" || ep.RecordType == "AAAA") { + r.RemoveReverseRecord(changes.UpdateOld[i].Targets[0], ep.DNSName) + r.AddReverseRecord(ep.Targets[0], ep.DNSName) + } } // only send if there are records available From a0040a46035e73a7c2aa0d007b723877551d3130 Mon Sep 17 00:00:00 2001 From: angeloxx Date: Mon, 13 May 2024 15:31:18 +0200 Subject: [PATCH 7/8] add PTR creation task --- provider/rfc2136/rfc2136_test.go | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/provider/rfc2136/rfc2136_test.go b/provider/rfc2136/rfc2136_test.go index 765d681118..efaa79d183 100644 --- a/provider/rfc2136/rfc2136_test.go +++ b/provider/rfc2136/rfc2136_test.go @@ -134,6 +134,19 @@ func createRfc2136TLSStubProvider(stub *rfc2136Stub, tlsConfig TLSConfig) (provi return NewRfc2136Provider("rfc2136-host", 0, nil, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, false, "", "", "", 50, tlsConfig, stub) } +func createRfc2136StubProviderWithReverse(stub *rfc2136Stub) (provider.Provider, error) { + tlsConfig := TLSConfig{ + UseTLS: false, + SkipTLSVerify: false, + CAFilePath: "", + ClientCertFilePath: "", + ClientCertKeyFilePath: "", + } + + zones := []string{"foo.com", "3.2.1.in-addr.arpa"} + return NewRfc2136Provider("", 0, zones, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{Filters: zones}, false, 300*time.Second, true, false, "", "", "", 50, tlsConfig, stub) +} + func createRfc2136StubProviderWithZones(stub *rfc2136Stub) (provider.Provider, error) { tlsConfig := TLSConfig{ UseTLS: false, @@ -196,6 +209,27 @@ func TestRfc2136GetRecordsMultipleTargets(t *testing.T) { assert.Equal(t, 0, len(recs[0].ProviderSpecific), "expected no provider specific config") } +func TestRfc2136PTRCreation(t *testing.T) { + stub := newStub() + provider, err := createRfc2136StubProviderWithReverse(stub) + assert.NoError(t, err) + + err = provider.ApplyChanges(context.Background(), &plan.Changes{ + Create: []*endpoint.Endpoint{ + { + DNSName: "demo.foo.com", + RecordType: "A", + Targets: []string{"1.2.3.4"}, + }, + }, + }) + assert.NoError(t, err) + assert.Equal(t, 2, len(stub.createMsgs), "expected two records, one A and one PTR") + createMsgs := getSortedChanges(stub.createMsgs) + assert.True(t, strings.Contains(strings.Join(strings.Fields(createMsgs[0]), " "), "4.3.2.1.in-addr.arpa. 300 IN PTR demo.foo.com."), "excpeted a PTR record") + assert.True(t, strings.Contains(strings.Join(strings.Fields(createMsgs[1]), " "), "demo.foo.com. 300 IN A 1.2.3.4"), "expected an A record") +} + func TestRfc2136TLSConfig(t *testing.T) { stub := newStub() From 1d93309e7fde3f1a5c5bc6f8439e37292e2ad3e5 Mon Sep 17 00:00:00 2001 From: angeloxx Date: Mon, 13 May 2024 15:43:24 +0200 Subject: [PATCH 8/8] lint --- provider/rfc2136/rfc2136.go | 1 - 1 file changed, 1 deletion(-) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index ce918b55dc..ba58282126 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -306,7 +306,6 @@ func (r rfc2136Provider) GenerateReverseRecord(ip string, hostname string) []*en }) return records - } // ApplyChanges applies a given set of changes in a given zone.