From a7eba97ada193e7ed72be1df9dd87cbbbd6642e7 Mon Sep 17 00:00:00 2001 From: Tom Limoncelli Date: Mon, 19 Mar 2018 17:18:58 -0400 Subject: [PATCH] Refactor in preparation to unexport RecordConfig.{Name,NameFQDN,Target} (#337) * Preparing for the unexport of Name/NameFQDN/Target * Cleanups --- integrationTest/integration_test.go | 40 ++++++--- models/dns_test.go | 16 ++-- models/domain.go | 14 ++- models/record.go | 12 ++- models/t_caa.go | 2 +- models/t_mx.go | 2 +- models/t_srv.go | 2 +- models/t_tlsa.go | 2 +- models/t_txt.go | 4 +- models/target.go | 4 +- pkg/nameservers/nameservers.go | 12 +-- pkg/normalize/flatten.go | 10 +-- pkg/normalize/importTransform_test.go | 14 ++- pkg/normalize/validate.go | 66 +++++++------- pkg/normalize/validate_test.go | 25 ++++-- providers/activedir/domains.go | 40 +++++---- providers/activedir/domains_test.go | 16 ++-- providers/bind/bindProvider.go | 2 +- providers/cloudflare/preprocess_test.go | 34 +++++--- providers/diff/diff.go | 12 +-- providers/diff/diff_test.go | 9 +- .../digitalocean/digitaloceanProvider.go | 2 +- providers/dnsimple/dnsimpleProvider.go | 7 +- providers/gandi/gandiProvider.go | 6 +- providers/gandi/livedns.go | 18 ++-- providers/gandi/livedns_test.go | 85 +++++++------------ providers/gcloud/gcloudProvider.go | 2 +- providers/linode/linodeProvider.go | 4 +- providers/namecheap/namecheapProvider.go | 16 ++-- providers/namedotcom/records.go | 10 +-- providers/octodns/octoyaml/read.go | 2 +- providers/octodns/octoyaml/rw_test.go | 4 +- providers/octodns/octoyaml/sort.go | 6 +- providers/octodns/octoyaml/write.go | 7 +- providers/ovh/protocol.go | 4 +- providers/softlayer/softlayerProvider.go | 44 +++++----- providers/vultr/vultrProvider.go | 13 ++- 37 files changed, 298 insertions(+), 270 deletions(-) diff --git a/integrationTest/integration_test.go b/integrationTest/integration_test.go index 24e66e638..f377e487c 100644 --- a/integrationTest/integration_test.go +++ b/integrationTest/integration_test.go @@ -107,9 +107,11 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string, dom, _ := dc.Copy() for _, r := range tst.Records { rc := models.RecordConfig(*r) - rc.NameFQDN = dnsutil.AddOrigin(rc.Name, domainName) - if strings.Contains(rc.Target, "**current-domain**") { - rc.Target = strings.Replace(rc.Target, "**current-domain**", domainName, 1) + "." + if strings.Contains(rc.GetTargetField(), "**current-domain**") { + rc.SetTarget(strings.Replace(rc.GetTargetField(), "**current-domain**", domainName, 1) + ".") + } + if strings.Contains(rc.GetLabelFQDN(), "**current-domain**") { + rc.SetLabelFromFQDN(strings.Replace(rc.GetLabelFQDN(), "**current-domain**", domainName, 1), domainName) } dom.Records = append(dom.Records, &rc) } @@ -205,6 +207,19 @@ type TestCase struct { type rec models.RecordConfig +func (r *rec) GetLabel() string { + return r.Name +} + +func (r *rec) SetLabel(label, domain string) { + r.Name = label + r.NameFQDN = dnsutil.AddOrigin(label, "**current-domain**") +} + +func (r *rec) SetTarget(target string) { + r.Target = target +} + func a(name, target string) *rec { return makeRec(name, target, "A") } @@ -273,24 +288,25 @@ func tlsa(name string, usage, selector, matchingtype uint8, target string) *rec r.TlsaUsage = usage r.TlsaSelector = selector r.TlsaMatchingType = matchingtype - r.Target = target return r } func ignore(name string) *rec { - return &rec{ - Name: name, + r := &rec{ Type: "IGNORE", } + r.SetLabel(name, "**current-domain**") + return r } func makeRec(name, target, typ string) *rec { - return &rec{ - Name: name, - Type: typ, - Target: target, - TTL: 300, + r := &rec{ + Type: typ, + TTL: 300, } + r.SetLabel(name, "**current-domain**") + r.SetTarget(target) + return r } func (r *rec) ttl(t uint32) *rec { @@ -303,7 +319,7 @@ func tc(desc string, recs ...*rec) *TestCase { var ignored []string for _, r := range recs { if r.Type == "IGNORE" { - ignored = append(ignored, r.Name) + ignored = append(ignored, r.GetLabel()) } else { records = append(records, r) } diff --git a/models/dns_test.go b/models/dns_test.go index cd9710019..40cfb3d7c 100644 --- a/models/dns_test.go +++ b/models/dns_test.go @@ -26,9 +26,9 @@ func TestRR(t *testing.T) { experiment := RecordConfig{ Type: "A", Name: "foo", + NameFQDN: "foo.example.com", Target: "1.2.3.4", TTL: 0, - NameFQDN: "foo.example.com", MxPreference: 0, } expected := "foo.example.com.\t300\tIN\tA\t1.2.3.4" @@ -40,9 +40,9 @@ func TestRR(t *testing.T) { experiment = RecordConfig{ Type: "CAA", Name: "@", + NameFQDN: "example.com", Target: "mailto:test@example.com", TTL: 300, - NameFQDN: "example.com", CaaTag: "iodef", CaaFlag: 1, } @@ -55,9 +55,9 @@ func TestRR(t *testing.T) { experiment = RecordConfig{ Type: "TLSA", Name: "@", + NameFQDN: "_443._tcp.example.com", Target: "abcdef0123456789", TTL: 300, - NameFQDN: "_443._tcp.example.com", TlsaUsage: 0, TlsaSelector: 0, TlsaMatchingType: 1, @@ -74,17 +74,17 @@ func TestDowncase(t *testing.T) { &RecordConfig{Type: "MX", Name: "lower", Target: "targetmx"}, &RecordConfig{Type: "MX", Name: "UPPER", Target: "TARGETMX"}, }} - Downcase(dc.Records) + downcase(dc.Records) if !dc.HasRecordTypeName("MX", "lower") { t.Errorf("%v: expected (%v) got (%v)\n", dc.Records, false, true) } if !dc.HasRecordTypeName("MX", "upper") { t.Errorf("%v: expected (%v) got (%v)\n", dc.Records, false, true) } - if dc.Records[0].Target != "targetmx" { - t.Errorf("%v: target0 expected (%v) got (%v)\n", dc.Records, "targetmx", dc.Records[0].Target) + if dc.Records[0].GetTargetField() != "targetmx" { + t.Errorf("%v: target0 expected (%v) got (%v)\n", dc.Records, "targetmx", dc.Records[0].GetTargetField()) } - if dc.Records[1].Target != "targetmx" { - t.Errorf("%v: target1 expected (%v) got (%v)\n", dc.Records, "targetmx", dc.Records[1].Target) + if dc.Records[1].GetTargetField() != "targetmx" { + t.Errorf("%v: target1 expected (%v) got (%v)\n", dc.Records, "targetmx", dc.Records[1].GetTargetField()) } } diff --git a/models/domain.go b/models/domain.go index 455cbf9d6..7093eb70f 100644 --- a/models/domain.go +++ b/models/domain.go @@ -49,7 +49,7 @@ func (dc *DomainConfig) Copy() (*DomainConfig, error) { // HasRecordTypeName returns True if there is a record with this rtype and name. func (dc *DomainConfig) HasRecordTypeName(rtype, name string) bool { for _, r := range dc.Records { - if r.Type == rtype && r.Name == name { + if r.Type == rtype && r.GetLabel() == name { return true } } @@ -73,19 +73,17 @@ func (dc *DomainConfig) Filter(f func(r *RecordConfig) bool) { // - NameFQDN // - Target (CNAME and MX only) func (dc *DomainConfig) Punycode() error { - var err error for _, rec := range dc.Records { - rec.Name, err = idna.ToASCII(rec.Name) - if err != nil { - return err - } - rec.NameFQDN, err = idna.ToASCII(rec.NameFQDN) + t, err := idna.ToASCII(rec.GetLabelFQDN()) if err != nil { return err } + rec.SetLabelFromFQDN(t, dc.Name) switch rec.Type { // #rtype_variations case "ALIAS", "MX", "NS", "CNAME", "PTR", "SRV", "URL", "URL301", "FRAME", "R53_ALIAS": - rec.Target, err = idna.ToASCII(rec.Target) + // These rtypes are hostnames, therefore need to be converted (unlike, for example, an AAAA record) + t, err := idna.ToASCII(rec.GetTargetField()) + rec.SetTarget(t) if err != nil { return err } diff --git a/models/record.go b/models/record.go index b04b9706c..d7d324a4f 100644 --- a/models/record.go +++ b/models/record.go @@ -120,6 +120,14 @@ func (rc *RecordConfig) SetLabel(short, origin string) { } } +// UnsafeSetLabelNull sets the label to "". Normally the FQDN is denoted by .Name being +// "@" however this can be used to violate that assertion. It should only be used +// on copies of a RecordConfig that is being used for non-standard things like +// Marshalling yaml. +func (rc *RecordConfig) UnsafeSetLabelNull() { + rc.Name = "" +} + // SetLabelFromFQDN sets the .Name/.NameFQDN fields given a FQDN and origin. // fqdn may have a trailing "." but it is not required. // origin may not have a trailing dot. @@ -268,11 +276,11 @@ func (r Records) GroupedByLabel() ([]string, map[string]Records) { // PostProcessRecords does any post-processing of the downloaded DNS records. func PostProcessRecords(recs []*RecordConfig) { - Downcase(recs) + downcase(recs) } // Downcase converts all labels and targets to lowercase in a list of RecordConfig. -func Downcase(recs []*RecordConfig) { +func downcase(recs []*RecordConfig) { for _, r := range recs { r.Name = strings.ToLower(r.Name) r.NameFQDN = strings.ToLower(r.NameFQDN) diff --git a/models/t_caa.go b/models/t_caa.go index cfd8d89ec..03b34bdf6 100644 --- a/models/t_caa.go +++ b/models/t_caa.go @@ -11,7 +11,7 @@ import ( func (rc *RecordConfig) SetTargetCAA(flag uint8, tag string, target string) error { rc.CaaTag = tag rc.CaaFlag = flag - rc.Target = target + rc.SetTarget(target) if rc.Type == "" { rc.Type = "CAA" } diff --git a/models/t_mx.go b/models/t_mx.go index ca4fa9011..7cee18ab4 100644 --- a/models/t_mx.go +++ b/models/t_mx.go @@ -10,7 +10,7 @@ import ( // SetTargetMX sets the MX fields. func (rc *RecordConfig) SetTargetMX(pref uint16, target string) error { rc.MxPreference = pref - rc.Target = target + rc.SetTarget(target) if rc.Type == "" { rc.Type = "MX" } diff --git a/models/t_srv.go b/models/t_srv.go index 92aa8f653..cc02e5ba5 100644 --- a/models/t_srv.go +++ b/models/t_srv.go @@ -12,7 +12,7 @@ func (rc *RecordConfig) SetTargetSRV(priority, weight, port uint16, target strin rc.SrvPriority = priority rc.SrvWeight = weight rc.SrvPort = port - rc.Target = target + rc.SetTarget(target) if rc.Type == "" { rc.Type = "SRV" } diff --git a/models/t_tlsa.go b/models/t_tlsa.go index 246ef1b79..dc2ff36b6 100644 --- a/models/t_tlsa.go +++ b/models/t_tlsa.go @@ -12,7 +12,7 @@ func (rc *RecordConfig) SetTargetTLSA(usage, selector, matchingtype uint8, targe rc.TlsaUsage = usage rc.TlsaSelector = selector rc.TlsaMatchingType = matchingtype - rc.Target = target + rc.SetTarget(target) if rc.Type == "" { rc.Type = "TLSA" } diff --git a/models/t_txt.go b/models/t_txt.go index 0b6a2326d..9afd24b39 100644 --- a/models/t_txt.go +++ b/models/t_txt.go @@ -2,7 +2,7 @@ package models // SetTargetTXT sets the TXT fields when there is 1 string. func (rc *RecordConfig) SetTargetTXT(s string) error { - rc.Target = s + rc.SetTarget(s) rc.TxtStrings = []string{s} if rc.Type == "" { rc.Type = "TXT" @@ -15,7 +15,7 @@ func (rc *RecordConfig) SetTargetTXT(s string) error { // SetTargetTXTs sets the TXT fields when there are many strings. func (rc *RecordConfig) SetTargetTXTs(s []string) error { - rc.Target = s[0] + rc.SetTarget(s[0]) rc.TxtStrings = s if rc.Type == "" { rc.Type = "TXT" diff --git a/models/target.go b/models/target.go index 9af79dfeb..03d44a8c2 100644 --- a/models/target.go +++ b/models/target.go @@ -109,11 +109,11 @@ func (rc *RecordConfig) SetTarget(target string) error { // SetTargetIP sets the target to an IP, verifying this is an appropriate rtype. func (rc *RecordConfig) SetTargetIP(ip net.IP) error { // TODO(tlim): Verify the rtype is appropriate for an IP. - rc.Target = ip.String() + rc.SetTarget(ip.String()) return nil } -// // SetTargetFQDN sets the target to an IP, verifying this is an appropriate rtype. +// // SetTargetFQDN sets the target to a string, verifying this is an appropriate rtype. // func (rc *RecordConfig) SetTargetFQDN(target string) error { // // TODO(tlim): Verify the rtype is appropriate for an hostname. // rc.Target = target diff --git a/pkg/nameservers/nameservers.go b/pkg/nameservers/nameservers.go index e4013f759..362e26e00 100644 --- a/pkg/nameservers/nameservers.go +++ b/pkg/nameservers/nameservers.go @@ -8,7 +8,6 @@ import ( "strconv" "github.com/StackExchange/dnscontrol/models" - "github.com/miekg/dns/dnsutil" ) // DetermineNameservers will find all nameservers we should use for a domain. It follows the following rules: @@ -52,15 +51,16 @@ func AddNSRecords(dc *models.DomainConfig) { for _, ns := range dc.Nameservers { rc := &models.RecordConfig{ Type: "NS", - Name: "@", - Target: ns.Name, Metadata: map[string]string{}, TTL: ttl, } - if !strings.HasSuffix(rc.Target, ".") { - rc.Target += "." + rc.SetLabel("@", dc.Name) + t := ns.Name + if !strings.HasSuffix(t, ".") { + rc.SetTarget(t + ".") } - rc.NameFQDN = dnsutil.AddOrigin(rc.Name, dc.Name) + rc.SetTarget(t) + dc.Records = append(dc.Records, rc) } } diff --git a/pkg/normalize/flatten.go b/pkg/normalize/flatten.go index 6c1393518..1018614c4 100644 --- a/pkg/normalize/flatten.go +++ b/pkg/normalize/flatten.go @@ -3,7 +3,6 @@ package normalize import ( "strings" - "github.com/miekg/dns/dnsutil" "github.com/pkg/errors" "github.com/StackExchange/dnscontrol/models" @@ -27,13 +26,13 @@ func flattenSPFs(cfg *models.DNSConfig) []error { return []error{err} } } - rec, err = spflib.Parse(txt.Target, cache) + rec, err = spflib.Parse(txt.GetTargetField(), cache) if err != nil { errs = append(errs, err) continue } } - if flatten, ok := txt.Metadata["flatten"]; ok && strings.HasPrefix(txt.Target, "v=spf1") { + if flatten, ok := txt.Metadata["flatten"]; ok && strings.HasPrefix(txt.GetTargetField(), "v=spf1") { rec = rec.Flatten(flatten) err = txt.SetTargetTXT(rec.TXT()) if err != nil { @@ -44,7 +43,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error { // now split if needed if split, ok := txt.Metadata["split"]; ok { if !strings.Contains(split, "%d") { - errs = append(errs, Warning{errors.Errorf("Split format `%s` in `%s` is not proper format (should have %%d in it)", split, txt.NameFQDN)}) + errs = append(errs, Warning{errors.Errorf("Split format `%s` in `%s` is not proper format (should have %%d in it)", split, txt.GetLabelFQDN())}) continue } recs := rec.TXTSplit(split + "." + domain.Name) @@ -54,8 +53,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error { } else { cp, _ := txt.Copy() cp.SetTargetTXT(v) - cp.NameFQDN = k - cp.Name = dnsutil.TrimDomainName(k, domain.Name) + cp.SetLabelFromFQDN(k, domain.Name) domain.Records = append(domain.Records, cp) } } diff --git a/pkg/normalize/importTransform_test.go b/pkg/normalize/importTransform_test.go index bb49d8b7b..d1ec4ab62 100644 --- a/pkg/normalize/importTransform_test.go +++ b/pkg/normalize/importTransform_test.go @@ -6,6 +6,12 @@ import ( "github.com/StackExchange/dnscontrol/models" ) +func makeRC(label, domain, target string, rc models.RecordConfig) *models.RecordConfig { + rc.SetLabel(label, domain) + rc.SetTarget(target) + return &rc +} + func TestImportTransform(t *testing.T) { const transformDouble = "0.0.0.0~1.1.1.1~~9.0.0.0,10.0.0.0" @@ -13,15 +19,15 @@ func TestImportTransform(t *testing.T) { src := &models.DomainConfig{ Name: "stackexchange.com", Records: []*models.RecordConfig{ - {Type: "A", Name: "*", NameFQDN: "*.stackexchange.com", Target: "0.0.2.2"}, - {Type: "A", Name: "www", NameFQDN: "www.stackexchange.com", Target: "0.0.1.1"}, + makeRC("*", "stackexchange.com", "0.0.2.2", models.RecordConfig{Type: "A"}), + makeRC("www", "stackexchange.com", "0.0.1.1", models.RecordConfig{Type: "A"}), }, } dst := &models.DomainConfig{ Name: "internal", Records: []*models.RecordConfig{ - {Type: "A", Name: "*.stackexchange.com", NameFQDN: "*.stackexchange.com.internal", Target: "0.0.3.3", Metadata: map[string]string{"transform_table": transformSingle}}, - {Type: "IMPORT_TRANSFORM", Name: "@", NameFQDN: "internal", Target: "stackexchange.com", Metadata: map[string]string{"transform_table": transformDouble}}, + makeRC("*.stackexchange.com", "*.stackexchange.com.internal", "0.0.3.3", models.RecordConfig{Type: "A", Metadata: map[string]string{"transform_table": transformSingle}}), + makeRC("@", "internal", "stackexchange.com", models.RecordConfig{Type: "IMPORT_TRANSFORM", Metadata: map[string]string{"transform_table": transformDouble}}), }, } cfg := &models.DNSConfig{ diff --git a/pkg/normalize/validate.go b/pkg/normalize/validate.go index f694537dc..b2a2c073d 100644 --- a/pkg/normalize/validate.go +++ b/pkg/normalize/validate.go @@ -66,7 +66,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin if !ok { cType := providers.GetCustomRecordType(rec.Type) if cType == nil { - return errors.Errorf("Unsupported record type (%v) domain=%v name=%v", rec.Type, domain, rec.Name) + return errors.Errorf("Unsupported record type (%v) domain=%v name=%v", rec.Type, domain, rec.GetLabel()) } for _, providerType := range pTypes { if providerType != cType.Provider { @@ -125,11 +125,11 @@ func checkLabel(label string, rType string, domain string, meta map[string]strin // checkTargets returns true if rec.Target is valid for the rec.Type. func checkTargets(rec *models.RecordConfig, domain string) (errs []error) { - label := rec.Name - target := rec.Target + label := rec.GetLabel() + target := rec.GetTargetField() check := func(e error) { if e != nil { - err := errors.Errorf("In %s %s.%s: %s", rec.Type, rec.Name, domain, e.Error()) + err := errors.Errorf("In %s %s.%s: %s", rec.Type, rec.GetLabel(), domain, e.Error()) if _, ok := e.(Warning); ok { err = Warning{err} } @@ -166,7 +166,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) { return } errs = append(errs, errors.Errorf("checkTargets: Unimplemented record type (%v) domain=%v name=%v", - rec.Type, domain, rec.Name)) + rec.Type, domain, rec.GetLabel())) } return } @@ -189,13 +189,13 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra // 4. For As, change the target as described the transforms. for _, rec := range srcDomain.Records { - if dstDomain.HasRecordTypeName(rec.Type, rec.NameFQDN) { + if dstDomain.HasRecordTypeName(rec.Type, rec.GetLabelFQDN()) { continue } newRec := func() *models.RecordConfig { rec2, _ := rec.Copy() - rec2.Name = rec2.NameFQDN - rec2.NameFQDN = dnsutil.AddOrigin(rec2.Name, dstDomain.Name) + newlabel := rec2.GetLabelFQDN() + rec2.SetLabelFromFQDN(newlabel, dstDomain.Name) if ttl != 0 { rec2.TTL = ttl } @@ -203,25 +203,25 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra } switch rec.Type { // #rtype_variations case "A": - trs, err := transform.TransformIPToList(net.ParseIP(rec.Target), transforms) + trs, err := transform.TransformIPToList(net.ParseIP(rec.GetTargetField()), transforms) if err != nil { - return errors.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.Target, transforms, err) + return errors.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.GetTargetField(), transforms, err) } for _, tr := range trs { r := newRec() - r.Target = tr.String() + r.SetTarget(tr.String()) dstDomain.Records = append(dstDomain.Records, r) } case "CNAME": r := newRec() - r.Target = transformCNAME(r.Target, srcDomain.Name, dstDomain.Name) + r.SetTarget(transformCNAME(r.GetTargetField(), srcDomain.Name, dstDomain.Name)) dstDomain.Records = append(dstDomain.Records, r) case "MX", "NS", "SRV", "TXT", "CAA", "TLSA": // Not imported. continue default: return errors.Errorf("import_transform: Unimplemented record type %v (%v)", - rec.Type, rec.Name) + rec.Type, rec.GetLabel()) } } return nil @@ -276,7 +276,7 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) { if err := validateRecordTypes(rec, domain.Name, pTypes); err != nil { errs = append(errs, err) } - if err := checkLabel(rec.Name, rec.Type, domain.Name, rec.Metadata); err != nil { + if err := checkLabel(rec.GetLabel(), rec.Type, domain.Name, rec.Metadata); err != nil { errs = append(errs, err) } if errs2 := checkTargets(rec, domain.Name); errs2 != nil { @@ -285,14 +285,16 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) { // Canonicalize Targets. if rec.Type == "CNAME" || rec.Type == "MX" || rec.Type == "NS" { - rec.Target = dnsutil.AddOrigin(rec.Target, domain.Name+".") + rec.SetTarget(dnsutil.AddOrigin(rec.GetTargetField(), domain.Name+".")) } else if rec.Type == "A" || rec.Type == "AAAA" { - rec.Target = net.ParseIP(rec.Target).String() + rec.SetTarget(net.ParseIP(rec.GetTargetField()).String()) } else if rec.Type == "PTR" { var err error - if rec.Name, err = transform.PtrNameMagic(rec.Name, domain.Name); err != nil { + var name string + if name, err = transform.PtrNameMagic(rec.GetLabel(), domain.Name); err != nil { errs = append(errs, err) } + rec.SetLabel(name, domain.Name) } else if rec.Type == "CAA" { if rec.CaaTag != "issue" && rec.CaaTag != "issuewild" && rec.CaaTag != "iodef" { errs = append(errs, errors.Errorf("CAA tag %s is invalid", rec.CaaTag)) @@ -300,26 +302,26 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) { } else if rec.Type == "TLSA" { if rec.TlsaUsage < 0 || rec.TlsaUsage > 3 { errs = append(errs, errors.Errorf("TLSA Usage %d is invalid in record %s (domain %s)", - rec.TlsaUsage, rec.Name, domain.Name)) + rec.TlsaUsage, rec.GetLabel(), domain.Name)) } if rec.TlsaSelector < 0 || rec.TlsaSelector > 1 { errs = append(errs, errors.Errorf("TLSA Selector %d is invalid in record %s (domain %s)", - rec.TlsaSelector, rec.Name, domain.Name)) + rec.TlsaSelector, rec.GetLabel(), domain.Name)) } if rec.TlsaMatchingType < 0 || rec.TlsaMatchingType > 2 { errs = append(errs, errors.Errorf("TLSA MatchingType %d is invalid in record %s (domain %s)", - rec.TlsaMatchingType, rec.Name, domain.Name)) + rec.TlsaMatchingType, rec.GetLabel(), domain.Name)) } } else if rec.Type == "TXT" && len(txtMultiDissenters) != 0 && len(rec.TxtStrings) > 1 { // There are providers that don't support TXTMulti yet there is // a TXT record with multiple strings: errs = append(errs, errors.Errorf("TXT records with multiple strings (label %v domain: %v) not supported by %s", - rec.Name, domain.Name, strings.Join(txtMultiDissenters, ","))) + rec.GetLabel(), domain.Name, strings.Join(txtMultiDissenters, ","))) } // Populate FQDN: - rec.NameFQDN = dnsutil.AddOrigin(rec.Name, domain.Name) + //rec.NameFQDN = dnsutil.AddOrigin(rec.GetLabel(), domain.Name) } } @@ -337,7 +339,7 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) { errs = append(errs, err) continue } - err = importTransform(config.FindDomain(rec.Target), domain, table, rec.TTL) + err = importTransform(config.FindDomain(rec.GetTargetField()), domain, table, rec.TTL) if err != nil { errs = append(errs, err) } @@ -375,15 +377,15 @@ func checkCNAMEs(dc *models.DomainConfig) (errs []error) { cnames := map[string]bool{} for _, r := range dc.Records { if r.Type == "CNAME" { - if cnames[r.Name] { - errs = append(errs, errors.Errorf("Cannot have multiple CNAMEs with same name: %s", r.NameFQDN)) + if cnames[r.GetLabel()] { + errs = append(errs, errors.Errorf("Cannot have multiple CNAMEs with same name: %s", r.GetLabelFQDN())) } - cnames[r.Name] = true + cnames[r.GetLabel()] = true } } for _, r := range dc.Records { - if cnames[r.Name] && r.Type != "CNAME" { - errs = append(errs, errors.Errorf("Cannot have CNAME and %s record with same name: %s", r.Type, r.NameFQDN)) + if cnames[r.GetLabel()] && r.Type != "CNAME" { + errs = append(errs, errors.Errorf("Cannot have CNAME and %s record with same name: %s", r.Type, r.GetLabelFQDN())) } } return @@ -433,21 +435,21 @@ func applyRecordTransforms(domain *models.DomainConfig) error { if err != nil { return err } - ip := net.ParseIP(rec.Target) // ip already validated above - newIPs, err := transform.TransformIPToList(net.ParseIP(rec.Target), table) + ip := net.ParseIP(rec.GetTargetField()) // ip already validated above + newIPs, err := transform.TransformIPToList(net.ParseIP(rec.GetTargetField()), table) if err != nil { return err } for i, newIP := range newIPs { if i == 0 && !newIP.Equal(ip) { - rec.Target = newIP.String() // replace target of first record if different + rec.SetTarget(newIP.String()) // replace target of first record if different } else if i > 0 { // any additional ips need identical records with the alternate ip added to the domain copy, err := rec.Copy() if err != nil { return err } - copy.Target = newIP.String() + copy.SetTarget(newIP.String()) domain.Records = append(domain.Records, copy) } } diff --git a/pkg/normalize/validate_test.go b/pkg/normalize/validate_test.go index 8ae596c53..2086082b8 100644 --- a/pkg/normalize/validate_test.go +++ b/pkg/normalize/validate_test.go @@ -113,12 +113,14 @@ func Test_transform_cname(t *testing.T) { func TestNSAtRoot(t *testing.T) { // do not allow ns records for @ - rec := &models.RecordConfig{Name: "test", Type: "NS", Target: "ns1.name.com."} + rec := &models.RecordConfig{Type: "NS"} + rec.SetLabel("test", "foo.com") + rec.SetTarget("ns1.name.com.") errs := checkTargets(rec, "foo.com") if len(errs) > 0 { t.Error("Expect no error with ns record on subdomain") } - rec.Name = "@" + rec.SetLabel("@", "foo.com") errs = checkTargets(rec, "foo.com") if len(errs) != 1 { t.Error("Expect error with ns record on @") @@ -138,7 +140,7 @@ func TestTransforms(t *testing.T) { for i, test := range tests { dc := &models.DomainConfig{ Records: []*models.RecordConfig{ - {Type: "A", Target: test.givenIP, Metadata: map[string]string{"transform": transform}}, + makeRC("f", "example.tld", test.givenIP, models.RecordConfig{Type: "A", Metadata: map[string]string{"transform": transform}}), }, } err := applyRecordTransforms(dc) @@ -151,8 +153,8 @@ func TestTransforms(t *testing.T) { continue } for r, rec := range dc.Records { - if rec.Target != test.expectedRecords[r] { - t.Errorf("test %d at index %d: records don't match. Expect %s but found %s.", i, r, test.expectedRecords[r], rec.Target) + if rec.GetTargetField() != test.expectedRecords[r] { + t.Errorf("test %d at index %d: records don't match. Expect %s but found %s.", i, r, test.expectedRecords[r], rec.GetTargetField()) continue } } @@ -160,7 +162,9 @@ func TestTransforms(t *testing.T) { } func TestCNAMEMutex(t *testing.T) { - var recA = &models.RecordConfig{Type: "CNAME", Name: "foo", NameFQDN: "foo.example.com", Target: "example.com."} + var recA = &models.RecordConfig{Type: "CNAME"} + recA.SetLabel("foo", "foo.example.com") + recA.SetTarget("example.com.") tests := []struct { rType string name string @@ -173,7 +177,9 @@ func TestCNAMEMutex(t *testing.T) { } for _, tst := range tests { t.Run(fmt.Sprintf("%s %s", tst.rType, tst.name), func(t *testing.T) { - var recB = &models.RecordConfig{Type: tst.rType, Name: tst.name, NameFQDN: tst.name + ".example.com", Target: "example2.com."} + var recB = &models.RecordConfig{Type: tst.rType} + recB.SetLabel(tst.name, "example.com") + recB.SetTarget("example2.com.") dc := &models.DomainConfig{ Name: "example.com", Records: []*models.RecordConfig{recA, recB}, @@ -196,7 +202,7 @@ func TestCAAValidation(t *testing.T) { Name: "example.com", RegistrarName: "BIND", Records: []*models.RecordConfig{ - {Name: "@", NameFQDN: "example.com", Type: "CAA", CaaTag: "invalid", Target: "example.com"}, + makeRC("@", "example.com", "example.com", models.RecordConfig{Type: "CAA", CaaTag: "invalid"}), }, }, }, @@ -214,7 +220,8 @@ func TestTLSAValidation(t *testing.T) { Name: "_443._tcp.example.com", RegistrarName: "BIND", Records: []*models.RecordConfig{ - {Name: "_443._tcp", NameFQDN: "_443._tcp._443._tcp.example.com", Type: "TLSA", TlsaUsage: 4, TlsaSelector: 1, TlsaMatchingType: 1, Target: "abcdef0"}, + makeRC("_443._tcp", "_443._tcp.example.com", "abcdef0", models.RecordConfig{ + Type: "TLSA", TlsaUsage: 4, TlsaSelector: 1, TlsaMatchingType: 1}), }, }, }, diff --git a/providers/activedir/domains.go b/providers/activedir/domains.go index 448b55f02..c617bf127 100644 --- a/providers/activedir/domains.go +++ b/providers/activedir/domains.go @@ -11,7 +11,6 @@ import ( "github.com/StackExchange/dnscontrol/models" "github.com/StackExchange/dnscontrol/providers/diff" "github.com/TomOnTime/utfutil" - "github.com/miekg/dns/dnsutil" "github.com/pkg/errors" ) @@ -35,7 +34,7 @@ func (c *adProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Co dc.Filter(func(r *models.RecordConfig) bool { if r.Type != "A" && r.Type != "CNAME" { - log.Printf("WARNING: Active Directory only manages A and CNAME records. Won't consider %s %s", r.Type, r.NameFQDN) + log.Printf("WARNING: Active Directory only manages A and CNAME records. Won't consider %s %s", r.Type, r.GetLabelFQDN()) return false } return true @@ -162,18 +161,16 @@ func (c *adProvider) getExistingRecords(domainname string) ([]*models.RecordConf } func (r *RecordConfigJson) unpackRecord(origin string) *models.RecordConfig { - rc := models.RecordConfig{} - - rc.Name = strings.ToLower(r.Name) - rc.NameFQDN = dnsutil.AddOrigin(rc.Name, origin) - rc.Type = r.Type - rc.TTL = r.TTL - - switch rc.Type { // #rtype_variations - case "A": - rc.Target = r.Data + rc := models.RecordConfig{ + Type: r.Type, + TTL: r.TTL, + } + rc.SetLabel(r.Name, origin) + switch rtype := rc.Type; rtype { // #rtype_variations + case "A", "AAAA": + rc.SetTarget(r.Data) case "CNAME": - rc.Target = strings.ToLower(r.Data) + rc.SetTarget(strings.ToLower(r.Data)) case "NS", "SOA": return nil default: @@ -197,12 +194,12 @@ Get-DnsServerResourceRecord -ComputerName REPLACE_WITH_COMPUTER_NAME -ZoneName $ // generatePowerShellCreate generates PowerShell commands to ADD a record. func (c *adProvider) generatePowerShellCreate(domainname string, rec *models.RecordConfig) string { - content := rec.Target + content := rec.GetTargetField() text := "\r\n" // Skip a line. text += fmt.Sprintf("Add-DnsServerResourceRecord%s", rec.Type) text += fmt.Sprintf(` -ComputerName "%s"`, c.adServer) text += fmt.Sprintf(` -ZoneName "%s"`, domainname) - text += fmt.Sprintf(` -Name "%s"`, rec.Name) + text += fmt.Sprintf(` -Name "%s"`, rec.GetLabel()) text += fmt.Sprintf(` -TimeToLive $(New-TimeSpan -Seconds %d)`, rec.TTL) switch rec.Type { // #rtype_variations case "CNAME": @@ -210,9 +207,10 @@ func (c *adProvider) generatePowerShellCreate(domainname string, rec *models.Rec case "A": text += fmt.Sprintf(` -IPv4Address "%s"`, content) case "NS": - text = fmt.Sprintf("\r\n"+`echo "Skipping NS update (%v %v)"`+"\r\n", rec.Name, rec.Target) + text = fmt.Sprintf("\r\n"+`echo "Skipping NS update (%v %v)"`+"\r\n", rec.GetLabel(), rec.GetTargetDebug()) default: - panic(errors.Errorf("generatePowerShellCreate() does not yet handle recType=%s recName=%#v content=%#v)", rec.Type, rec.Name, content)) + panic(errors.Errorf("generatePowerShellCreate() does not yet handle recType=%s recName=%#v content=%#v)", + rec.Type, rec.GetLabel(), content)) // We panic so that we quickly find any switch statements // that have not been updated for a new RR type. } @@ -286,7 +284,7 @@ func (c *adProvider) generatePowerShellDelete(domainname, recName, recType, cont func (c *adProvider) createRec(domainname string, rec *models.RecordConfig) []*models.Correction { arr := []*models.Correction{ { - Msg: fmt.Sprintf("CREATE record: %s %s ttl(%d) %s", rec.Name, rec.Type, rec.TTL, rec.Target), + Msg: fmt.Sprintf("CREATE record: %s %s ttl(%d) %s", rec.GetLabel(), rec.Type, rec.TTL, rec.GetTargetField()), F: func() error { return c.powerShellDoCommand(c.generatePowerShellCreate(domainname, rec), true) }}, @@ -299,16 +297,16 @@ func (c *adProvider) modifyRec(domainname string, m diff.Correlation) *models.Co return &models.Correction{ Msg: m.String(), F: func() error { - return c.powerShellDoCommand(c.generatePowerShellModify(domainname, rec.Name, rec.Type, old.Target, rec.Target, old.TTL, rec.TTL), true) + return c.powerShellDoCommand(c.generatePowerShellModify(domainname, rec.GetLabel(), rec.Type, old.GetTargetField(), rec.GetTargetField(), old.TTL, rec.TTL), true) }, } } func (c *adProvider) deleteRec(domainname string, rec *models.RecordConfig) *models.Correction { return &models.Correction{ - Msg: fmt.Sprintf("DELETE record: %s %s ttl(%d) %s", rec.Name, rec.Type, rec.TTL, rec.Target), + Msg: fmt.Sprintf("DELETE record: %s %s ttl(%d) %s", rec.GetLabel(), rec.Type, rec.TTL, rec.GetTargetField()), F: func() error { - return c.powerShellDoCommand(c.generatePowerShellDelete(domainname, rec.Name, rec.Type, rec.Target), true) + return c.powerShellDoCommand(c.generatePowerShellDelete(domainname, rec.GetLabel(), rec.Type, rec.GetTargetField()), true) }, } } diff --git a/providers/activedir/domains_test.go b/providers/activedir/domains_test.go index c19001caf..cf9fe025d 100644 --- a/providers/activedir/domains_test.go +++ b/providers/activedir/domains_test.go @@ -7,6 +7,12 @@ import ( "github.com/StackExchange/dnscontrol/models" ) +func makeRC(label, domain, target string, rc models.RecordConfig) *models.RecordConfig { + rc.SetLabel(label, domain) + rc.SetTarget(target) + return &rc +} + func TestGetExistingRecords(t *testing.T) { cf := &adProvider{} @@ -17,11 +23,11 @@ func TestGetExistingRecords(t *testing.T) { t.Fatal(err) } expected := []*models.RecordConfig{ - {Name: "@", NameFQDN: "test2", Type: "A", TTL: 600, Target: "10.166.2.11"}, - //{Name: "_msdcs", NameFQDN: "_msdcs.test2", Type: "NS", TTL: 300, Target: "other_record"}, // Will be filtered. - {Name: "co-devsearch02", NameFQDN: "co-devsearch02.test2", Type: "A", TTL: 3600, Target: "10.8.2.64"}, - {Name: "co-devservice01", NameFQDN: "co-devservice01.test2", Type: "A", TTL: 1200, Target: "10.8.2.48"}, // Downcased. - {Name: "yum", NameFQDN: "yum.test2", Type: "A", TTL: 3600, Target: "10.8.0.59"}, + makeRC("@", "test2", "10.166.2.11", models.RecordConfig{Type: "A", TTL: 600}), + //makeRC("_msdcs", "test2", "other_record", models.RecordConfig{Type: "NS", TTL: 300}), // Will be filtered. + makeRC("co-devsearch02", "test2", "10.8.2.64", models.RecordConfig{Type: "A", TTL: 3600}), + makeRC("co-devservice01", "test2", "10.8.2.48", models.RecordConfig{Type: "A", TTL: 1200}), // Downcased. + makeRC("yum", "test2", "10.8.0.59", models.RecordConfig{Type: "A", TTL: 3600}), } actualS := "" diff --git a/providers/bind/bindProvider.go b/providers/bind/bindProvider.go index e357a7352..f2c8ad1e6 100644 --- a/providers/bind/bindProvider.go +++ b/providers/bind/bindProvider.go @@ -127,7 +127,7 @@ func rrToRecord(rr dns.RR, origin string, replaceSerial uint32) (models.RecordCo } newSerial = v.Serial //if (dnsutil.TrimDomainName(rc.Name, origin+".") == "@") && replaceSerial != 0 { - if rc.Name == "@" && replaceSerial != 0 { + if rc.GetLabel() == "@" && replaceSerial != 0 { newSerial = replaceSerial } panicInvalid(rc.SetTarget( diff --git a/providers/cloudflare/preprocess_test.go b/providers/cloudflare/preprocess_test.go index 1aeb3e6aa..4253099c6 100644 --- a/providers/cloudflare/preprocess_test.go +++ b/providers/cloudflare/preprocess_test.go @@ -16,14 +16,25 @@ func newDomainConfig() *models.DomainConfig { } } +func makeRCmeta(meta map[string]string) *models.RecordConfig { + rc := models.RecordConfig{ + Type: "A", + Metadata: meta, + } + rc.SetLabel("foo", "example.tld") + rc.SetTarget("1.2.3.4") + return &rc +} + func TestPreprocess_BoolValidation(t *testing.T) { cf := &CloudflareApi{} + domain := newDomainConfig() - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{metaProxy: "on"}}) - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{metaProxy: "fUll"}}) - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{}}) - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{metaProxy: "Off"}}) - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{metaProxy: "off"}}) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{metaProxy: "on"})) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{metaProxy: "fUll"})) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{})) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{metaProxy: "Off"})) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{metaProxy: "off"})) err := cf.preprocessConfig(domain) if err != nil { t.Fatal(err) @@ -51,9 +62,9 @@ func TestPreprocess_DefaultProxy(t *testing.T) { cf := &CloudflareApi{} domain := newDomainConfig() domain.Metadata[metaProxyDefault] = "full" - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{metaProxy: "on"}}) - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{metaProxy: "off"}}) - domain.Records = append(domain.Records, &models.RecordConfig{Type: "A", Target: "1.2.3.4", Metadata: map[string]string{}}) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{metaProxy: "on"})) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{metaProxy: "off"})) + domain.Records = append(domain.Records, makeRCmeta(map[string]string{})) err := cf.preprocessConfig(domain) if err != nil { t.Fatal(err) @@ -97,7 +108,8 @@ func TestIpRewriting(t *testing.T) { NewBases: []net.IP{net.ParseIP("255.255.255.0")}, NewIPs: nil}} for _, tst := range tests { - rec := &models.RecordConfig{Type: "A", Target: tst.Given, Metadata: map[string]string{metaProxy: tst.Proxy}} + rec := &models.RecordConfig{Type: "A", Metadata: map[string]string{metaProxy: tst.Proxy}} + rec.SetTarget(tst.Given) domain.Records = append(domain.Records, rec) } err := cf.preprocessConfig(domain) @@ -106,8 +118,8 @@ func TestIpRewriting(t *testing.T) { } for i, tst := range tests { rec := domain.Records[i] - if rec.Target != tst.Expected { - t.Fatalf("At index %d, expected target of %s, but found %s.", i, tst.Expected, rec.Target) + if rec.GetTargetField() != tst.Expected { + t.Fatalf("At index %d, expected target of %s, but found %s.", i, tst.Expected, rec.GetTargetField()) } if tst.Proxy == "full" && tst.Given != tst.Expected && rec.Metadata[metaOriginalIP] != tst.Given { t.Fatalf("At index %d, expected original_ip to be set", i) diff --git a/providers/diff/diff.go b/providers/diff/diff.go index f2c01b558..093a6f8bf 100644 --- a/providers/diff/diff.go +++ b/providers/diff/diff.go @@ -77,7 +77,7 @@ func (d *differ) IncrementalDiff(existing []*models.RecordConfig) (unchanged, cr if d.matchIgnored(e.GetLabel()) { log.Printf("Ignoring record %s %s due to IGNORE", e.GetLabel(), e.Type) } else { - k := key{e.NameFQDN, e.Type} + k := key{e.GetLabelFQDN(), e.Type} existingByNameAndType[k] = append(existingByNameAndType[k], e) } } @@ -85,7 +85,7 @@ func (d *differ) IncrementalDiff(existing []*models.RecordConfig) (unchanged, cr if d.matchIgnored(dr.GetLabel()) { panic(fmt.Sprintf("Trying to update/add IGNOREd record: %s %s", dr.GetLabel(), dr.Type)) } else { - k := key{dr.NameFQDN, dr.Type} + k := key{dr.GetLabelFQDN(), dr.Type} desiredByNameAndType[k] = append(desiredByNameAndType[k], dr) } } @@ -106,7 +106,7 @@ func (d *differ) IncrementalDiff(existing []*models.RecordConfig) (unchanged, cr for i := len(existingRecords) - 1; i >= 0; i-- { ex := existingRecords[i] for j, de := range desiredRecords { - if de.Target == ex.Target { + if de.GetTargetField() == ex.GetTargetField() { // they're either identical or should be a modification of each other (ttl or metadata changes) if d.content(de) == d.content(ex) { unchanged = append(unchanged, Correlation{d, ex, de}) @@ -197,12 +197,12 @@ func (d *differ) ChangedGroups(existing []*models.RecordConfig) map[models.Recor func (c Correlation) String() string { if c.Existing == nil { - return fmt.Sprintf("CREATE %s %s %s", c.Desired.Type, c.Desired.NameFQDN, c.d.content(c.Desired)) + return fmt.Sprintf("CREATE %s %s %s", c.Desired.Type, c.Desired.GetLabelFQDN(), c.d.content(c.Desired)) } if c.Desired == nil { - return fmt.Sprintf("DELETE %s %s %s", c.Existing.Type, c.Existing.NameFQDN, c.d.content(c.Existing)) + return fmt.Sprintf("DELETE %s %s %s", c.Existing.Type, c.Existing.GetLabelFQDN(), c.d.content(c.Existing)) } - return fmt.Sprintf("MODIFY %s %s: (%s) -> (%s)", c.Existing.Type, c.Existing.NameFQDN, c.d.content(c.Existing), c.d.content(c.Desired)) + return fmt.Sprintf("MODIFY %s %s: (%s) -> (%s)", c.Existing.Type, c.Existing.GetLabelFQDN(), c.d.content(c.Existing), c.d.content(c.Desired)) } func sortedKeys(m map[string]*models.RecordConfig) []string { diff --git a/providers/diff/diff_test.go b/providers/diff/diff_test.go index 6c9f59377..0d116166f 100644 --- a/providers/diff/diff_test.go +++ b/providers/diff/diff_test.go @@ -7,20 +7,19 @@ import ( "testing" "github.com/StackExchange/dnscontrol/models" - "github.com/miekg/dns/dnsutil" ) func myRecord(s string) *models.RecordConfig { parts := strings.Split(s, " ") ttl, _ := strconv.ParseUint(parts[2], 10, 32) - return &models.RecordConfig{ - Name: parts[0], - NameFQDN: dnsutil.AddOrigin(parts[0], "example.com"), + r := &models.RecordConfig{ Type: parts[1], TTL: uint32(ttl), - Target: parts[3], Metadata: map[string]string{}, } + r.SetLabel(parts[0], "example.com") + r.SetTarget(parts[3]) + return r } func TestAdditionsOnly(t *testing.T) { diff --git a/providers/digitalocean/digitaloceanProvider.go b/providers/digitalocean/digitaloceanProvider.go index 41a49610f..e6d34c43e 100644 --- a/providers/digitalocean/digitaloceanProvider.go +++ b/providers/digitalocean/digitaloceanProvider.go @@ -203,7 +203,6 @@ func toRc(dc *models.DomainConfig, r *godo.DomainRecord) *models.RecordConfig { t := &models.RecordConfig{ Type: r.Type, - Target: target, TTL: uint32(r.TTL), MxPreference: uint16(r.Priority), SrvPriority: uint16(r.Priority), @@ -212,6 +211,7 @@ func toRc(dc *models.DomainConfig, r *godo.DomainRecord) *models.RecordConfig { Original: r, } t.SetLabelFromFQDN(name, dc.Name) + t.SetTarget(target) switch rtype := r.Type; rtype { case "TXT": t.SetTargetTXTString(target) diff --git a/providers/dnsimple/dnsimpleProvider.go b/providers/dnsimple/dnsimpleProvider.go index 1a75d2929..9a7dc8669 100644 --- a/providers/dnsimple/dnsimpleProvider.go +++ b/providers/dnsimple/dnsimpleProvider.go @@ -10,7 +10,6 @@ import ( "github.com/StackExchange/dnscontrol/models" "github.com/StackExchange/dnscontrol/providers" "github.com/StackExchange/dnscontrol/providers/diff" - "github.com/miekg/dns/dnsutil" "github.com/pkg/errors" dnsimpleapi "github.com/dnsimple/dnsimple-go/dnsimple" @@ -281,7 +280,7 @@ func (c *DnsimpleApi) createRecordFunc(rc *models.RecordConfig, domainName strin return err } record := dnsimpleapi.ZoneRecord{ - Name: dnsutil.TrimDomainName(rc.NameFQDN, domainName), + Name: rc.GetLabel(), Type: rc.Type, Content: rc.GetTargetCombined(), TTL: int(rc.TTL), @@ -327,7 +326,7 @@ func (c *DnsimpleApi) updateRecordFunc(old *dnsimpleapi.ZoneRecord, rc *models.R } record := dnsimpleapi.ZoneRecord{ - Name: dnsutil.TrimDomainName(rc.NameFQDN, domainName), + Name: rc.GetLabel(), Type: rc.Type, Content: rc.GetTargetCombined(), TTL: int(rc.TTL), @@ -374,7 +373,7 @@ func removeOtherNS(dc *models.DomainConfig) { for _, rec := range dc.Records { if rec.Type == "NS" { // apex NS inside dnsimple are expected. - if rec.NameFQDN == dc.Name && strings.HasSuffix(rec.GetTargetField(), ".dnsimple.com.") { + if rec.GetLabelFQDN() == dc.Name && strings.HasSuffix(rec.GetTargetField(), ".dnsimple.com.") { continue } fmt.Printf("Warning: dnsimple.com does not allow NS records to be modified. %s will not be added.\n", rec.GetTargetField()) diff --git a/providers/gandi/gandiProvider.go b/providers/gandi/gandiProvider.go index 1dda1aad1..6622c55b6 100644 --- a/providers/gandi/gandiProvider.go +++ b/providers/gandi/gandiProvider.go @@ -99,11 +99,11 @@ func (c *GandiApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Corr return nil, errors.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL) } if rec.Type == "TXT" { - rec.Target = "\"" + rec.Target + "\"" // FIXME(tlim): Should do proper quoting. + rec.SetTarget("\"" + rec.GetTargetField() + "\"") // FIXME(tlim): Should do proper quoting. } if rec.Type == "NS" && rec.GetLabel() == "@" { - if !strings.HasSuffix(rec.Target, ".gandi.net.") { - log.Printf("WARNING: Gandi does not support changing apex NS records. %s will not be added.", rec.Target) + if !strings.HasSuffix(rec.GetTargetField(), ".gandi.net.") { + log.Printf("WARNING: Gandi does not support changing apex NS records. %s will not be added.", rec.GetTargetField()) } continue } diff --git a/providers/gandi/livedns.go b/providers/gandi/livedns.go index 04cd81d87..358ffc72d 100644 --- a/providers/gandi/livedns.go +++ b/providers/gandi/livedns.go @@ -223,31 +223,31 @@ func (c *liveClient) recordsToInfo(records models.Records) (models.Records, []*g for _, rec := range records { if rec.TTL < 300 { - log.Printf("WARNING: Gandi does not support ttls < 300. %s will not be set to %d.", rec.NameFQDN, rec.TTL) + log.Printf("WARNING: Gandi does not support ttls < 300. %s will not be set to %d.", rec.GetLabelFQDN(), rec.TTL) rec.TTL = 300 } if rec.TTL > 2592000 { return nil, nil, errors.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL) } - if rec.Type == "NS" && rec.Name == "@" { - if !strings.HasSuffix(rec.Target, ".gandi.net.") { - log.Printf("WARNING: Gandi does not support changing apex NS records. %s will not be added.", rec.Target) + if rec.Type == "NS" && rec.GetLabel() == "@" { + if !strings.HasSuffix(rec.GetTargetField(), ".gandi.net.") { + log.Printf("WARNING: Gandi does not support changing apex NS records. %s will not be added.", rec.GetTargetField()) } continue } - r, ok := recordSets[rec.Name][rec.Type] + r, ok := recordSets[rec.GetLabel()][rec.Type] if !ok { - _, ok := recordSets[rec.Name] + _, ok := recordSets[rec.GetLabel()] if !ok { - recordSets[rec.Name] = map[string]*gandiliverecord.Info{} + recordSets[rec.GetLabel()] = map[string]*gandiliverecord.Info{} } r = &gandiliverecord.Info{ Type: rec.Type, - Name: rec.Name, + Name: rec.GetLabel(), TTL: int64(rec.TTL), } recordInfos = append(recordInfos, r) - recordSets[rec.Name][rec.Type] = r + recordSets[rec.GetLabel()][rec.Type] = r } else { if r.TTL != int64(rec.TTL) { log.Printf( diff --git a/providers/gandi/livedns_test.go b/providers/gandi/livedns_test.go index 7389d1efe..9dffd5f0f 100644 --- a/providers/gandi/livedns_test.go +++ b/providers/gandi/livedns_test.go @@ -8,6 +8,11 @@ import ( "github.com/stretchr/testify/assert" ) +func makeRC(label, domain, target string, rc models.RecordConfig) *models.RecordConfig { + rc.SetLabel(label, domain) + rc.SetTarget(target) + return &rc +} func TestRecordConfigFromInfo(t *testing.T) { for _, data := range []struct { @@ -22,20 +27,14 @@ func TestRecordConfigFromInfo(t *testing.T) { Values: []string{"127.0.0.1", "127.1.0.1"}, }, []*models.RecordConfig{ - { - NameFQDN: "www.example.com", - Name: "www", - Type: "A", - Target: "127.0.0.1", - TTL: 500, - }, - { - NameFQDN: "www.example.com", - Name: "www", - Type: "A", - Target: "127.1.0.1", - TTL: 500, - }, + makeRC("www", "example.com", "127.0.0.1", models.RecordConfig{ + Type: "A", + TTL: 500, + }), + makeRC("www", "example.com", "127.1.0.1", models.RecordConfig{ + Type: "A", + TTL: 500, + }), }, }, { @@ -46,14 +45,11 @@ func TestRecordConfigFromInfo(t *testing.T) { Values: []string{"\"test 2\"", "\"test message test message test message\""}, }, []*models.RecordConfig{ - { - NameFQDN: "www.example.com", - Name: "www", + makeRC("www", "example.com", "test 2", models.RecordConfig{ Type: "TXT", - Target: "test 2", TxtStrings: []string{"test 2", "test message test message test message"}, TTL: 500, - }, + }), }, }, { @@ -65,24 +61,18 @@ func TestRecordConfigFromInfo(t *testing.T) { Values: []string{"0 issue \"www.certinomis.com\"", "0 issuewild \"buypass.com\""}, }, []*models.RecordConfig{ - { - NameFQDN: "www.example.com", - Name: "www", - Type: "CAA", - Target: "www.certinomis.com", - CaaFlag: 0, - CaaTag: "issue", - TTL: 500, - }, - { - NameFQDN: "www.example.com", - Name: "www", - Type: "CAA", - Target: "buypass.com", - CaaFlag: 0, - CaaTag: "issuewild", - TTL: 500, - }, + makeRC("www", "example.com", "www.certinomis.com", models.RecordConfig{ + Type: "CAA", + CaaFlag: 0, + CaaTag: "issue", + TTL: 500, + }), + makeRC("www", "example.com", "buypass.com", models.RecordConfig{ + Type: "CAA", + CaaFlag: 0, + CaaTag: "issuewild", + TTL: 500, + }), }, }, { @@ -93,16 +83,13 @@ func TestRecordConfigFromInfo(t *testing.T) { Values: []string{"20 0 5060 backupbox.example.com."}, }, []*models.RecordConfig{ - { - NameFQDN: "test.example.com", - Name: "test", + makeRC("test", "example.com", "backupbox.example.com.", models.RecordConfig{ Type: "SRV", - Target: "backupbox.example.com.", SrvPriority: 20, SrvWeight: 0, SrvPort: 5060, TTL: 500, - }, + }), }, }, { @@ -113,22 +100,16 @@ func TestRecordConfigFromInfo(t *testing.T) { Values: []string{"50 fb.mail.gandi.net.", "10 spool.mail.gandi.net."}, }, []*models.RecordConfig{ - { - NameFQDN: "mail.example.com", - Name: "mail", + makeRC("mail", "example.com", "fb.mail.gandi.net.", models.RecordConfig{ Type: "MX", MxPreference: 50, - Target: "fb.mail.gandi.net.", TTL: 500, - }, - { - NameFQDN: "mail.example.com", - Name: "mail", + }), + makeRC("mail", "example.com", "spool.mail.gandi.net.", models.RecordConfig{ Type: "MX", MxPreference: 10, - Target: "spool.mail.gandi.net.", TTL: 500, - }, + }), }, }, } { diff --git a/providers/gcloud/gcloudProvider.go b/providers/gcloud/gcloudProvider.go index 36eea1898..54171b3f9 100644 --- a/providers/gcloud/gcloudProvider.go +++ b/providers/gcloud/gcloudProvider.go @@ -104,7 +104,7 @@ func keyFor(r *gdns.ResourceRecordSet) key { return key{Type: r.Type, Name: r.Name} } func keyForRec(r *models.RecordConfig) key { - return key{Type: r.Type, Name: r.NameFQDN + "."} + return key{Type: r.Type, Name: r.GetLabelFQDN() + "."} } func (g *gcloud) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { diff --git a/providers/linode/linodeProvider.go b/providers/linode/linodeProvider.go index 407150a3f..47c1c9148 100644 --- a/providers/linode/linodeProvider.go +++ b/providers/linode/linodeProvider.go @@ -136,10 +136,10 @@ func (api *LinodeApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C // https://github.com/linode/manager/blob/edd99dc4e1be5ab8190f243c3dbf8b830716255e/src/constants.js#L184 for _, name := range defaultNameServerNames { rc := &models.RecordConfig{ - NameFQDN: dc.Name, Type: "NS", Original: &domainRecord{}, } + rc.SetLabelFromFQDN(dc.Name, dc.Name) rc.SetTarget(name) existingRecords = append(existingRecords, rc) @@ -249,7 +249,7 @@ func toRc(dc *models.DomainConfig, r *domainRecord) *models.RecordConfig { func toReq(dc *models.DomainConfig, rc *models.RecordConfig) (*recordEditRequest, error) { req := &recordEditRequest{ Type: rc.Type, - Name: dnsutil.TrimDomainName(rc.NameFQDN, dc.Name), + Name: rc.GetLabel(), Target: rc.GetTargetField(), TTL: int(rc.TTL), Priority: 0, diff --git a/providers/namecheap/namecheapProvider.go b/providers/namecheap/namecheapProvider.go index 5d2e46e2b..c196cb200 100644 --- a/providers/namecheap/namecheapProvider.go +++ b/providers/namecheap/namecheapProvider.go @@ -14,7 +14,6 @@ import ( "github.com/StackExchange/dnscontrol/providers" "github.com/StackExchange/dnscontrol/providers/diff" nc "github.com/billputer/go-namecheap" - "github.com/miekg/dns/dnsutil" "github.com/pkg/errors" ) @@ -125,9 +124,9 @@ func (n *Namecheap) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Cor // namecheap does not allow setting @ NS with basic DNS dc.Filter(func(r *models.RecordConfig) bool { - if r.Type == "NS" && r.Name == "@" { - if !strings.HasSuffix(r.Target, "registrar-servers.com.") { - fmt.Println("\n", r.Target, "Namecheap does not support changing apex NS records. Skipping.") + if r.Type == "NS" && r.GetLabel() == "@" { + if !strings.HasSuffix(r.GetTargetField(), "registrar-servers.com.") { + fmt.Println("\n", r.GetTargetField(), "Namecheap does not support changing apex NS records. Skipping.") } return false } @@ -150,13 +149,13 @@ func (n *Namecheap) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Cor continue } rec := &models.RecordConfig{ - NameFQDN: dnsutil.AddOrigin(r.Name, dc.Name), Type: r.Type, - Target: r.Address, TTL: uint32(r.TTL), MxPreference: uint16(r.MXPref), Original: r, } + rec.SetLabel(r.Name, dc.Name) + rec.SetTarget(r.Address) actual = append(actual, rec) } @@ -204,12 +203,11 @@ func (n *Namecheap) generateRecords(dc *models.DomainConfig) error { id := 1 for _, r := range dc.Records { - name := dnsutil.TrimDomainName(r.NameFQDN, dc.Name) rec := nc.DomainDNSHost{ ID: id, - Name: name, + Name: r.GetLabel(), Type: r.Type, - Address: r.Target, + Address: r.GetTargetField(), MXPref: int(r.MxPreference), TTL: int(r.TTL), } diff --git a/providers/namedotcom/records.go b/providers/namedotcom/records.go index a045e9d4a..22cca72b0 100644 --- a/providers/namedotcom/records.go +++ b/providers/namedotcom/records.go @@ -8,8 +8,6 @@ import ( "github.com/namedotcom/go/namecom" "github.com/pkg/errors" - "github.com/miekg/dns/dnsutil" - "github.com/StackExchange/dnscontrol/models" "github.com/StackExchange/dnscontrol/providers/diff" ) @@ -76,7 +74,7 @@ func (n *NameCom) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Corre func checkNSModifications(dc *models.DomainConfig) { newList := make([]*models.RecordConfig, 0, len(dc.Records)) for _, rec := range dc.Records { - if rec.Type == "NS" && rec.NameFQDN == dc.Name { + if rec.Type == "NS" && rec.GetLabel() == "@" { continue // Apex NS records are automatically created for the domain's nameservers and cannot be managed otherwise via the name.com API. } newList = append(newList, rec) @@ -147,9 +145,9 @@ func (n *NameCom) getRecords(domain string) ([]*namecom.Record, error) { func (n *NameCom) createRecord(rc *models.RecordConfig, domain string) error { record := &namecom.Record{ DomainName: domain, - Host: dnsutil.TrimDomainName(rc.NameFQDN, domain), + Host: rc.GetLabel(), Type: rc.Type, - Answer: rc.Target, + Answer: rc.GetTargetField(), TTL: rc.TTL, Priority: uint32(rc.MxPreference), } @@ -159,7 +157,7 @@ func (n *NameCom) createRecord(rc *models.RecordConfig, domain string) error { case "TXT": record.Answer = encodeTxt(rc.TxtStrings) case "SRV": - record.Answer = fmt.Sprintf("%d %d %v", rc.SrvWeight, rc.SrvPort, rc.Target) + record.Answer = fmt.Sprintf("%d %d %v", rc.SrvWeight, rc.SrvPort, rc.GetTargetField()) record.Priority = uint32(rc.SrvPriority) default: panic(fmt.Sprintf("createRecord rtype %v unimplemented", rc.Type)) diff --git a/providers/octodns/octoyaml/read.go b/providers/octodns/octoyaml/read.go index 88bdaf74a..485c973d6 100644 --- a/providers/octodns/octoyaml/read.go +++ b/providers/octodns/octoyaml/read.go @@ -178,7 +178,7 @@ func parseLeaf(results models.Records, k string, v interface{}, origin string) ( case "port": // SRV newRc.SrvPort = uint16(v4.(int)) case "value": // MX - newRc.Target = v4.(string) + newRc.SetTarget(v4.(string)) } } //fmt.Printf("parseLeaf: append %v\n", newRc) diff --git a/providers/octodns/octoyaml/rw_test.go b/providers/octodns/octoyaml/rw_test.go index 15cbf0930..32c81b62a 100644 --- a/providers/octodns/octoyaml/rw_test.go +++ b/providers/octodns/octoyaml/rw_test.go @@ -56,7 +56,9 @@ func TestYamlWrite(t *testing.T) { m.AddFunc("json", minjson.Minify) t.Run(f.Name(), func(t *testing.T) { - content, err := ioutil.ReadFile(filepath.Join(testDir, f.Name())) + fname := filepath.Join(testDir, f.Name()) + fmt.Printf("Filename: %v\n", fname) + content, err := ioutil.ReadFile(fname) if err != nil { t.Fatal(err) } diff --git a/providers/octodns/octoyaml/sort.go b/providers/octodns/octoyaml/sort.go index d8dd7403e..8e85a6f72 100644 --- a/providers/octodns/octoyaml/sort.go +++ b/providers/octodns/octoyaml/sort.go @@ -48,14 +48,14 @@ func (z *genYamlData) Less(i, j int) bool { case "NS", "TXT", "TLSA": // pass through. case "A": - ta2, tb2 := net.ParseIP(a.Target), net.ParseIP(b.Target) + ta2, tb2 := net.ParseIP(a.GetTargetField()), net.ParseIP(b.GetTargetField()) ipa, ipb := ta2.To4(), tb2.To4() if ipa == nil || ipb == nil { log.Fatalf("should not happen: IPs are not 4 bytes: %#v %#v", ta2, tb2) } return bytes.Compare(ipa, ipb) == -1 case "AAAA": - ta2, tb2 := net.ParseIP(a.Target), net.ParseIP(b.Target) + ta2, tb2 := net.ParseIP(a.GetTargetField()), net.ParseIP(b.GetTargetField()) ipa, ipb := ta2.To16(), tb2.To16() return bytes.Compare(ipa, ipb) == -1 case "MX": @@ -75,7 +75,7 @@ func (z *genYamlData) Less(i, j int) bool { return pa < pb } case "PTR": - pa, pb := a.Target, b.Target + pa, pb := a.GetTargetField(), b.GetTargetField() if pa != pb { return pa < pb } diff --git a/providers/octodns/octoyaml/write.go b/providers/octodns/octoyaml/write.go index 5597ab1e7..6cd243e7f 100644 --- a/providers/octodns/octoyaml/write.go +++ b/providers/octodns/octoyaml/write.go @@ -28,8 +28,9 @@ func WriteYaml(w io.Writer, records models.Records, origin string) error { recsCopy = append(recsCopy, r) } for _, r := range recsCopy { - if r.Name == "@" { - r.Name = "" + if r.GetLabel() == "@" { + //r.Name = "" + r.UnsafeSetLabelNull() } } @@ -156,7 +157,7 @@ func sameType(records models.Records) bool { func oneLabel(records models.Records) yaml.MapItem { item := yaml.MapItem{ // a yaml.MapItem is a YAML map that retains the key order. - Key: records[0].Name, + Key: records[0].GetLabel(), } // Special case labels with a single record: if len(records) == 1 { diff --git a/providers/ovh/protocol.go b/providers/ovh/protocol.go index 7f99b40c0..4d63ecc18 100644 --- a/providers/ovh/protocol.go +++ b/providers/ovh/protocol.go @@ -112,7 +112,7 @@ func (c *ovhProvider) deleteRecordFunc(id int64, fqdn string) func() error { func (c *ovhProvider) createRecordFunc(rc *models.RecordConfig, fqdn string) func() error { return func() error { record := Record{ - SubDomain: dnsutil.TrimDomainName(rc.NameFQDN, fqdn), + SubDomain: dnsutil.TrimDomainName(rc.GetLabelFQDN(), fqdn), FieldType: rc.Type, Target: rc.GetTargetCombined(), TTL: rc.TTL, @@ -130,7 +130,7 @@ func (c *ovhProvider) createRecordFunc(rc *models.RecordConfig, fqdn string) fun func (c *ovhProvider) updateRecordFunc(old *Record, rc *models.RecordConfig, fqdn string) func() error { return func() error { record := Record{ - SubDomain: dnsutil.TrimDomainName(rc.NameFQDN, fqdn), + SubDomain: rc.GetLabel(), FieldType: rc.Type, Target: rc.GetTargetCombined(), TTL: rc.TTL, diff --git a/providers/softlayer/softlayerProvider.go b/providers/softlayer/softlayerProvider.go index 00a9e44fb..fc86e8f46 100644 --- a/providers/softlayer/softlayerProvider.go +++ b/providers/softlayer/softlayerProvider.go @@ -9,7 +9,6 @@ import ( "github.com/StackExchange/dnscontrol/models" "github.com/StackExchange/dnscontrol/providers" "github.com/StackExchange/dnscontrol/providers/diff" - "github.com/miekg/dns/dnsutil" "github.com/pkg/errors" "github.com/softlayer/softlayer-go/datatypes" @@ -129,10 +128,10 @@ func (s *SoftLayer) getExistingRecords(domain *datatypes.Dns_Domain) ([]*models. recConfig := &models.RecordConfig{ Type: recType, - Target: *record.Data, TTL: uint32(*record.Ttl), Original: record, } + recConfig.SetTarget(*record.Data) switch recType { case "SRV": @@ -153,21 +152,16 @@ func (s *SoftLayer) getExistingRecords(domain *datatypes.Dns_Domain) ([]*models. if record.Service != nil { service = *record.Service } - - recConfig.Name = fmt.Sprintf("%s.%s", service, strings.ToLower(protocol)) - + recConfig.SetLabel(fmt.Sprintf("%s.%s", service, strings.ToLower(protocol)), *domain.Name) case "MX": if record.MxPriority != nil { recConfig.MxPreference = uint16(*record.MxPriority) } - fallthrough - default: - recConfig.Name = *record.Host + recConfig.SetLabel(*record.Host, *domain.Name) } - recConfig.NameFQDN = dnsutil.AddOrigin(recConfig.Name, *domain.Name) actual = append(actual, recConfig) } @@ -180,7 +174,7 @@ func (s *SoftLayer) getExistingRecords(domain *datatypes.Dns_Domain) ([]*models. func (s *SoftLayer) createRecordFunc(desired *models.RecordConfig, domain *datatypes.Dns_Domain) func() error { var ttl, preference, domainID int = int(desired.TTL), int(desired.MxPreference), *domain.Id var weight, priority, port int = int(desired.SrvWeight), int(desired.SrvPriority), int(desired.SrvPort) - var host, data, newType string = desired.Name, desired.Target, desired.Type + var host, data, newType string = desired.GetLabel(), desired.GetTargetField(), desired.Type var err error srvRegexp := regexp.MustCompile(`^_(?P\w+)\.\_(?P\w+)$`) @@ -260,13 +254,15 @@ func (s *SoftLayer) updateRecordFunc(existing *datatypes.Dns_Domain_ResourceReco service := services.GetDnsDomainResourceRecordMxTypeService(s.Session) updated := datatypes.Dns_Domain_ResourceRecord_MxType{} - if desired.Name != *existing.Host { - updated.Host = &desired.Name + label := desired.GetLabel() + if label != *existing.Host { + updated.Host = &label changes = true } - if desired.Target != *existing.Data { - updated.Data = &desired.Target + target := desired.GetTargetField() + if target != *existing.Data { + updated.Data = &target changes = true } @@ -290,13 +286,15 @@ func (s *SoftLayer) updateRecordFunc(existing *datatypes.Dns_Domain_ResourceReco service := services.GetDnsDomainResourceRecordSrvTypeService(s.Session) updated := datatypes.Dns_Domain_ResourceRecord_SrvType{} - if desired.Name != *existing.Host { - updated.Host = &desired.Name + label := desired.GetLabel() + if label != *existing.Host { + updated.Host = &label changes = true } - if desired.Target != *existing.Data { - updated.Data = &desired.Target + target := desired.GetTargetField() + if target != *existing.Data { + updated.Data = &target changes = true } @@ -333,13 +331,15 @@ func (s *SoftLayer) updateRecordFunc(existing *datatypes.Dns_Domain_ResourceReco service := services.GetDnsDomainResourceRecordService(s.Session) updated := datatypes.Dns_Domain_ResourceRecord{} - if desired.Name != *existing.Host { - updated.Host = &desired.Name + label := desired.GetLabel() + if label != *existing.Host { + updated.Host = &label changes = true } - if desired.Target != *existing.Data { - updated.Data = &desired.Target + target := desired.GetTargetField() + if target != *existing.Data { + updated.Data = &target changes = true } diff --git a/providers/vultr/vultrProvider.go b/providers/vultr/vultrProvider.go index 625acf7e3..78eb47f6b 100644 --- a/providers/vultr/vultrProvider.go +++ b/providers/vultr/vultrProvider.go @@ -234,7 +234,7 @@ func toRecordConfig(dc *models.DomainConfig, r *vultr.DNSRecord) (*models.Record // toVultrRecord converts a RecordConfig converted by toRecordConfig back to a Vultr DNSRecord #rtype_variations func toVultrRecord(dc *models.DomainConfig, rc *models.RecordConfig) *vultr.DNSRecord { - name := dnsutil.TrimDomainName(rc.NameFQDN, dc.Name) + name := rc.GetLabel() // Vultr uses a blank string to represent the apex domain if name == "@" { name = "" @@ -267,17 +267,16 @@ func toVultrRecord(dc *models.DomainConfig, rc *models.RecordConfig) *vultr.DNSR TTL: int(rc.TTL), Priority: priority, } - - if rc.Type == "SRV" { - target := rc.Target + switch rtype := rc.Type; rtype { // #rtype_variations + case "SRV": + target := rc.GetTargetField() if strings.HasSuffix(target, ".") { target = target[:len(target)-1] } r.Data = fmt.Sprintf("%v %v %s", rc.SrvWeight, rc.SrvPort, target) - } - - if rc.Type == "CAA" { + case "CAA": r.Data = fmt.Sprintf(`%v %s "%s"`, rc.CaaFlag, rc.CaaTag, rc.GetTargetField()) + default: } return r