BUGFIX: IGNORE() deletes ignored records on ByZone() platforms (#3263)

This commit is contained in:
Tom Limoncelli 2024-12-18 20:34:52 -05:00 committed by GitHub
parent 7f477d8023
commit a341022068
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 358 additions and 40 deletions

View file

@ -2093,6 +2093,7 @@ func makeTests() []*TestGroup {
a("bar", "5.5.5.5"), a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
), ),
tc("ignore label", tc("ignore label",
// NB(tlim): This ignores 1 record of a recordSet. This should // NB(tlim): This ignores 1 record of a recordSet. This should
// fail for diff2.ByRecordSet() providers if diff2 is not // fail for diff2.ByRecordSet() providers if diff2 is not
@ -2104,6 +2105,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("foo", "", ""), ignore("foo", "", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore label,type", tc("ignore label,type",
//a("foo", "1.2.3.4"), //a("foo", "1.2.3.4"),
//a("foo", "2.3.4.5"), //a("foo", "2.3.4.5"),
@ -2112,6 +2121,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("foo", "A", ""), ignore("foo", "A", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore label,type,target", tc("ignore label,type,target",
//a("foo", "1.2.3.4"), //a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"), a("foo", "2.3.4.5"),
@ -2120,6 +2137,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("foo", "A", "1.2.3.4"), ignore("foo", "A", "1.2.3.4"),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore type", tc("ignore type",
//a("foo", "1.2.3.4"), //a("foo", "1.2.3.4"),
//a("foo", "2.3.4.5"), //a("foo", "2.3.4.5"),
@ -2128,6 +2153,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "A", ""), ignore("", "A", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore type,target", tc("ignore type,target",
a("foo", "1.2.3.4"), a("foo", "1.2.3.4"),
//a("foo", "2.3.4.5"), //a("foo", "2.3.4.5"),
@ -2136,6 +2169,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "A", "2.3.4.5"), ignore("", "A", "2.3.4.5"),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore target", tc("ignore target",
a("foo", "1.2.3.4"), a("foo", "1.2.3.4"),
//a("foo", "2.3.4.5"), //a("foo", "2.3.4.5"),
@ -2144,7 +2185,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "", "2.3.4.5"), ignore("", "", "2.3.4.5"),
).ExpectNoChanges(), ).ExpectNoChanges(),
// tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
// Many types: // Many types:
tc("ignore manytypes", tc("ignore manytypes",
//a("foo", "1.2.3.4"), //a("foo", "1.2.3.4"),
@ -2154,7 +2202,14 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "A,TXT", ""), ignore("", "A,TXT", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
// tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
// Target with wildcard: // Target with wildcard:
tc("ignore label,type,target=*", tc("ignore label,type,target=*",
a("foo", "1.2.3.4"), a("foo", "1.2.3.4"),
@ -2164,6 +2219,13 @@ func makeTests() []*TestGroup {
//cname("mail", "ghs.googlehosted.com."), //cname("mail", "ghs.googlehosted.com."),
ignore("", "CNAME", "*.googlehosted.com."), ignore("", "CNAME", "*.googlehosted.com."),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo", "1.2.3.4"),
a("foo", "2.3.4.5"),
txt("foo", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
), ),
// Same as "main" but with an apex ("@") record. // Same as "main" but with an apex ("@") record.
@ -2175,7 +2237,8 @@ func makeTests() []*TestGroup {
a("bar", "5.5.5.5"), a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
), ),
tc("ignore label",
tc("apex label",
// NB(tlim): This ignores 1 record of a recordSet. This should // NB(tlim): This ignores 1 record of a recordSet. This should
// fail for diff2.ByRecordSet() providers if diff2 is not // fail for diff2.ByRecordSet() providers if diff2 is not
// implemented correctly. // implemented correctly.
@ -2190,7 +2253,15 @@ func makeTests() []*TestGroup {
// that providers injects into zones are treated like input // that providers injects into zones are treated like input
// from dnsconfig.js. // from dnsconfig.js.
).ExpectNoChanges().UnsafeIgnore(), ).ExpectNoChanges().UnsafeIgnore(),
tc("ignore label,type", tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("apex label,type",
//a("@", "1.2.3.4"), //a("@", "1.2.3.4"),
//a("@", "2.3.4.5"), //a("@", "2.3.4.5"),
txt("@", "simple"), txt("@", "simple"),
@ -2198,7 +2269,15 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("@", "A", ""), ignore("@", "A", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("ignore label,type,target", tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("apex label,type,target",
//a("@", "1.2.3.4"), //a("@", "1.2.3.4"),
a("@", "2.3.4.5"), a("@", "2.3.4.5"),
txt("@", "simple"), txt("@", "simple"),
@ -2209,7 +2288,15 @@ func makeTests() []*TestGroup {
// that providers injects into zones are treated like input // that providers injects into zones are treated like input
// from dnsconfig.js. // from dnsconfig.js.
).ExpectNoChanges().UnsafeIgnore(), ).ExpectNoChanges().UnsafeIgnore(),
tc("ignore type", tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("apex type",
//a("@", "1.2.3.4"), //a("@", "1.2.3.4"),
//a("@", "2.3.4.5"), //a("@", "2.3.4.5"),
txt("@", "simple"), txt("@", "simple"),
@ -2217,7 +2304,15 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "A", ""), ignore("", "A", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("ignore type,target", tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("apex type,target",
a("@", "1.2.3.4"), a("@", "1.2.3.4"),
//a("@", "2.3.4.5"), //a("@", "2.3.4.5"),
txt("@", "simple"), txt("@", "simple"),
@ -2225,7 +2320,15 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "A", "2.3.4.5"), ignore("", "A", "2.3.4.5"),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("ignore target", tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("apex target",
a("@", "1.2.3.4"), a("@", "1.2.3.4"),
//a("@", "2.3.4.5"), //a("@", "2.3.4.5"),
txt("@", "simple"), txt("@", "simple"),
@ -2233,8 +2336,16 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "", "2.3.4.5"), ignore("", "", "2.3.4.5"),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
// Many types: // Many types:
tc("ignore manytypes", tc("apex manytypes",
//a("@", "1.2.3.4"), //a("@", "1.2.3.4"),
//a("@", "2.3.4.5"), //a("@", "2.3.4.5"),
//txt("@", "simple"), //txt("@", "simple"),
@ -2242,31 +2353,52 @@ func makeTests() []*TestGroup {
cname("mail", "ghs.googlehosted.com."), cname("mail", "ghs.googlehosted.com."),
ignore("", "A,TXT", ""), ignore("", "A,TXT", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("@", "1.2.3.4"),
a("@", "2.3.4.5"),
txt("@", "simple"),
a("bar", "5.5.5.5"),
cname("mail", "ghs.googlehosted.com."),
).ExpectNoChanges(),
), ),
// IGNORE with unsafe notation // IGNORE with unsafe notation
testgroup("IGNORE cross", testgroup("IGNORE unsafe",
tc("Create some records", tc("Create some records",
txt("foo", "simple"), txt("foo", "simple"),
a("foo", "1.2.3.4"), a("foo", "1.2.3.4"),
txt("@", "asimple"), txt("@", "asimple"),
a("@", "2.2.2.2"), a("@", "2.2.2.2"),
), ),
tc("ignore label=apex",
tc("ignore unsafe apex",
txt("foo", "simple"), txt("foo", "simple"),
a("foo", "1.2.3.4"), a("foo", "1.2.3.4"),
txt("@", "asimple"), txt("@", "asimple"),
a("@", "2.2.2.2"), a("@", "2.2.2.2"),
ignore("foo", "TXT", ""), ignore("@", "", ""),
).ExpectNoChanges().UnsafeIgnore(), ).ExpectNoChanges().UnsafeIgnore(),
tc("ignore label=apex", tc("VERIFY PREVIOUS",
txt("foo", "simple"), txt("foo", "simple"),
a("foo", "1.2.3.4"), a("foo", "1.2.3.4"),
txt("@", "asimple"), txt("@", "asimple"),
a("@", "2.2.2.2"), a("@", "2.2.2.2"),
ignore("@", "TXT", ""), ).ExpectNoChanges(),
tc("ignore unsafe label",
txt("foo", "simple"),
a("foo", "1.2.3.4"),
txt("@", "asimple"),
a("@", "2.2.2.2"),
ignore("foo", "", ""),
).ExpectNoChanges().UnsafeIgnore(), ).ExpectNoChanges().UnsafeIgnore(),
tc("VERIFY PREVIOUS",
txt("foo", "simple"),
a("foo", "1.2.3.4"),
txt("@", "asimple"),
a("@", "2.2.2.2"),
).ExpectNoChanges(),
), ),
// IGNORE with wildcards // IGNORE with wildcards
@ -2279,6 +2411,7 @@ func makeTests() []*TestGroup {
a("bar.bat", "5.5.5.5"), a("bar.bat", "5.5.5.5"),
cname("mail.bat", "ghs.googlehosted.com."), cname("mail.bat", "ghs.googlehosted.com."),
), ),
tc("ignore label=foo.*", tc("ignore label=foo.*",
//a("foo.bat", "1.2.3.4"), //a("foo.bat", "1.2.3.4"),
//a("foo.bat", "2.3.4.5"), //a("foo.bat", "2.3.4.5"),
@ -2287,6 +2420,14 @@ func makeTests() []*TestGroup {
cname("mail.bat", "ghs.googlehosted.com."), cname("mail.bat", "ghs.googlehosted.com."),
ignore("foo.*", "", ""), ignore("foo.*", "", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo.bat", "1.2.3.4"),
a("foo.bat", "2.3.4.5"),
txt("foo.bat", "simple"),
a("bar.bat", "5.5.5.5"),
cname("mail.bat", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore label=foo.bat,type", tc("ignore label=foo.bat,type",
//a("foo.bat", "1.2.3.4"), //a("foo.bat", "1.2.3.4"),
//a("foo.bat", "2.3.4.5"), //a("foo.bat", "2.3.4.5"),
@ -2295,6 +2436,14 @@ func makeTests() []*TestGroup {
cname("mail.bat", "ghs.googlehosted.com."), cname("mail.bat", "ghs.googlehosted.com."),
ignore("*.bat", "A", ""), ignore("*.bat", "A", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo.bat", "1.2.3.4"),
a("foo.bat", "2.3.4.5"),
txt("foo.bat", "simple"),
a("bar.bat", "5.5.5.5"),
cname("mail.bat", "ghs.googlehosted.com."),
).ExpectNoChanges(),
tc("ignore target=*.domain", tc("ignore target=*.domain",
a("foo.bat", "1.2.3.4"), a("foo.bat", "1.2.3.4"),
a("foo.bat", "2.3.4.5"), a("foo.bat", "2.3.4.5"),
@ -2303,6 +2452,119 @@ func makeTests() []*TestGroup {
//cname("mail.bat", "ghs.googlehosted.com."), //cname("mail.bat", "ghs.googlehosted.com."),
ignore("", "", "*.googlehosted.com."), ignore("", "", "*.googlehosted.com."),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("foo.bat", "1.2.3.4"),
a("foo.bat", "2.3.4.5"),
txt("foo.bat", "simple"),
a("bar.bat", "5.5.5.5"),
cname("mail.bat", "ghs.googlehosted.com."),
).ExpectNoChanges(),
),
// IGNORE with changes
testgroup("IGNORE with modify",
tc("Create some records",
a("foo", "1.1.1.1"),
a("foo", "10.10.10.10"),
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
),
// ByZone: Change (anywhere)
tc("IGNORE change ByZone",
ignore("zzz", "A", ""),
a("foo", "1.1.1.1"),
a("foo", "11.11.11.11"), // CHANGE
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
//a("zzz", "3.3.3.3"),
//a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
),
tc("VERIFY PREVIOUS",
a("foo", "1.1.1.1"),
a("foo", "11.11.11.11"),
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
).ExpectNoChanges(),
// ByLabel: Change within a (name) while we ignore the rest
tc("IGNORE change ByLabel",
ignore("foo", "MX", ""),
a("foo", "1.1.1.1"),
a("foo", "12.12.12.12"), // CHANGE
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
//mx("foo", 10, "aspmx.l.google.com."),
//mx("foo", 20, "alt1.aspmx.l.google.com"),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
),
tc("VERIFY PREVIOUS",
a("foo", "1.1.1.1"),
a("foo", "12.12.12.12"),
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
).ExpectNoChanges(),
// ByRecordSet: Change within a (name+type) while we ignore the rest
tc("IGNORE change ByRecordSet",
ignore("foo", "MX,AAAA", ""),
a("foo", "1.1.1.1"),
a("foo", "13.13.13.13"), // CHANGE
//aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
//mx("foo", 10, "aspmx.l.google.com."),
//mx("foo", 20, "alt1.aspmx.l.google.com"),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
),
tc("VERIFY PREVIOUS",
a("foo", "1.1.1.1"),
a("foo", "13.13.13.13"),
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
).ExpectNoChanges(),
// Change within a (name+type+data) ("ByRecord")
tc("IGNORE change ByRecord",
ignore("foo", "A", "1.1.1.1"),
//a("foo", "1.1.1.1"),
a("foo", "14.14.14.14"),
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
),
tc("VERIFY PREVIOUS",
a("foo", "1.1.1.1"),
a("foo", "14.14.14.14"),
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
mx("foo", 10, "aspmx.l.google.com."),
mx("foo", 20, "alt1.aspmx.l.google.com."),
a("zzz", "3.3.3.3"),
a("zzz", "4.4.4.4"),
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
).ExpectNoChanges(),
), ),
// IGNORE repro bug reports // IGNORE repro bug reports
@ -2316,6 +2578,10 @@ func makeTests() []*TestGroup {
tc("Add a new record - ignoring test.foo.com.", tc("Add a new record - ignoring test.foo.com.",
ignoreTarget("**.acm-validations.aws.", "CNAME"), ignoreTarget("**.acm-validations.aws.", "CNAME"),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
cname("foo", "redact1.acm-validations.aws."),
cname("bar", "redact2.acm-validations.aws."),
).ExpectNoChanges(),
), ),
// https://github.com/StackExchange/dnscontrol/issues/2822 // https://github.com/StackExchange/dnscontrol/issues/2822
@ -2338,6 +2604,12 @@ func makeTests() []*TestGroup {
ignore("dyndns-city1", "A,AAAA", ""), ignore("dyndns-city1", "A,AAAA", ""),
ignore("dyndns-city2", "A,AAAA", ""), ignore("dyndns-city2", "A,AAAA", ""),
).ExpectNoChanges().UnsafeIgnore(), ).ExpectNoChanges().UnsafeIgnore(),
tc("VERIFY PREVIOUS",
a("dyndns-city1", "91.42.1.1"),
a("dyndns-city2", "91.42.1.2"),
aaaa("dyndns-city1", "2003:dd:d7ff::fe71:ce77"),
aaaa("dyndns-city2", "2003:dd:d7ff::fe71:ce78"),
).ExpectNoChanges(),
), ),
// https://github.com/StackExchange/dnscontrol/issues/3227 // https://github.com/StackExchange/dnscontrol/issues/3227
@ -2351,11 +2623,29 @@ func makeTests() []*TestGroup {
a("testdefined", "9.9.9.9"), a("testdefined", "9.9.9.9"),
ignore("testignore", "", ""), ignore("testignore", "", ""),
).ExpectNoChanges(), ).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("testignore", "8.8.8.8"),
a("testdefined", "9.9.9.9"),
).ExpectNoChanges(),
tc("Verify nothing changed",
a("testignore", "8.8.8.8"),
a("testdefined", "9.9.9.9"),
).ExpectNoChanges(),
tc("VERIFY PREVIOUS",
a("testignore", "8.8.8.8"),
a("testdefined", "9.9.9.9"),
).ExpectNoChanges(),
tc("ignore with change", tc("ignore with change",
//a("testignore", "8.8.8.8"), //a("testignore", "8.8.8.8"),
a("testdefined", "2.2.2.2"), a("testdefined", "2.2.2.2"),
ignore("testignore", "", ""), ignore("testignore", "", ""),
), ),
tc("VERIFY PREVIOUS",
a("testignore", "8.8.8.8"),
a("testdefined", "2.2.2.2"),
).ExpectNoChanges(),
), ),
// OVH features // OVH features

View file

@ -195,29 +195,47 @@ func ByRecord(existing models.Records, dc *models.DomainConfig, compFunc Compara
// //
// Example usage: // Example usage:
// //
// msgs, changes, err := diff2.ByZone(foundRecords, dc, nil) // result, err := diff2.ByZone(foundRecords, dc, nil)
// if err != nil { // if err != nil {
// return nil, err // return nil, err
// } // }
// if changes { // if changes {
// // Generate a "correction" that uploads the entire zone. // // Generate a "correction" that uploads the entire zone.
// // (dc.Records are the new records for the zone). // // (result.DesiredPlus are the new records for the zone).
// } // }
// //
// Example providers include: BIND, AUTODNS // Example providers include: BIND, AUTODNS
func ByZone(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) ([]string, bool, int, error) { func ByZone(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ByResults, error) {
// Only return the messages. The caller has the list of records needed to build the new zone. // Only return the messages and a list of records needed to build the new zone.
instructions, actualChangeCount, err := byHelper(analyzeByRecord, existing, dc, compFunc) result, err := byHelperStruct(analyzeByRecord, existing, dc, compFunc)
return justMsgs(instructions), actualChangeCount > 0, actualChangeCount, err result.Msgs = justMsgs(result.Instructions)
return result, err
} }
// // ByResults is the results of ByZone() and perhaps someday all the By*() functions.
// It is partially populated by // byHelperStruct() and partially by the By*()
// functions that use it.
type ByResults struct {
// Fields filled in by byHelperStruct():
Instructions ChangeList // Instructions to turn existing into desired.
ActualChangeCount int // Number of actual changes, not including REPORTs.
HasChanges bool // True if there are any changes.
DesiredPlus models.Records // Desired + foreign + ignored
// Fields filled in by ByZone():
Msgs []string // Just the messages from the instructions.
}
// byHelper does 90% of the work for the By*() calls. // byHelper is like byHelperStruct but has a signature that is compatible with legacy code.
// Deprecated: Use byHelperStruct instead.
func byHelper(fn func(cc *CompareConfig) (ChangeList, int), existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, int, error) { func byHelper(fn func(cc *CompareConfig) (ChangeList, int), existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, int, error) {
result, err := byHelperStruct(fn, existing, dc, compFunc)
return result.Instructions, result.ActualChangeCount, err
}
// byHelperStruct does 90% of the work for the By*() calls.
func byHelperStruct(fn func(cc *CompareConfig) (ChangeList, int), existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ByResults, error) {
// Process NO_PURGE/ENSURE_ABSENT and IGNORE*(). // Process NO_PURGE/ENSURE_ABSENT and IGNORE*().
desired, msgs, err := handsoff( desiredPlus, msgs, err := handsoff(
dc.Name, dc.Name,
existing, dc.Records, dc.EnsureAbsent, existing, dc.Records, dc.EnsureAbsent,
dc.Unmanaged, dc.Unmanaged,
@ -225,11 +243,11 @@ func byHelper(fn func(cc *CompareConfig) (ChangeList, int), existing models.Reco
dc.KeepUnknown, dc.KeepUnknown,
) )
if err != nil { if err != nil {
return nil, 0, err return ByResults{}, err
} }
// Regroup existing/desiredd for easy comparison: // Regroup existing/desiredd for easy comparison:
cc := NewCompareConfig(dc.Name, existing, desired, compFunc) cc := NewCompareConfig(dc.Name, existing, desiredPlus, compFunc)
// Analyze and generate the instructions: // Analyze and generate the instructions:
instructions, actualChangeCount := fn(cc) instructions, actualChangeCount := fn(cc)
@ -245,5 +263,10 @@ func byHelper(fn func(cc *CompareConfig) (ChangeList, int), existing models.Reco
instructions = append([]Change{chg}, instructions...) instructions = append([]Change{chg}, instructions...)
} }
return instructions, actualChangeCount, nil return ByResults{
Instructions: instructions,
ActualChangeCount: actualChangeCount,
HasChanges: actualChangeCount > 0,
DesiredPlus: desiredPlus,
}, nil
} }

View file

@ -77,16 +77,18 @@ func (api *autoDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, e
var corrections []*models.Correction var corrections []*models.Correction
msgs, changed, actualChangeCount, err := diff2.ByZone(existingRecords, dc, nil) result, err := diff2.ByZone(existingRecords, dc, nil)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
msgs, changed, actualChangeCount := result.Msgs, result.HasChanges, result.ActualChangeCount
if changed { if changed {
msgs = append(msgs, "Zone update for "+domain) msgs = append(msgs, "Zone update for "+domain)
msg := strings.Join(msgs, "\n") msg := strings.Join(msgs, "\n")
nameServers, zoneTTL, resourceRecords := recordsToNative(dc.Records) nameServers, zoneTTL, resourceRecords := recordsToNative(result.DesiredPlus)
corrections = append(corrections, corrections = append(corrections,
&models.Correction{ &models.Correction{

View file

@ -211,7 +211,7 @@ func ParseZoneContents(content string, zoneName string, zonefileName string) (mo
return foundRecords, nil return foundRecords, nil
} }
func (n *bindProvider) EnsureZoneExists(_ string) error { func (c *bindProvider) EnsureZoneExists(_ string) error {
return nil return nil
} }
@ -247,12 +247,12 @@ func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundR
} }
var msgs []string var msgs []string
var err error
var actualChangeCount int var actualChangeCount int
msgs, changes, actualChangeCount, err = diff2.ByZone(foundRecords, dc, nil) result, err := diff2.ByZone(foundRecords, dc, nil)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
msgs, changes, actualChangeCount = result.Msgs, result.HasChanges, result.ActualChangeCount
if !changes { if !changes {
return nil, 0, nil return nil, 0, nil
} }
@ -299,7 +299,7 @@ func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundR
// Beware that if there are any fake types, then they will // Beware that if there are any fake types, then they will
// be commented out on write, but we don't reverse that when // be commented out on write, but we don't reverse that when
// reading, so there will be a diff on every invocation. // reading, so there will be a diff on every invocation.
err = prettyzone.WriteZoneFileRC(zf, dc.Records, dc.Name, 0, comments) err = prettyzone.WriteZoneFileRC(zf, result.DesiredPlus, dc.Name, 0, comments)
if err != nil { if err != nil {
return fmt.Errorf("failed WriteZoneFile: %w", err) return fmt.Errorf("failed WriteZoneFile: %w", err)

View file

@ -115,10 +115,11 @@ func zoneFileToRecords(r io.Reader, origin string) (models.Records, error) {
// GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records.
func (n *mythicBeastsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { func (n *mythicBeastsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) {
msgs, changes, actualChangeCount, err := diff2.ByZone(actual, dc, nil) result, err := diff2.ByZone(actual, dc, nil)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
msgs, changes, actualChangeCount := result.Msgs, result.HasChanges, result.ActualChangeCount
var corrections []*models.Correction var corrections []*models.Correction
if changes { if changes {
@ -127,7 +128,7 @@ func (n *mythicBeastsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig
Msg: strings.Join(msgs, "\n"), Msg: strings.Join(msgs, "\n"),
F: func() error { F: func() error {
var b strings.Builder var b strings.Builder
for _, record := range dc.Records { for _, record := range result.DesiredPlus {
switch rr := record.ToRR().(type) { switch rr := record.ToRR().(type) {
case *dns.SSHFP: case *dns.SSHFP:
// "Hex strings [for SSHFP] must be in lower-case", per Mythic Beasts API docs. // "Hex strings [for SSHFP] must be in lower-case", per Mythic Beasts API docs.

View file

@ -107,10 +107,11 @@ func (api *realtimeregisterAPI) GetZoneRecords(domain string, meta map[string]st
} }
func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) {
msgs, changes, actualChangeCount, err := diff2.ByZone(existing, dc, nil) result, err := diff2.ByZone(existing, dc, nil)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
msgs, changes, actualChangeCount := result.Msgs, result.HasChanges, result.ActualChangeCount
var corrections []*models.Correction var corrections []*models.Correction
@ -149,8 +150,8 @@ func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfi
&models.Correction{ &models.Correction{
Msg: strings.Join(msgs, "\n"), Msg: strings.Join(msgs, "\n"),
F: func() error { F: func() error {
records := make([]Record, len(dc.Records)) records := make([]Record, len(result.DesiredPlus))
for i, r := range dc.Records { for i, r := range result.DesiredPlus {
records[i] = toRecord(r) records[i] = toRecord(r)
} }
zone := &Zone{Records: records, Dnssec: dnssec} zone := &Zone{Records: records, Dnssec: dnssec}

View file

@ -65,10 +65,11 @@ func (s *sakuracloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig,
} }
} }
msgs, changes, actualChangeCount, err := diff2.ByZone(existing, dc, nil) result, err := diff2.ByZone(existing, dc, nil)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
msgs, changes, actualChangeCount := result.Msgs, result.HasChanges, result.ActualChangeCount
if !changes { if !changes {
return nil, actualChangeCount, nil return nil, actualChangeCount, nil
} }
@ -78,8 +79,8 @@ func (s *sakuracloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig,
&models.Correction{ &models.Correction{
Msg: msg, Msg: msg,
F: func() error { F: func() error {
drs := make([]domainRecord, 0, len(dc.Records)) drs := make([]domainRecord, 0, len(result.DesiredPlus))
for _, rc := range dc.Records { for _, rc := range result.DesiredPlus {
drs = append(drs, toNative(rc)) drs = append(drs, toNative(rc))
} }
return s.api.UpdateZone(dc.Name, drs) return s.api.UpdateZone(dc.Name, drs)