From 0203b3eebc8cfe7a4d73cae04b5ed870b46017c9 Mon Sep 17 00:00:00 2001 From: Craig Peterson Date: Thu, 13 Apr 2017 11:10:15 -0600 Subject: [PATCH] checking only one cname on a name (#81) --- normalize/validate.go | 21 +++++++++++++++++++++ normalize/validate_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/normalize/validate.go b/normalize/validate.go index 1df2aae23..81f7aa76e 100644 --- a/normalize/validate.go +++ b/normalize/validate.go @@ -260,9 +260,30 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) { errs = append(errs, err) } } + for _, d := range config.Domains { + errs = append(errs, checkCNAMEs(d)...) + } return errs } +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, fmt.Errorf("Cannot have multiple CNAMEs with same name: %s", r.NameFQDN)) + } + cnames[r.Name] = true + } + } + for _, r := range dc.Records { + if cnames[r.Name] && r.Type != "CNAME" { + errs = append(errs, fmt.Errorf("Cannot have CNAME and %s record with same name: %s", r.Type, r.NameFQDN)) + } + } + return +} + func applyRecordTransforms(domain *models.DomainConfig) error { for _, rec := range domain.Records { if rec.Type != "A" { diff --git a/normalize/validate_test.go b/normalize/validate_test.go index baa9d89fd..5da41941c 100644 --- a/normalize/validate_test.go +++ b/normalize/validate_test.go @@ -3,6 +3,8 @@ package normalize import ( "testing" + "fmt" + "github.com/StackExchange/dnscontrol/models" ) @@ -137,3 +139,33 @@ 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."} + tests := []struct { + rType string + name string + fail bool + }{ + {"A", "foo", true}, + {"A", "foo2", false}, + {"CNAME", "foo", true}, + {"CNAME", "foo2", false}, + } + 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."} + dc := &models.DomainConfig{ + Name: "example.com", + Records: []*models.RecordConfig{recA, recB}, + } + errs := checkCNAMEs(dc) + if errs != nil && !tst.fail { + t.Error("Got error but expected none") + } + if errs == nil && tst.fail { + t.Error("Expected error but got none") + } + }) + } +}