1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

FEATURE: Add rTypes restrictions to IGNORE_NAME (#1808)

Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
Dragos Harabor
2022-11-07 08:27:04 -08:00
committed by GitHub
parent 4b3d8f724e
commit 68516025a5
12 changed files with 121 additions and 39 deletions

View File

@@ -2,6 +2,7 @@ package diff
import (
"fmt"
"regexp"
"sort"
"github.com/StackExchange/dnscontrol/v3/models"
@@ -42,11 +43,18 @@ func New(dc *models.DomainConfig, extraValues ...func(*models.RecordConfig) map[
}
}
// An ignoredName must match both the name glob and one of the recordTypes in rTypes. If rTypes is empty, any
// record type will match.
type ignoredName struct {
nameGlob glob.Glob
rTypes []string
}
type differ struct {
dc *models.DomainConfig
extraValues []func(*models.RecordConfig) map[string]string
compiledIgnoredNames []glob.Glob
compiledIgnoredNames []ignoredName
compiledIgnoredTargets []glob.Glob
}
@@ -99,7 +107,7 @@ func (d *differ) IncrementalDiff(existing []*models.RecordConfig) (unchanged, cr
// Gather the existing records. Skip over any that should be ignored.
for _, e := range existing {
//fmt.Printf("********** DEBUG: existing %v %v %v\n", e.GetLabel(), e.Type, e.GetTargetCombined())
if d.matchIgnoredName(e.GetLabel()) {
if d.matchIgnoredName(e.GetLabel(), e.Type) {
//fmt.Printf("Ignoring record %s %s due to IGNORE_NAME\n", e.GetLabel(), e.Type)
printer.Debugf("Ignoring record %s %s due to IGNORE_NAME\n", e.GetLabel(), e.Type)
} else if d.matchIgnoredTarget(e.GetTargetField(), e.Type) {
@@ -115,7 +123,7 @@ func (d *differ) IncrementalDiff(existing []*models.RecordConfig) (unchanged, cr
//fmt.Printf("********** DEBUG: desired list %+v\n", desired)
for _, dr := range desired {
//fmt.Printf("********** DEBUG: desired %v %v %v -- %v %v\n", dr.GetLabel(), dr.Type, dr.GetTargetCombined(), apexException(dr), d.matchIgnoredName(dr.GetLabel()))
if d.matchIgnoredName(dr.GetLabel()) {
if d.matchIgnoredName(dr.GetLabel(), dr.Type) {
//if !apexException(dr) || !ignoreNameException(dr) {
if (!ignoreNameException(dr)) && (!apexException(dr)) {
return nil, nil, nil, nil, fmt.Errorf("trying to update/add IGNORE_NAMEd record: %s %s", dr.GetLabel(), dr.Type)
@@ -345,16 +353,23 @@ func sortedKeys(m map[string]*models.RecordConfig) []string {
return s
}
func compileIgnoredNames(ignoredNames []string) []glob.Glob {
result := make([]glob.Glob, 0, len(ignoredNames))
var spaceCommaTokenizerRegexp = regexp.MustCompile(`\s*,\s*`)
func compileIgnoredNames(ignoredNames []*models.IgnoreName) []ignoredName {
result := make([]ignoredName, 0, len(ignoredNames))
for _, tst := range ignoredNames {
g, err := glob.Compile(tst, '.')
g, err := glob.Compile(tst.Pattern, '.')
if err != nil {
panic(fmt.Sprintf("Failed to compile IGNORE_NAME pattern %q: %v", tst, err))
panic(fmt.Sprintf("Failed to compile IGNORE_NAME pattern %q: %v", tst.Pattern, err))
}
result = append(result, g)
t := []string{}
if tst.Types != "" {
t = spaceCommaTokenizerRegexp.Split(tst.Types, -1)
}
result = append(result, ignoredName{nameGlob: g, rTypes: t})
}
return result
@@ -379,11 +394,19 @@ func compileIgnoredTargets(ignoredTargets []*models.IgnoreTarget) []glob.Glob {
return result
}
func (d *differ) matchIgnoredName(name string) bool {
func (d *differ) matchIgnoredName(name string, rType string) bool {
for _, tst := range d.compiledIgnoredNames {
//fmt.Printf("********** DEBUG: matchIgnoredName %q %q %v\n", name, tst, tst.Match(name))
if tst.Match(name) {
return true
//fmt.Printf("********** DEBUG: matchIgnoredName %q %q %v %v\n", name, rType, tst, tst.nameGlob.Match(name))
if tst.nameGlob.Match(name) {
if tst.rTypes == nil {
return true
}
for _, rt := range tst.rTypes {
if rt == "*" || rt == rType {
return true
}
}
}
}
return false

View File

@@ -158,10 +158,10 @@ func checkLengths(t *testing.T, existing, desired []*models.RecordConfig, unCoun
}
func checkLengthsWithKeepUnknown(t *testing.T, existing, desired []*models.RecordConfig, unCount, createCount, delCount, modCount int, keepUnknown bool, valFuncs ...func(*models.RecordConfig) map[string]string) (un, cre, del, mod Changeset) {
return checkLengthsFull(t, existing, desired, unCount, createCount, delCount, modCount, keepUnknown, []string{}, nil, valFuncs...)
return checkLengthsFull(t, existing, desired, unCount, createCount, delCount, modCount, keepUnknown, []*models.IgnoreName{}, nil, valFuncs...)
}
func checkLengthsFull(t *testing.T, existing, desired []*models.RecordConfig, unCount, createCount, delCount, modCount int, keepUnknown bool, ignoredRecords []string, ignoredTargets []*models.IgnoreTarget, valFuncs ...func(*models.RecordConfig) map[string]string) (un, cre, del, mod Changeset) {
func checkLengthsFull(t *testing.T, existing, desired []*models.RecordConfig, unCount, createCount, delCount, modCount int, keepUnknown bool, ignoredRecords []*models.IgnoreName, ignoredTargets []*models.IgnoreTarget, valFuncs ...func(*models.RecordConfig) map[string]string) (un, cre, del, mod Changeset) {
dc := &models.DomainConfig{
Name: "example.com",
Records: desired,
@@ -206,14 +206,23 @@ func TestNoPurge(t *testing.T) {
func TestIgnoredRecords(t *testing.T) {
existing := []*models.RecordConfig{
myRecord("www1 A 1 1.1.1.1"),
myRecord("www1 MX 1 1.1.1.1"),
myRecord("www2 A 1 1.1.1.1"),
myRecord("www2 CNAME 1 www"),
myRecord("www2 MX 1 1.1.1.1"),
myRecord("www3 MX 1 1.1.1.1"),
}
desired := []*models.RecordConfig{
myRecord("www3 MX 1 2.2.2.2"),
}
checkLengthsFull(t, existing, desired, 0, 0, 0, 1, false, []string{"www1", "www2"}, nil)
checkLengthsFull(t, existing, desired, 0, 0, 0, 1, false,
[]*models.IgnoreName{
{Pattern: "www1", Types: "*"},
{Pattern: "www2", Types: "A,MX, CNAME"},
},
nil,
)
}
func TestModifyingIgnoredRecords(t *testing.T) {
@@ -232,7 +241,10 @@ func TestModifyingIgnoredRecords(t *testing.T) {
}
}()
checkLengthsFull(t, existing, desired, 0, 0, 0, 1, false, []string{"www1", "www2"}, nil)
checkLengthsFull(t, existing, desired, 0, 0, 0, 1, false,
[]*models.IgnoreName{{Pattern: "www1", Types: "MX"}, {Pattern: "www2", Types: "*"}},
nil,
)
}
func TestGlobIgnoredName(t *testing.T) {
@@ -245,7 +257,14 @@ func TestGlobIgnoredName(t *testing.T) {
desired := []*models.RecordConfig{
myRecord("www4 MX 1 2.2.2.2"),
}
checkLengthsFull(t, existing, desired, 0, 0, 0, 1, false, []string{"www1", "*.www2", "**.www3"}, nil)
checkLengthsFull(t, existing, desired, 0, 0, 0, 1, false,
[]*models.IgnoreName{
{Pattern: "www1", Types: "*"},
{Pattern: "*.www2", Types: "*"},
{Pattern: "**.www3", Types: "*"},
},
nil,
)
}
func TestInvalidGlobIgnoredName(t *testing.T) {
@@ -264,7 +283,10 @@ func TestInvalidGlobIgnoredName(t *testing.T) {
}
}()
checkLengthsFull(t, existing, desired, 0, 1, 0, 0, false, []string{"www1", "www2", "[.www3"}, nil)
checkLengthsFull(t, existing, desired, 0, 1, 0, 0, false,
[]*models.IgnoreName{{Pattern: "www1"}, {Pattern: "*.www2"}, {Pattern: "[.www3"}},
nil,
)
}
func TestGlobIgnoredTarget(t *testing.T) {