diff --git a/.github/workflows/pr_test.yml b/.github/workflows/pr_test.yml index efc2012ed..a5b42cc5e 100644 --- a/.github/workflows/pr_test.yml +++ b/.github/workflows/pr_test.yml @@ -96,7 +96,7 @@ jobs: if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' runs-on: ubuntu-latest container: - image: golang:1.22 + image: golang:1.23 needs: - integration-test-providers env: diff --git a/.github/workflows/release_draft.yml b/.github/workflows/release_draft.yml index 55460a429..225015d88 100644 --- a/.github/workflows/release_draft.yml +++ b/.github/workflows/release_draft.yml @@ -42,7 +42,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ^1.22 + go-version: ^1.23 # Stringer is needed because .goreleaser includes "go generate ./..." - name: Install stringer diff --git a/commands/ppreviewPush.go b/commands/ppreviewPush.go index 1256d55a6..68e846b4e 100644 --- a/commands/ppreviewPush.go +++ b/commands/ppreviewPush.go @@ -240,7 +240,7 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor out.StartDNSProvider(provider.Name, skip) if !skip { corrections := zone.GetCorrections(provider.Name) - numActions := countActions(corrections) + numActions := zone.GetChangeCount(provider.Name) totalCorrections += numActions out.EndProvider2(provider.Name, numActions) reportItems = append(reportItems, genReportItem(zone.Name, corrections, provider.Name)) @@ -253,7 +253,7 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor out.StartRegistrar(zone.RegistrarName, !skip) if skip { corrections := zone.GetCorrections(zone.RegistrarInstance.Name) - numActions := countActions(corrections) + numActions := zone.GetChangeCount(zone.RegistrarInstance.Name) out.EndProvider2(zone.RegistrarName, numActions) totalCorrections += numActions reportItems = append(reportItems, genReportItem(zone.Name, corrections, zone.RegistrarName)) @@ -281,15 +281,15 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor return nil } -func countActions(corrections []*models.Correction) int { - r := 0 - for _, c := range corrections { - if c.F != nil { - r++ - } - } - return r -} +//func countActions(corrections []*models.Correction) int { +// r := 0 +// for _, c := range corrections { +// if c.F != nil { +// r++ +// } +// } +// return r +//} func whichZonesToProcess(domains []*models.DomainConfig, filter string) []*models.DomainConfig { if filter == "" || filter == "all" { @@ -364,7 +364,7 @@ func optimizeOrder(zones []*models.DomainConfig) []*models.DomainConfig { func oneZone(zone *models.DomainConfig, args PPreviewArgs, zc *zoneCache) { // Fix the parent zone's delegation: (if able/needed) //zone.NameserversMutex.Lock() - delegationCorrections := generateDelegationCorrections(zone, zone.DNSProviderInstances, zone.RegistrarInstance) + delegationCorrections, dcCount := generateDelegationCorrections(zone, zone.DNSProviderInstances, zone.RegistrarInstance) //zone.NameserversMutex.Unlock() // Loop over the (selected) providers configured for that zone: @@ -378,13 +378,15 @@ func oneZone(zone *models.DomainConfig, args PPreviewArgs, zc *zoneCache) { } // Update the zone's records at the provider: - zoneCor, rep := generateZoneCorrections(zone, provider) + zoneCor, rep, actualChangeCount := generateZoneCorrections(zone, provider) zone.StoreCorrections(provider.Name, rep) zone.StoreCorrections(provider.Name, zoneCor) + zone.IncrementChangeCount(provider.Name, actualChangeCount) } // Do the delegation corrections after the zones are updated. zone.StoreCorrections(zone.RegistrarInstance.Name, delegationCorrections) + zone.IncrementChangeCount(zone.RegistrarInstance.Name, dcCount) } func whichProvidersToProcess(providers []*models.DNSProviderInstance, filter string) []*models.DNSProviderInstance { @@ -533,32 +535,32 @@ func generatePopulateCorrections(provider *models.DNSProviderInstance, zoneName }} } -func generateZoneCorrections(zone *models.DomainConfig, provider *models.DNSProviderInstance) ([]*models.Correction, []*models.Correction) { - reports, zoneCorrections, err := zonerecs.CorrectZoneRecords(provider.Driver, zone) +func generateZoneCorrections(zone *models.DomainConfig, provider *models.DNSProviderInstance) ([]*models.Correction, []*models.Correction, int) { + reports, zoneCorrections, actualChangeCount, err := zonerecs.CorrectZoneRecords(provider.Driver, zone) if err != nil { - return []*models.Correction{{Msg: fmt.Sprintf("Domain %q provider %s Error: %s", zone.Name, provider.Name, err)}}, nil + return []*models.Correction{{Msg: fmt.Sprintf("Domain %q provider %s Error: %s", zone.Name, provider.Name, err)}}, nil, 0 } - return zoneCorrections, reports + return zoneCorrections, reports, actualChangeCount } -func generateDelegationCorrections(zone *models.DomainConfig, providers []*models.DNSProviderInstance, _ *models.RegistrarInstance) []*models.Correction { +func generateDelegationCorrections(zone *models.DomainConfig, providers []*models.DNSProviderInstance, _ *models.RegistrarInstance) ([]*models.Correction, int) { //fmt.Printf("DEBUG: generateDelegationCorrections start zone=%q nsList = %v\n", zone.Name, zone.Nameservers) nsList, err := nameservers.DetermineNameserversForProviders(zone, providers, true) if err != nil { - return msg(fmt.Sprintf("DtermineNS: zone %q; Error: %s", zone.Name, err)) + return msg(fmt.Sprintf("DetermineNS: zone %q; Error: %s", zone.Name, err)), 0 } zone.Nameservers = nsList nameservers.AddNSRecords(zone) if len(zone.Nameservers) == 0 && zone.Metadata["no_ns"] != "true" { - return []*models.Correction{{Msg: fmt.Sprintf("No nameservers declared for domain %q; skipping registrar. Add {no_ns:'true'} to force", zone.Name)}} + return []*models.Correction{{Msg: fmt.Sprintf("No nameservers declared for domain %q; skipping registrar. Add {no_ns:'true'} to force", zone.Name)}}, 0 } corrections, err := zone.RegistrarInstance.Driver.GetRegistrarCorrections(zone) if err != nil { - return msg(fmt.Sprintf("zone %q; Rprovider %q; Error: %s", zone.Name, zone.RegistrarInstance.Name, err)) + return msg(fmt.Sprintf("zone %q; Rprovider %q; Error: %s", zone.Name, zone.RegistrarInstance.Name, err)), 0 } - return corrections + return corrections, len(corrections) } func msg(s string) []*models.Correction { diff --git a/commands/previewPush.go b/commands/previewPush.go index 528fe4307..8220f5bee 100644 --- a/commands/previewPush.go +++ b/commands/previewPush.go @@ -247,17 +247,17 @@ func run(args PreviewArgs, push bool, interactive bool, out printer.CLI, report continue } - reports, corrections, err := zonerecs.CorrectZoneRecords(provider.Driver, domain) - out.EndProvider(provider.Name, len(corrections), err) + reports, corrections, actualChangeCount, err := zonerecs.CorrectZoneRecords(provider.Driver, domain) + out.EndProvider(provider.Name, actualChangeCount, err) if err != nil { anyErrors = true return } - totalCorrections += len(corrections) + totalCorrections += actualChangeCount printReports(domain.Name, provider.Name, reports, out, push, notifier) reportItems = append(reportItems, ReportItem{ Domain: domain.Name, - Corrections: len(corrections), + Corrections: actualChangeCount, Provider: provider.Name, }) anyErrors = printOrRunCorrections(domain.Name, provider.Name, corrections, out, push, interactive, notifier) || anyErrors diff --git a/go.mod b/go.mod index fb233d39c..cd5f4943d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/StackExchange/dnscontrol/v4 -go 1.22.1 +go 1.23.0 retract v4.8.0 diff --git a/integrationTest/integration_test.go b/integrationTest/integration_test.go index 4911376a8..ae0551f1c 100644 --- a/integrationTest/integration_test.go +++ b/integrationTest/integration_test.go @@ -228,13 +228,13 @@ func makeChanges(t *testing.T, prv providers.DNSServiceProvider, dc *models.Doma } // get and run corrections for first time - _, corrections, err := zonerecs.CorrectZoneRecords(prv, dom) + _, corrections, actualChangeCount, err := zonerecs.CorrectZoneRecords(prv, dom) if err != nil { t.Fatal(fmt.Errorf("runTests: %w", err)) } if tst.Changeless { - if count := len(corrections); count != 0 { - t.Logf("Expected 0 corrections on FIRST run, but found %d.", count) + if actualChangeCount != 0 { + t.Logf("Expected 0 corrections on FIRST run, but found %d.", actualChangeCount) for i, c := range corrections { t.Logf("UNEXPECTED #%d: %s", i, c.Msg) } @@ -261,12 +261,12 @@ func makeChanges(t *testing.T, prv providers.DNSServiceProvider, dc *models.Doma } // run a second time and expect zero corrections - _, corrections, err = zonerecs.CorrectZoneRecords(prv, dom2) + _, corrections, actualChangeCount, err = zonerecs.CorrectZoneRecords(prv, dom2) if err != nil { t.Fatal(err) } - if count := len(corrections); count != 0 { - t.Logf("Expected 0 corrections on second run, but found %d.", count) + if actualChangeCount != 0 { + t.Logf("Expected 0 corrections on second run, but found %d.", actualChangeCount) for i, c := range corrections { t.Logf("UNEXPECTED #%d: %s", i, c.Msg) } @@ -353,7 +353,7 @@ func TestDualProviders(t *testing.T) { run := func() { dom, _ := dc.Copy() - rs, cs, err := zonerecs.CorrectZoneRecords(p, dom) + rs, cs, _, err := zonerecs.CorrectZoneRecords(p, dom) if err != nil { t.Fatal(err) } @@ -378,12 +378,12 @@ func TestDualProviders(t *testing.T) { run() // run again to make sure no corrections t.Log("Running again to ensure stability") - rs, cs, err := zonerecs.CorrectZoneRecords(p, dc) + rs, cs, actualChangeCount, err := zonerecs.CorrectZoneRecords(p, dc) if err != nil { t.Fatal(err) } - if count := len(cs); count != 0 { - t.Logf("Expect no corrections on second run, but found %d.", count) + if actualChangeCount != 0 { + t.Logf("Expect no corrections on second run, but found %d.", actualChangeCount) for i, c := range rs { t.Logf("INFO#%d:\n%s", i+1, c.Msg) } diff --git a/models/domain.go b/models/domain.go index 5b58d0cab..3054a443d 100644 --- a/models/domain.go +++ b/models/domain.go @@ -49,9 +49,10 @@ type DomainConfig struct { RawRecords []RawRecordConfig `json:"rawrecords,omitempty"` // Pending work to do for each provider. Provider may be a registrar or DSP. - pendingCorrectionsMutex sync.Mutex // Protect pendingCorrections* - pendingCorrections map[string]([]*Correction) // Work to be done for each provider - pendingCorrectionsOrder []string // Call the providers in this order + pendingCorrectionsMutex sync.Mutex // Protect pendingCorrections* + pendingCorrections map[string]([]*Correction) // Work to be done for each provider + pendingCorrectionsOrder []string // Call the providers in this order + pendingActualChangeCount map[string](int) // Number of changes to report (cumulative) } // GetSplitHorizonNames returns the domain's name, uniquename, and tag. @@ -176,3 +177,23 @@ func (dc *DomainConfig) GetCorrections(providerName string) []*Correction { } return nil } + +// IncrementChangeCount accumulates change count in a thread-safe way. +func (dc *DomainConfig) IncrementChangeCount(providerName string, delta int) { + dc.pendingCorrectionsMutex.Lock() + defer dc.pendingCorrectionsMutex.Unlock() + + if dc.pendingActualChangeCount == nil { + // First time storing anything. + dc.pendingActualChangeCount = make(map[string](int)) + } + dc.pendingActualChangeCount[providerName] += delta +} + +// GetChangeCount accumulates change count in a thread-safe way. +func (dc *DomainConfig) GetChangeCount(providerName string) int { + dc.pendingCorrectionsMutex.Lock() + defer dc.pendingCorrectionsMutex.Unlock() + + return dc.pendingActualChangeCount[providerName] +} diff --git a/models/provider.go b/models/provider.go index 11c7453bd..e98e83259 100644 --- a/models/provider.go +++ b/models/provider.go @@ -4,7 +4,7 @@ package models type DNSProvider interface { GetNameservers(domain string) ([]*Nameserver, error) GetZoneRecords(domain string, meta map[string]string) (Records, error) - GetZoneRecordsCorrections(dc *DomainConfig, existing Records) ([]*Correction, error) + GetZoneRecordsCorrections(dc *DomainConfig, existing Records) ([]*Correction, int, error) } // Registrar is an interface for Registrar plug-ins. diff --git a/pkg/acme/acme.go b/pkg/acme/acme.go index 2c0823e90..8d9457aac 100644 --- a/pkg/acme/acme.go +++ b/pkg/acme/acme.go @@ -276,7 +276,7 @@ func (c *certManager) getCorrections(d *models.DomainConfig) ([]*models.Correcti if err != nil { return nil, err } - reports, corrections, err := zonerecs.CorrectZoneRecords(p.Driver, dc) + reports, corrections, _, err := zonerecs.CorrectZoneRecords(p.Driver, dc) if err != nil { return nil, err } diff --git a/pkg/diff/diff.go b/pkg/diff/diff.go index f2b18b8b1..d572afcd3 100644 --- a/pkg/diff/diff.go +++ b/pkg/diff/diff.go @@ -20,10 +20,10 @@ type Changeset []Correlation // Differ is an interface for computing the difference between two zones. type Differ interface { // IncrementalDiff performs a diff on a record-by-record basis, and returns a sets for which records need to be created, deleted, or modified. - IncrementalDiff(existing []*models.RecordConfig) (reportMsgs []string, create, toDelete, modify Changeset, err error) + IncrementalDiff(existing []*models.RecordConfig) (reportMsgs []string, create, toDelete, modify Changeset, actualChangeCount int, err error) // ChangedGroups performs a diff more appropriate for providers with a "RecordSet" model, where all records with the same name and type are grouped. // Individual record changes are often not useful in such scenarios. Instead we return a map of record keys to a list of change descriptions within that group. - ChangedGroups(existing []*models.RecordConfig) (map[models.RecordKey][]string, []string, error) + ChangedGroups(existing []*models.RecordConfig) (map[models.RecordKey][]string, []string, int, error) } type differ struct { diff --git a/pkg/diff/diff2compat.go b/pkg/diff/diff2compat.go index 02ccae5df..43bab69a7 100644 --- a/pkg/diff/diff2compat.go +++ b/pkg/diff/diff2compat.go @@ -32,10 +32,10 @@ type differCompat struct { // IncrementalDiff usees pkg/diff2 to generate output compatible with systems // still using NewCompat(). -func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (reportMsgs []string, toCreate, toDelete, toModify Changeset, err error) { - instructions, err := diff2.ByRecord(existing, d.dc, nil) +func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (reportMsgs []string, toCreate, toDelete, toModify Changeset, actualChangeCount int, err error) { + instructions, actualChangeCount, err := diff2.ByRecord(existing, d.dc, nil) if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, 0, err } for _, inst := range instructions { @@ -71,11 +71,11 @@ func GenerateMessageCorrections(msgs []string) (corrections []*models.Correction } // ChangedGroups provides the same results as IncrementalDiff but grouped by key. -func (d *differCompat) ChangedGroups(existing []*models.RecordConfig) (map[models.RecordKey][]string, []string, error) { +func (d *differCompat) ChangedGroups(existing []*models.RecordConfig) (map[models.RecordKey][]string, []string, int, error) { changedKeys := map[models.RecordKey][]string{} - toReport, toCreate, toDelete, toModify, err := d.IncrementalDiff(existing) + toReport, toCreate, toDelete, toModify, actualChangeCount, err := d.IncrementalDiff(existing) if err != nil { - return nil, nil, err + return nil, nil, 0, err } for _, c := range toCreate { changedKeys[c.Desired.Key()] = append(changedKeys[c.Desired.Key()], c.String()) @@ -86,5 +86,5 @@ func (d *differCompat) ChangedGroups(existing []*models.RecordConfig) (map[model for _, m := range toModify { changedKeys[m.Desired.Key()] = append(changedKeys[m.Desired.Key()], m.String()) } - return changedKeys, toReport, nil + return changedKeys, toReport, actualChangeCount, nil } diff --git a/pkg/diff2/analyze.go b/pkg/diff2/analyze.go index 3f8d3ffdf..6201db7c4 100644 --- a/pkg/diff2/analyze.go +++ b/pkg/diff2/analyze.go @@ -9,8 +9,9 @@ import ( "github.com/fatih/color" ) -func analyzeByRecordSet(cc *CompareConfig) ChangeList { +func analyzeByRecordSet(cc *CompareConfig) (ChangeList, int) { var instructions ChangeList + var actualChangeCount int // For each label... for _, lc := range cc.ldata { // for each type at that label... @@ -18,7 +19,9 @@ func analyzeByRecordSet(cc *CompareConfig) ChangeList { // ...if there are changes generate an instruction. ets := rt.existingTargets dts := rt.desiredTargets - msgs := genmsgs(ets, dts) + cs := diffTargets(ets, dts) + actualChangeCount += len(cs) + msgs := justMsgs(cs) if len(msgs) == 0 { // No differences? // The records at this rset are the same. No work to be done. continue @@ -35,11 +38,12 @@ func analyzeByRecordSet(cc *CompareConfig) ChangeList { instructions = orderByDependencies(instructions) - return instructions + return instructions, actualChangeCount } -func analyzeByLabel(cc *CompareConfig) ChangeList { +func analyzeByLabel(cc *CompareConfig) (ChangeList, int) { var instructions ChangeList + var actualChangeCount int // Accumulate any changes and collect the info needed to generate instructions. for _, lc := range cc.ldata { // for each type at that label... @@ -52,7 +56,9 @@ func analyzeByLabel(cc *CompareConfig) ChangeList { // for each type at that label... ets := rt.existingTargets dts := rt.desiredTargets - msgs := genmsgs(ets, dts) + cs := diffTargets(ets, dts) + actualChangeCount += len(cs) + msgs := justMsgs(cs) k := models.RecordKey{NameFQDN: label, Type: rt.rType} msgsByKey[k] = msgs accMsgs = append(accMsgs, msgs...) // Accumulate the messages @@ -79,25 +85,27 @@ func analyzeByLabel(cc *CompareConfig) ChangeList { instructions = orderByDependencies(instructions) - return instructions + return instructions, actualChangeCount } -func analyzeByRecord(cc *CompareConfig) ChangeList { +func analyzeByRecord(cc *CompareConfig) (ChangeList, int) { var instructions ChangeList + var actualChangeCount int // For each label, for each type at that label, see if there are any changes. for _, lc := range cc.ldata { for _, rt := range lc.tdata { ets := rt.existingTargets dts := rt.desiredTargets cs := diffTargets(ets, dts) + actualChangeCount += len(cs) instructions = append(instructions, cs...) } } instructions = orderByDependencies(instructions) - return instructions + return instructions, actualChangeCount } // FYI: there is no analyzeByZone. diff2.ByZone() calls analyzeByRecords(). @@ -303,10 +311,6 @@ func diffTargets(existing, desired []targetConfig) ChangeList { return instructions } -func genmsgs(existing, desired []targetConfig) []string { - return justMsgs(diffTargets(existing, desired)) -} - func justMsgs(cl ChangeList) []string { var msgs []string for _, c := range cl { diff --git a/pkg/diff2/analyze_test.go b/pkg/diff2/analyze_test.go index a220ffac5..a4bc83b2c 100644 --- a/pkg/diff2/analyze_test.go +++ b/pkg/diff2/analyze_test.go @@ -127,7 +127,13 @@ func compareCL(t *testing.T, fnname, testname, testpart string, gotcl ChangeList if d != "" { t.Errorf("%s()/%s (wantChange%s):\n===got===\n%s\n===want===\n%s\n===diff===\n%s\n===", fnname, testname, testpart, gs, ws, d) } +} +func compareACC(t *testing.T, fnname, testname, testpart string, gotacc int, wantacc int) { + t.Helper() + if gotacc != wantacc { + t.Errorf("%s()/%s (wantChange%s):\n===got===\n%v\n===want===\n%v\n", fnname, testname, testpart, gotacc, wantacc) + } } func Test_analyzeByRecordSet(t *testing.T) { @@ -150,6 +156,7 @@ func Test_analyzeByRecordSet(t *testing.T) { wantChangeRec string wantMsgsRec string wantChangeZone string + wantChangeCount int }{ { @@ -159,6 +166,7 @@ func Test_analyzeByRecordSet(t *testing.T) { existing: models.Records{testDataAA1234}, desired: models.Records{testDataAA1234clone}, }, + wantChangeCount: 0, wantMsgs: "", // Empty wantChangeRSet: "ChangeList: len=0", wantChangeLabel: "ChangeList: len=0", @@ -172,7 +180,8 @@ func Test_analyzeByRecordSet(t *testing.T) { existing: models.Records{testDataAA1234, testDataAMX10a}, desired: models.Records{testDataAA1234clone, testDataAMX20b}, }, - wantMsgs: "± MODIFY laba.f.com MX (10 laba.f.com. ttl=300) -> (20 labb.f.com. ttl=300)", + wantChangeCount: 1, + wantMsgs: "± MODIFY laba.f.com MX (10 laba.f.com. ttl=300) -> (20 labb.f.com. ttl=300)", wantChangeRSet: ` ChangeList: len=1 00: Change: verb=CHANGE @@ -206,7 +215,8 @@ ChangeList: len=1 existing: models.Records{testDataAA1234, testDataApexMX1aaa}, desired: models.Records{testDataAA1234clone, testDataApexMX22bbb}, }, - wantMsgs: "± MODIFY f.com MX (1 aaa.f.com. ttl=300) -> (22 bbb.f.com. ttl=300)", + wantChangeCount: 1, + wantMsgs: "± MODIFY f.com MX (1 aaa.f.com. ttl=300) -> (22 bbb.f.com. ttl=300)", wantChangeRSet: ` ChangeList: len=1 00: Change: verb=CHANGE @@ -240,6 +250,7 @@ ChangeList: len=1 existing: models.Records{testDataAA1234, testDataAMX10a}, desired: models.Records{testDataAA1234clone, testDataAA12345, testDataAMX20b}, }, + wantChangeCount: 2, wantMsgs: ` ± MODIFY laba.f.com MX (10 laba.f.com. ttl=300) -> (20 labb.f.com. ttl=300) + CREATE laba.f.com A 1.2.3.5 ttl=300 @@ -290,6 +301,7 @@ ChangeList: len=2 existing: models.Records{testDataAA1234, testDataCCa}, desired: models.Records{d13, d3}, }, + wantChangeCount: 3, wantMsgs: ` + CREATE labe.f.com A 10.10.10.95 ttl=300 ± MODIFY labc.f.com CNAME (laba.f.com. ttl=300) -> (labe.f.com. ttl=300) @@ -352,6 +364,7 @@ ChangeList: len=3 existing: models.Records{testDataAA1234, testDataAMX10a, testDataCCa, testDataEA15, e4, e5, e6, e7, e8, e9, e10, e11}, desired: models.Records{testDataAA1234clone, testDataAA12345, testDataAMX20b, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12}, }, + wantChangeCount: 11, wantMsgs: ` + CREATE labf.f.com TXT "foo" ttl=300 ± MODIFY labg.f.com NS (labc.f.com. ttl=300) -> (labf.f.com. ttl=300) @@ -525,21 +538,24 @@ ChangeList: len=11 // Therefore we have to run NewCompareConfig() each time. t.Run(tt.name, func(t *testing.T) { - cl := analyzeByRecordSet(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) + cl, actualChangeCount := analyzeByRecordSet(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) compareMsgs(t, "analyzeByRecordSet", tt.name, "RSet", cl, tt.wantMsgsRSet, tt.wantMsgs) compareCL(t, "analyzeByRecordSet", tt.name, "RSet", cl, tt.wantChangeRSet) + compareACC(t, "analyzeByRecordSet", tt.name, "ACC", actualChangeCount, tt.wantChangeCount) }) t.Run(tt.name, func(t *testing.T) { - cl := analyzeByLabel(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) + cl, actualChangeCount := analyzeByLabel(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) compareMsgs(t, "analyzeByLabel", tt.name, "Label", cl, tt.wantMsgsLabel, tt.wantMsgs) compareCL(t, "analyzeByLabel", tt.name, "Label", cl, tt.wantChangeLabel) + compareACC(t, "analyzeByLabel", tt.name, "ACC", actualChangeCount, tt.wantChangeCount) }) t.Run(tt.name, func(t *testing.T) { - cl := analyzeByRecord(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) + cl, actualChangeCount := analyzeByRecord(NewCompareConfig(tt.args.origin, tt.args.existing, tt.args.desired, tt.args.compFn)) compareMsgs(t, "analyzeByRecord", tt.name, "Rec", cl, tt.wantMsgsRec, tt.wantMsgs) compareCL(t, "analyzeByRecord", tt.name, "Rec", cl, tt.wantChangeRec) + compareACC(t, "analyzeByRecord", tt.name, "ACC", actualChangeCount, tt.wantChangeCount) }) // NB(tlim): There is no analyzeByZone(). diff2.ByZone() uses analyzeByRecord(). diff --git a/pkg/diff2/diff2.go b/pkg/diff2/diff2.go index f8f27f7e7..ddfb7b650 100644 --- a/pkg/diff2/diff2.go +++ b/pkg/diff2/diff2.go @@ -151,7 +151,7 @@ func (c *Change) CreateCorrectionWithMessage(msg string, correctionFunction func // www.example.com, A, and a list of all the desired IP addresses. // // Examples include: AZURE_DNS, GCORE, NS1, ROUTE53 -func ByRecordSet(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, error) { +func ByRecordSet(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, int, error) { return byHelper(analyzeByRecordSet, existing, dc, compFunc) } @@ -163,7 +163,7 @@ func ByRecordSet(existing models.Records, dc *models.DomainConfig, compFunc Comp // to be served at a particular label, or the label itself is deleted. // // Examples include: GANDI_V5 -func ByLabel(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, error) { +func ByLabel(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, int, error) { return byHelper(analyzeByLabel, existing, dc, compFunc) } @@ -179,7 +179,7 @@ func ByLabel(existing models.Records, dc *models.DomainConfig, compFunc Comparab // A delete always has exactly 1 old: .Old[0] // // Examples include: CLOUDFLAREAPI, HEDNS, INWX, MSDNS, OVH, PORKBUN, VULTR -func ByRecord(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, error) { +func ByRecord(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, int, error) { return byHelper(analyzeByRecord, existing, dc, compFunc) } @@ -205,23 +205,16 @@ func ByRecord(existing models.Records, dc *models.DomainConfig, compFunc Compara // } // // Example providers include: BIND, AUTODNS -func ByZone(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) ([]string, bool, error) { +func ByZone(existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) ([]string, bool, int, error) { // Only return the messages. The caller has the list of records needed to build the new zone. - instructions, err := byHelper(analyzeByRecord, existing, dc, compFunc) - changes := false - for i := range instructions { - //fmt.Printf("DEBUG: ByZone #%d: %v\n", i, ii) - if instructions[i].Type != REPORT { - changes = true - } - } - return justMsgs(instructions), changes, err + instructions, actualChangeCount, err := byHelper(analyzeByRecord, existing, dc, compFunc) + return justMsgs(instructions), actualChangeCount > 0, actualChangeCount, err } // // byHelper does 90% of the work for the By*() calls. -func byHelper(fn func(cc *CompareConfig) ChangeList, existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, error) { +func byHelper(fn func(cc *CompareConfig) (ChangeList, int), existing models.Records, dc *models.DomainConfig, compFunc ComparableFunc) (ChangeList, int, error) { // Process NO_PURGE/ENSURE_ABSENT and IGNORE*(). desired, msgs, err := handsoff( @@ -232,14 +225,14 @@ func byHelper(fn func(cc *CompareConfig) ChangeList, existing models.Records, dc dc.KeepUnknown, ) if err != nil { - return nil, err + return nil, 0, err } // Regroup existing/desiredd for easy comparison: cc := NewCompareConfig(dc.Name, existing, desired, compFunc) // Analyze and generate the instructions: - instructions := fn(cc) + instructions, actualChangeCount := fn(cc) // If we have msgs, create a change to output them: if len(msgs) != 0 { @@ -252,5 +245,5 @@ func byHelper(fn func(cc *CompareConfig) ChangeList, existing models.Records, dc instructions = append([]Change{chg}, instructions...) } - return instructions, nil + return instructions, actualChangeCount, nil } diff --git a/pkg/zonerecs/zonerecords.go b/pkg/zonerecs/zonerecords.go index be8c882ae..b43f06b8a 100644 --- a/pkg/zonerecs/zonerecords.go +++ b/pkg/zonerecs/zonerecords.go @@ -7,11 +7,11 @@ import ( // CorrectZoneRecords calls both GetZoneRecords, does any // post-processing, and then calls GetZoneRecordsCorrections. The // name sucks because all the good names were taken. -func CorrectZoneRecords(driver models.DNSProvider, dc *models.DomainConfig) ([]*models.Correction, []*models.Correction, error) { +func CorrectZoneRecords(driver models.DNSProvider, dc *models.DomainConfig) ([]*models.Correction, []*models.Correction, int, error) { existingRecords, err := driver.GetZoneRecords(dc.Name, dc.Metadata) if err != nil { - return nil, nil, err + return nil, nil, 0, err } // downcase @@ -26,7 +26,7 @@ func CorrectZoneRecords(driver models.DNSProvider, dc *models.DomainConfig) ([]* // dc.Records. dc, err = dc.Copy() if err != nil { - return nil, nil, err + return nil, nil, 0, err } // punycode @@ -34,9 +34,9 @@ func CorrectZoneRecords(driver models.DNSProvider, dc *models.DomainConfig) ([]* // FIXME(tlim) It is a waste to PunyCode every iteration. // This should be moved to where the JavaScript is processed. - everything, err := driver.GetZoneRecordsCorrections(dc, existingRecords) + everything, actualChangeCount, err := driver.GetZoneRecordsCorrections(dc, existingRecords) reports, corrections := splitReportsAndCorrections(everything) - return reports, corrections, err + return reports, corrections, actualChangeCount, err } func splitReportsAndCorrections(everything []*models.Correction) (reports, corrections []*models.Correction) { diff --git a/providers/akamaiedgedns/akamaiEdgeDnsProvider.go b/providers/akamaiedgedns/akamaiEdgeDnsProvider.go index dbe6fb5f7..64c5a673a 100644 --- a/providers/akamaiedgedns/akamaiEdgeDnsProvider.go +++ b/providers/akamaiedgedns/akamaiEdgeDnsProvider.go @@ -107,10 +107,10 @@ func (a *edgeDNSProvider) EnsureZoneExists(domain string) error { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (a *edgeDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { - keysToUpdate, toReport, err := diff.NewCompat(dc).ChangedGroups(existingRecords) +func (a *edgeDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { + keysToUpdate, toReport, actualChangeCount, err := diff.NewCompat(dc).ChangedGroups(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -180,7 +180,7 @@ func (a *edgeDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi // AutoDnsSec correction existingAutoDNSSecEnabled, err := isAutoDNSSecEnabled(dc.Name) if err != nil { - return nil, err + return nil, 0, err } desiredAutoDNSSecEnabled := dc.AutoDNSSEC == "on" @@ -205,7 +205,7 @@ func (a *edgeDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi printer.Debugf("autoDNSSecEnable: Disable AutoDnsSec for zone %s\n", dc.Name) } - return corrections, nil + return corrections, actualChangeCount, nil } // GetNameservers returns the nameservers for a domain. diff --git a/providers/autodns/autoDnsProvider.go b/providers/autodns/autoDnsProvider.go index af7ec81ec..afc507c21 100644 --- a/providers/autodns/autoDnsProvider.go +++ b/providers/autodns/autoDnsProvider.go @@ -71,14 +71,14 @@ func New(settings map[string]string, _ json.RawMessage) (providers.DNSServicePro } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *autoDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *autoDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { domain := dc.Name var corrections []*models.Correction - msgs, changed, err := diff2.ByZone(existingRecords, dc, nil) + msgs, changed, actualChangeCount, err := diff2.ByZone(existingRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } if changed { @@ -107,7 +107,7 @@ func (api *autoDNSProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, e } - return corrections, nil + return corrections, actualChangeCount, nil } func recordsToNative(recs models.Records) ([]*models.Nameserver, uint32, []*ResourceRecord) { diff --git a/providers/axfrddns/axfrddnsProvider.go b/providers/axfrddns/axfrddnsProvider.go index 3033df4be..594396345 100644 --- a/providers/axfrddns/axfrddnsProvider.go +++ b/providers/axfrddns/axfrddnsProvider.go @@ -426,7 +426,7 @@ func hasNSDeletion(changes diff2.ChangeList) bool { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, error) { +func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, int, error) { // Ignoring the SOA, others providers don't manage it either. if len(foundRecords) >= 1 && foundRecords[0].Type == "SOA" { foundRecords = foundRecords[1:] @@ -466,19 +466,19 @@ func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, fo dummyNs1, err := dns.NewRR(dc.Name + ". IN NS 255.255.255.255") if err != nil { - return nil, err + return nil, 0, err } dummyNs2, err := dns.NewRR(dc.Name + ". IN NS 255.255.255.255") if err != nil { - return nil, err + return nil, 0, err } - changes, err := diff2.ByRecord(foundRecords, dc, nil) + changes, actualChangeCount, err := diff2.ByRecord(foundRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } if changes == nil { - return nil, nil + return nil, 0, nil } // A DNS server should silently ignore a DDNS update that removes @@ -547,5 +547,5 @@ func (c *axfrddnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, fo if len(reports) > 0 { returnValue = append(returnValue, c.BuildCorrection(dc, reports, nil)) } - return returnValue, nil + return returnValue, actualChangeCount, nil } diff --git a/providers/azuredns/azureDnsProvider.go b/providers/azuredns/azureDnsProvider.go index 0ab74a72a..856077ba7 100644 --- a/providers/azuredns/azureDnsProvider.go +++ b/providers/azuredns/azureDnsProvider.go @@ -190,14 +190,14 @@ func (a *azurednsProvider) getExistingRecords(domain string) (models.Records, [] } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (a *azurednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (a *azurednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction // Azure is a "ByRecordSet" API. - changes, err := diff2.ByRecordSet(existingRecords, dc, nil) + changes, actualChangeCount, err := diff2.ByRecordSet(existingRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -230,7 +230,7 @@ func (a *azurednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex } } - return corrections, nil + return corrections, actualChangeCount, nil } func (a *azurednsProvider) recordCreate(zoneName string, reckey models.RecordKey, recs models.Records) error { diff --git a/providers/azureprivatedns/azurePrivateDnsProvider.go b/providers/azureprivatedns/azurePrivateDnsProvider.go index 5a901380e..2e2b05fe6 100644 --- a/providers/azureprivatedns/azurePrivateDnsProvider.go +++ b/providers/azureprivatedns/azurePrivateDnsProvider.go @@ -187,12 +187,12 @@ func (a *azurednsProvider) getExistingRecords(domain string) (models.Records, [] } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (a *azurednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (a *azurednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction - changes, err := diff2.ByRecordSet(existingRecords, dc, nil) + changes, actualChangeCount, err := diff2.ByRecordSet(existingRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -225,7 +225,7 @@ func (a *azurednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex } } - return corrections, nil + return corrections, actualChangeCount, nil } func (a *azurednsProvider) recordCreate(zoneName string, reckey models.RecordKey, recs models.Records) error { diff --git a/providers/bind/bindProvider.go b/providers/bind/bindProvider.go index a8509542d..583693141 100644 --- a/providers/bind/bindProvider.go +++ b/providers/bind/bindProvider.go @@ -217,7 +217,7 @@ func ParseZoneContents(content string, zoneName string, zonefileName string) (mo } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, error) { +func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction changes := false @@ -248,12 +248,13 @@ func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundR var msgs []string var err error - msgs, changes, err = diff2.ByZone(foundRecords, dc, nil) + var actualChangeCount int + msgs, changes, actualChangeCount, err = diff2.ByZone(foundRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } if !changes { - return nil, nil + return nil, 0, nil } msg = strings.Join(msgs, "\n") @@ -311,7 +312,7 @@ func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundR }, }) - return corrections, nil + return corrections, actualChangeCount, nil } // preprocessFilename pre-processes a filename we're about to os.Create() diff --git a/providers/bunnydns/records.go b/providers/bunnydns/records.go index 00ff817fc..34e247bc0 100644 --- a/providers/bunnydns/records.go +++ b/providers/bunnydns/records.go @@ -2,6 +2,7 @@ package bunnydns import ( "fmt" + "github.com/StackExchange/dnscontrol/v4/models" "github.com/StackExchange/dnscontrol/v4/pkg/diff2" "github.com/StackExchange/dnscontrol/v4/pkg/printer" @@ -53,7 +54,7 @@ func (b *bunnydnsProvider) GetZoneRecords(domain string, meta map[string]string) return recs, nil } -func (b *bunnydnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (b *bunnydnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { // Bunny DNS never returns NS records for the apex domain, so these are artificially added when retrieving records. // As no TTL can be configured or retrieved for these NS records, we set it to 0 to avoid unnecessary updates. for _, rc := range dc.Records { @@ -68,12 +69,12 @@ func (b *bunnydnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex zone, err := b.findZoneByDomain(dc.Name) if err != nil { - return nil, err + return nil, 0, err } - instructions, err := diff2.ByRecord(existing, dc, nil) + instructions, actualChangeCount, err := diff2.ByRecord(existing, dc, nil) if err != nil { - return nil, err + return nil, 0, err } var corrections []*models.Correction @@ -100,7 +101,7 @@ func (b *bunnydnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex } } - return corrections, nil + return corrections, actualChangeCount, nil } func (b *bunnydnsProvider) mkCreateCorrection(zoneID int64, newRec *models.RecordConfig, msg string) *models.Correction { diff --git a/providers/cloudflare/cloudflareProvider.go b/providers/cloudflare/cloudflareProvider.go index 0188aa36c..89b090b0c 100644 --- a/providers/cloudflare/cloudflareProvider.go +++ b/providers/cloudflare/cloudflareProvider.go @@ -204,7 +204,7 @@ func (c *cloudflareProvider) getDomainID(name string) (string, error) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *cloudflareProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { +func (c *cloudflareProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { for _, rec := range dc.Records { if rec.Type == "ALIAS" { @@ -213,14 +213,14 @@ func (c *cloudflareProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, } if err := c.preprocessConfig(dc); err != nil { - return nil, err + return nil, 0, err } checkNSModifications(dc) domainID, err := c.getDomainID(dc.Name) if err != nil { - return nil, err + return nil, 0, err } for _, rec := range dc.Records { @@ -237,9 +237,9 @@ func (c *cloudflareProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, var corrections []*models.Correction // Cloudflare is a "ByRecord" API. - instructions, err := diff2.ByRecord(records, dc, genComparable) + instructions, actualChangeCount, err := diff2.ByRecord(records, dc, genComparable) if err != nil { - return nil, err + return nil, 0, err } for _, inst := range instructions { @@ -291,7 +291,7 @@ func (c *cloudflareProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, }) } - return corrections, nil + return corrections, actualChangeCount, nil } func genComparable(rec *models.RecordConfig) string { diff --git a/providers/cloudns/cloudnsProvider.go b/providers/cloudns/cloudnsProvider.go index d3f7952e5..36076fccb 100644 --- a/providers/cloudns/cloudnsProvider.go +++ b/providers/cloudns/cloudnsProvider.go @@ -114,16 +114,16 @@ func (c *cloudnsProvider) GetNameservers(domain string) ([]*models.Nameserver, e // } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { if c.domainIndex == nil { if err := c.fetchDomainList(); err != nil { - return nil, err + return nil, 0, err } } domainID, ok := c.domainIndex[dc.Name] if !ok { - return nil, fmt.Errorf("'%s' not a zone in ClouDNS account", dc.Name) + return nil, 0, fmt.Errorf("'%s' not a zone in ClouDNS account", dc.Name) } // Get a list of available TTL values. @@ -134,9 +134,9 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi record.TTL = fixTTL(record.TTL) } - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -168,7 +168,7 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi for _, m := range create { req, err := toReq(m.Desired) if err != nil { - return nil, err + return nil, 0, err } // ClouDNS does not require the trailing period to be specified when creating an NS record where the A or AAAA record exists in the zone. @@ -203,7 +203,7 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi id := m.Existing.Original.(*domainRecord).ID req, err := toReq(m.Desired) if err != nil { - return nil, err + return nil, 0, err } // ClouDNS does not require the trailing period to be specified when updating an NS record where the A or AAAA record exists in the zone. @@ -221,7 +221,7 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } diff --git a/providers/cscglobal/dns.go b/providers/cscglobal/dns.go index 41063a853..840dc81bd 100644 --- a/providers/cscglobal/dns.go +++ b/providers/cscglobal/dns.go @@ -75,11 +75,11 @@ func (client *providerClient) GetNameservers(domain string) ([]*models.Nameserve } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (client *providerClient) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, error) { +func (client *providerClient) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, int, error) { - toReport, creates, dels, modifications, err := diff.NewCompat(dc).IncrementalDiff(foundRecords) + toReport, creates, dels, modifications, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(foundRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -123,7 +123,7 @@ func (client *providerClient) GetZoneRecordsCorrections(dc *models.DomainConfig, corrections = append(corrections, c) } - return corrections, nil + return corrections, actualChangeCount, nil } func makePurge(cor diff.Correlation) zoneResourceRecordEdit { diff --git a/providers/desec/desecProvider.go b/providers/desec/desecProvider.go index 1e08d6c29..4c425f7ca 100644 --- a/providers/desec/desecProvider.go +++ b/providers/desec/desecProvider.go @@ -154,10 +154,10 @@ func PrepDesiredRecords(dc *models.DomainConfig, minTTL uint32) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { minTTL, ok, err := c.searchDomainIndex(dc.Name) if err != nil { - return nil, err + return nil, 0, err } if !ok { minTTL = 3600 @@ -165,15 +165,15 @@ func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist PrepDesiredRecords(dc, minTTL) - keysToUpdate, toReport, err := diff.NewCompat(dc).ChangedGroups(existing) + keysToUpdate, toReport, actualChangeCount, err := diff.NewCompat(dc).ChangedGroups(existing) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) if len(corrections) == 0 && len(keysToUpdate) == 0 { - return nil, nil + return nil, 0, nil } desiredRecords := dc.Records.GroupedByKey() @@ -245,7 +245,7 @@ func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist // be to just remove the sort. //sort.Slice(corrections, func(i, j int) bool { return diff.CorrectionLess(corrections, i, j) }) - return corrections, nil + return corrections, actualChangeCount, nil } // ListZones return all the zones in the account diff --git a/providers/digitalocean/digitaloceanProvider.go b/providers/digitalocean/digitaloceanProvider.go index 1d4d4c2dd..81fe4be31 100644 --- a/providers/digitalocean/digitaloceanProvider.go +++ b/providers/digitalocean/digitaloceanProvider.go @@ -172,12 +172,12 @@ func (api *digitaloceanProvider) GetZoneRecords(domain string, meta map[string]s } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *digitaloceanProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *digitaloceanProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { ctx := context.Background() - toReport, toCreate, toDelete, toModify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, toCreate, toDelete, toModify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -236,7 +236,7 @@ func (api *digitaloceanProvider) GetZoneRecordsCorrections(dc *models.DomainConf corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } func getRecords(api *digitaloceanProvider, name string) ([]godo.DomainRecord, error) { diff --git a/providers/dnsimple/dnsimpleProvider.go b/providers/dnsimple/dnsimpleProvider.go index 68ef7a005..d9455f0ee 100644 --- a/providers/dnsimple/dnsimpleProvider.go +++ b/providers/dnsimple/dnsimpleProvider.go @@ -160,17 +160,17 @@ func (c *dnsimpleProvider) GetZoneRecords(domain string, meta map[string]string) return cleanedRecords, nil } -func (c *dnsimpleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { +func (c *dnsimpleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { removeOtherApexNS(dc) dnssecFixes, err := c.getDNSSECCorrections(dc) if err != nil { - return nil, err + return nil, 0, err } - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(actual) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(actual) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -202,7 +202,7 @@ func (c *dnsimpleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ac }) } - return corrections, nil + return corrections, actualChangeCount, nil } func removeApexNS(records models.Records) models.Records { diff --git a/providers/dnsmadeeasy/dnsMadeEasyProvider.go b/providers/dnsmadeeasy/dnsMadeEasyProvider.go index 4364ab5ee..08f5655aa 100644 --- a/providers/dnsmadeeasy/dnsMadeEasyProvider.go +++ b/providers/dnsmadeeasy/dnsMadeEasyProvider.go @@ -103,11 +103,11 @@ func New(settings map[string]string, _ json.RawMessage) (providers.DNSServicePro // return api.GetZoneRecordsCorrections(dc, existingRecords) // } -func (api *dnsMadeEasyProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *dnsMadeEasyProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { domainName := dc.Name domain, err := api.findDomain(domainName) if err != nil { - return nil, err + return nil, 0, err } for _, rec := range dc.Records { @@ -120,9 +120,9 @@ func (api *dnsMadeEasyProvider) GetZoneRecordsCorrections(dc *models.DomainConfi } } - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -186,7 +186,7 @@ func (api *dnsMadeEasyProvider) GetZoneRecordsCorrections(dc *models.DomainConfi corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } // EnsureZoneExists creates a zone if it does not exist diff --git a/providers/domainnameshop/dns.go b/providers/domainnameshop/dns.go index 320506b6f..6915b65f1 100644 --- a/providers/domainnameshop/dns.go +++ b/providers/domainnameshop/dns.go @@ -25,7 +25,7 @@ func (api *domainNameShopProvider) GetZoneRecords(domain string, meta map[string } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { // Merge TXT strings to one string for _, rc := range dc.Records { @@ -39,9 +39,9 @@ func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainCo record.TTL = fixTTL(record.TTL) } - toReport, create, delete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, delete, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -65,7 +65,7 @@ func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainCo dnsR, err := api.fromRecordConfig(domainName, r.Desired) if err != nil { - return nil, err + return nil, 0, err } corr := &models.Correction{ @@ -81,7 +81,7 @@ func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainCo dnsR, err := api.fromRecordConfig(domainName, r.Desired) if err != nil { - return nil, err + return nil, 0, err } dnsR.ID = r.Existing.Original.(*domainNameShopRecord).ID @@ -94,7 +94,7 @@ func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainCo corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } func (api *domainNameShopProvider) GetNameservers(domain string) ([]*models.Nameserver, error) { diff --git a/providers/exoscale/exoscaleProvider.go b/providers/exoscale/exoscaleProvider.go index 7d77a1daf..999fe2599 100644 --- a/providers/exoscale/exoscaleProvider.go +++ b/providers/exoscale/exoscaleProvider.go @@ -187,18 +187,18 @@ func (c *exoscaleProvider) GetZoneRecords(domainName string, meta map[string]str } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *exoscaleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (c *exoscaleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { removeOtherNS(dc) domain, err := c.findDomainByName(dc.Name) if err != nil { - return nil, err + return nil, 0, err } domainID := *domain.ID - toReport, create, toDelete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, toDelete, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -228,7 +228,7 @@ func (c *exoscaleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex }) } - return corrections, nil + return corrections, actualChangeCount, nil } // Returns a function that can be invoked to create a record in a zone. diff --git a/providers/gandiv5/gandi_v5Provider.go b/providers/gandiv5/gandi_v5Provider.go index 06e0ca92a..6d030cc8e 100644 --- a/providers/gandiv5/gandi_v5Provider.go +++ b/providers/gandiv5/gandi_v5Provider.go @@ -202,7 +202,7 @@ func PrepDesiredRecords(dc *models.DomainConfig) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (client *gandiv5Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (client *gandiv5Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction if client.debug { debugRecords("GenDC input", existing) @@ -214,9 +214,9 @@ func (client *gandiv5Provider) GetZoneRecordsCorrections(dc *models.DomainConfig // Gandi is a "ByLabel" API with the odd exception that changes must be // done one label:rtype at a time. - instructions, err := diff2.ByLabel(existing, dc, nil) + instructions, actualChangeCount, err := diff2.ByLabel(existing, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, inst := range instructions { switch inst.Type { @@ -292,7 +292,7 @@ func (client *gandiv5Provider) GetZoneRecordsCorrections(dc *models.DomainConfig } - return corrections, nil + return corrections, actualChangeCount, nil } // debugRecords prints a list of RecordConfig. diff --git a/providers/gcloud/gcloudProvider.go b/providers/gcloud/gcloudProvider.go index 026103f44..ae976139f 100644 --- a/providers/gcloud/gcloudProvider.go +++ b/providers/gcloud/gcloudProvider.go @@ -241,14 +241,14 @@ func (g *gcloudProvider) getZoneSets(domain string) (models.Records, error) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (g *gcloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (g *gcloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { - changes, err := diff2.ByRecordSet(existingRecords, dc, nil) + changes, actualChangeCount, err := diff2.ByRecordSet(existingRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } if len(changes) == 0 { - return nil, nil + return nil, 0, nil } var corrections []*models.Correction @@ -280,7 +280,7 @@ func (g *gcloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis newAdds = nil newDels = change.Old[0].Original.(*gdns.ResourceRecordSet) default: - return nil, fmt.Errorf("GCLOUD unhandled change.TYPE %s", change.Type) + return nil, 0, fmt.Errorf("GCLOUD unhandled change.TYPE %s", change.Type) } // If the work would overflow the current batch, process what we have so far and start a new batch. @@ -308,7 +308,7 @@ func (g *gcloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis // Process the remaining work. corrections = g.mkCorrection(corrections, accumlatedMsgs, batch, dc.Name) - return corrections, nil + return corrections, actualChangeCount, nil } // mkRRSs returns a gdns.ResourceRecordSet using the name, rType, and recs diff --git a/providers/gcore/gcoreProvider.go b/providers/gcore/gcoreProvider.go index 14123c94d..91f930c2e 100644 --- a/providers/gcore/gcoreProvider.go +++ b/providers/gcore/gcoreProvider.go @@ -137,7 +137,7 @@ func generateChangeMsg(updates []string) string { // a list of functions to call to actually make the desired // correction, and a message to output to the user when the change is // made. -func (c *gcoreProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (c *gcoreProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { // Make delete happen earlier than creates & updates. var corrections []*models.Correction @@ -151,9 +151,9 @@ func (c *gcoreProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist } } - changes, err := diff2.ByRecordSet(existing, dc, nil) + changes, actualChangeCount, err := diff2.ByRecordSet(existing, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -196,7 +196,7 @@ func (c *gcoreProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist dnssecEnabled, err := c.dnssdkGetDNSSEC(dc.Name) if err != nil { - return nil, err + return nil, 0, err } if !dnssecEnabled && dc.AutoDNSSEC == "on" { @@ -221,5 +221,5 @@ func (c *gcoreProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist result := append(reports, deletions...) result = append(result, corrections...) - return result, nil + return result, actualChangeCount, nil } diff --git a/providers/hedns/hednsProvider.go b/providers/hedns/hednsProvider.go index d5e3f7276..1da1992a6 100644 --- a/providers/hedns/hednsProvider.go +++ b/providers/hedns/hednsProvider.go @@ -186,7 +186,7 @@ func (c *hednsProvider) GetNameservers(_ string) ([]*models.Nameserver, error) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *hednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { +func (c *hednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { // Get the SOA record to get the ZoneID, then remove it from the list. zoneID := uint64(0) @@ -202,10 +202,10 @@ func (c *hednsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, recor return c.getDiff2DomainCorrections(dc, zoneID, prunedRecords) } -func (c *hednsProvider) getDiff2DomainCorrections(dc *models.DomainConfig, zoneID uint64, records models.Records) ([]*models.Correction, error) { - changes, err := diff2.ByRecord(records, dc, nil) +func (c *hednsProvider) getDiff2DomainCorrections(dc *models.DomainConfig, zoneID uint64, records models.Records) ([]*models.Correction, int, error) { + changes, actualChangeCount, err := diff2.ByRecord(records, dc, nil) if err != nil { - return nil, err + return nil, 0, err } var corrections []*models.Correction @@ -243,7 +243,7 @@ func (c *hednsProvider) getDiff2DomainCorrections(dc *models.DomainConfig, zoneI } } - return corrections, nil + return corrections, actualChangeCount, nil } // GetZoneRecords returns all the records for the given domain diff --git a/providers/hetzner/hetznerProvider.go b/providers/hetzner/hetznerProvider.go index 242c826f3..8f911919d 100644 --- a/providers/hetzner/hetznerProvider.go +++ b/providers/hetzner/hetznerProvider.go @@ -74,19 +74,19 @@ func (api *hetznerProvider) EnsureZoneExists(domain string) error { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *hetznerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *hetznerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { domain := dc.Name - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) z, err := api.getZone(domain) if err != nil { - return nil, err + return nil, 0, err } for _, m := range del { @@ -136,7 +136,7 @@ func (api *hetznerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, e corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } // GetNameservers returns the nameservers for a domain. diff --git a/providers/hexonet/records.go b/providers/hexonet/records.go index 43dd6d2c0..7d164548e 100644 --- a/providers/hexonet/records.go +++ b/providers/hexonet/records.go @@ -56,10 +56,10 @@ func (n *HXClient) GetZoneRecords(domain string, meta map[string]string) (models } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (n *HXClient) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { - toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(actual) +func (n *HXClient) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { + toReport, create, del, mod, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(actual) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -76,7 +76,7 @@ func (n *HXClient) GetZoneRecordsCorrections(dc *models.DomainConfig, actual mod rec := cre.Desired recordString, err := n.createRecordString(rec, dc.Name) if err != nil { - return corrections, err + return corrections, 0, err } params[fmt.Sprintf("ADDRR%d", addrridx)] = recordString addrridx++ @@ -96,7 +96,7 @@ func (n *HXClient) GetZoneRecordsCorrections(dc *models.DomainConfig, actual mod params[fmt.Sprintf("DELRR%d", delrridx)] = n.deleteRecordString(old) newRecordString, err := n.createRecordString(new, dc.Name) if err != nil { - return corrections, err + return corrections, 0, err } params[fmt.Sprintf("ADDRR%d", addrridx)] = newRecordString addrridx++ @@ -113,7 +113,7 @@ func (n *HXClient) GetZoneRecordsCorrections(dc *models.DomainConfig, actual mod }) } - return corrections, nil + return corrections, actualChangeCount, nil } func toRecord(r *HXRecord, origin string) *models.RecordConfig { diff --git a/providers/hostingde/hostingdeProvider.go b/providers/hostingde/hostingdeProvider.go index 80a0fabed..aa109007d 100644 --- a/providers/hostingde/hostingdeProvider.go +++ b/providers/hostingde/hostingdeProvider.go @@ -123,7 +123,7 @@ func soaToString(s soaValues) string { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { +func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { var err error // TTL must be between (inclusive) 1m and 1y (in fact, a little bit more) @@ -140,12 +140,12 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, zone, err := hp.getZone(dc.Name) if err != nil { - return nil, err + return nil, 0, err } - toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(records) + toReport, create, del, mod, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(records) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -225,7 +225,7 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, if existingAutoDNSSecEnabled && desiredAutoDNSSecEnabled { currentDNSSecOptions, err := hp.getDNSSECOptions(zone.ZoneConfig.ID) if err != nil { - return nil, err + return nil, 0, err } if !currentDNSSecOptions.PublishKSK { msg = append(msg, "Enabling publishKsk for AutoDNSSec") @@ -246,7 +246,7 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, } else if existingAutoDNSSecEnabled && !desiredAutoDNSSecEnabled { currentDNSSecOptions, err := hp.getDNSSECOptions(zone.ZoneConfig.ID) if err != nil { - return nil, err + return nil, 0, err } msg = append(msg, "Disable AutoDNSSEC") zone.ZoneConfig.DNSSECMode = "off" @@ -254,7 +254,7 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, // Remove auto dnssec keys from domain DomainConfig, err := hp.getDomainConfig(dc.Name) if err != nil { - return nil, err + return nil, 0, err } for _, entry := range DomainConfig.DNSSecEntries { for _, autoDNSKey := range currentDNSSecOptions.Keys { @@ -267,7 +267,7 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, } if !zoneChanged { - return nil, nil + return nil, 0, nil } corrections = append(corrections, &models.Correction{ @@ -306,7 +306,7 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, corrections = append(corrections, correction) } - return corrections, nil + return corrections, actualChangeCount, nil } func firstNonZero(items ...uint32) uint32 { diff --git a/providers/huaweicloud/records.go b/providers/huaweicloud/records.go index 5b1a6f327..8efb9da92 100644 --- a/providers/huaweicloud/records.go +++ b/providers/huaweicloud/records.go @@ -45,13 +45,13 @@ func (c *huaweicloudProvider) GetZoneRecords(domain string, meta map[string]stri // a list of functions to call to actually make the desired // correction, and a message to output to the user when the change is // made. -func (c *huaweicloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (c *huaweicloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { if err := c.getZones(); err != nil { - return nil, err + return nil, 0, err } zoneID, ok := c.zoneIDByDomain[dc.Name] if !ok { - return nil, fmt.Errorf("zone %s not found", dc.Name) + return nil, 0, fmt.Errorf("zone %s not found", dc.Name) } addDefaultMeta(dc.Records) @@ -61,9 +61,9 @@ func (c *huaweicloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, var deletions []*models.Correction var reports []*models.Correction - changes, err := diff2.ByRecordSet(existing, dc, genComparable) + changes, actualChangeCount, err := diff2.ByRecordSet(existing, dc, genComparable) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -133,7 +133,7 @@ func (c *huaweicloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, result := append(reports, deletions...) result = append(result, corrections...) - return result, nil + return result, actualChangeCount, nil } func collectRecordsByLineAndWeightAndKey(records models.Records) map[string]models.Records { diff --git a/providers/inwx/inwxProvider.go b/providers/inwx/inwxProvider.go index 020460814..3c5ca53f0 100644 --- a/providers/inwx/inwxProvider.go +++ b/providers/inwx/inwxProvider.go @@ -236,15 +236,15 @@ func checkRecords(records models.Records) error { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, error) { +func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, int, error) { err := checkRecords(dc.Records) if err != nil { - return nil, err + return nil, 0, err } - toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(foundRecords) + toReport, create, del, mod, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(foundRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -272,7 +272,7 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco }) } - return corrections, nil + return corrections, actualChangeCount, nil } // getDefaultNameservers returns string map with default nameservers based on e.g. sandbox mode. diff --git a/providers/linode/linodeProvider.go b/providers/linode/linodeProvider.go index efa45980c..24bbaa1e8 100644 --- a/providers/linode/linodeProvider.go +++ b/providers/linode/linodeProvider.go @@ -131,7 +131,7 @@ func (api *linodeProvider) GetZoneRecords(domain string, meta map[string]string) } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { // Linode doesn't allow selecting an arbitrary TTL, only a set of predefined values // We need to make sure we don't change it every time if it is as close as it's going to get // The documentation says that it will always round up to the next highest value: 300 -> 300, 301 -> 3600. @@ -142,17 +142,17 @@ func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex if api.domainIndex == nil { if err := api.fetchDomainList(); err != nil { - return nil, err + return nil, 0, err } } domainID, ok := api.domainIndex[dc.Name] if !ok { - return nil, fmt.Errorf("'%s' not a zone in Linode account", dc.Name) + return nil, 0, fmt.Errorf("'%s' not a zone in Linode account", dc.Name) } - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -174,11 +174,11 @@ func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex for _, m := range create { req, err := toReq(dc, m.Desired) if err != nil { - return nil, err + return nil, 0, err } j, err := json.Marshal(req) if err != nil { - return nil, err + return nil, 0, err } corr := &models.Correction{ Msg: fmt.Sprintf("%s: %s", m.String(), string(j)), @@ -200,11 +200,11 @@ func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex } req, err := toReq(dc, m.Desired) if err != nil { - return nil, err + return nil, 0, err } j, err := json.Marshal(req) if err != nil { - return nil, err + return nil, 0, err } corr := &models.Correction{ Msg: fmt.Sprintf("%s, Linode ID: %d: %s", m.String(), id, string(j)), @@ -215,7 +215,7 @@ func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } func (api *linodeProvider) getRecordsForDomain(domainID int, domain string) (models.Records, error) { diff --git a/providers/loopia/loopiaProvider.go b/providers/loopia/loopiaProvider.go index 8e6d1dc2f..1d4908c33 100644 --- a/providers/loopia/loopiaProvider.go +++ b/providers/loopia/loopiaProvider.go @@ -270,7 +270,7 @@ func gatherAffectedLabels(groups map[models.RecordKey][]string) (labels map[stri } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *APIClient) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (c *APIClient) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { if c.Debug { debugRecords("GenerateZoneRecordsCorrections input:\n", existingRecords) @@ -280,16 +280,16 @@ func (c *APIClient) GetZoneRecordsCorrections(dc *models.DomainConfig, existingR var keysToUpdate map[models.RecordKey][]string differ := diff.NewCompat(dc) - toReport, create, del, modify, err := differ.IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := differ.IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) - keysToUpdate, _, err = differ.ChangedGroups(existingRecords) + keysToUpdate, _, _, err = differ.ChangedGroups(existingRecords) if err != nil { - return nil, err + return nil, 0, err } for _, d := range create { @@ -365,7 +365,7 @@ func (c *APIClient) GetZoneRecordsCorrections(dc *models.DomainConfig, existingR }) } - return corrections, nil + return corrections, actualChangeCount, nil } // debugRecords prints a list of RecordConfig. diff --git a/providers/luadns/luadnsProvider.go b/providers/luadns/luadnsProvider.go index ac301c14e..aa240ab80 100644 --- a/providers/luadns/luadnsProvider.go +++ b/providers/luadns/luadnsProvider.go @@ -100,21 +100,21 @@ func (l *luadnsProvider) GetZoneRecords(domain string, meta map[string]string) ( } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (l *luadnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { +func (l *luadnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction checkNS(dc) domainID, err := l.getDomainID(dc.Name) if err != nil { - return nil, err + return nil, 0, err } var corrs []*models.Correction - changes, err := diff2.ByRecord(records, dc, nil) + changes, actualChangeCount, err := diff2.ByRecord(records, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -133,7 +133,7 @@ func (l *luadnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, reco } corrections = append(corrections, corrs...) } - return corrections, nil + return corrections, actualChangeCount, nil } func (l *luadnsProvider) makeCreateCorrection(newrec *models.RecordConfig, domainID uint32, msg string) []*models.Correction { diff --git a/providers/msdns/corrections.go b/providers/msdns/corrections.go index 32cd6197a..57ad783b7 100644 --- a/providers/msdns/corrections.go +++ b/providers/msdns/corrections.go @@ -8,14 +8,14 @@ import ( ) // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (client *msdnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, error) { +func (client *msdnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction models.PostProcessRecords(foundRecords) - changes, err := diff2.ByRecord(foundRecords, dc, nil) + changes, actualChangeCount, err := diff2.ByRecord(foundRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } var corr *models.Correction @@ -66,7 +66,7 @@ func (client *msdnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } func (client *msdnsProvider) deleteOneRecord(dnsserver, zonename string, oldrec *models.RecordConfig) error { diff --git a/providers/mythicbeasts/mythicbeastsProvider.go b/providers/mythicbeasts/mythicbeastsProvider.go index 9bef9de87..517a8ceb0 100644 --- a/providers/mythicbeasts/mythicbeastsProvider.go +++ b/providers/mythicbeasts/mythicbeastsProvider.go @@ -114,10 +114,10 @@ func zoneFileToRecords(r io.Reader, origin string) (models.Records, error) { } // 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, error) { - msgs, changes, err := diff2.ByZone(actual, dc, nil) +func (n *mythicBeastsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { + msgs, changes, actualChangeCount, err := diff2.ByZone(actual, dc, nil) if err != nil { - return nil, err + return nil, 0, err } var corrections []*models.Correction @@ -151,7 +151,7 @@ func (n *mythicBeastsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig }) } - return corrections, nil + return corrections, actualChangeCount, nil } // GetNameservers returns the nameservers for a domain. diff --git a/providers/namecheap/namecheapProvider.go b/providers/namecheap/namecheapProvider.go index a69dfe6f9..cad13c80c 100644 --- a/providers/namecheap/namecheapProvider.go +++ b/providers/namecheap/namecheapProvider.go @@ -64,7 +64,7 @@ func newReg(conf map[string]string) (providers.Registrar, error) { return newProvider(conf, nil) } -func newProvider(m map[string]string, metadata json.RawMessage) (*namecheapProvider, error) { +func newProvider(m map[string]string, _ json.RawMessage) (*namecheapProvider, error) { api := &namecheapProvider{} api.APIUser, api.APIKEY = m["apiuser"], m["apikey"] if api.APIKEY == "" || api.APIUser == "" { @@ -236,7 +236,7 @@ func (n *namecheapProvider) GetZoneRecords(domain string, meta map[string]string // } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (n *namecheapProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { +func (n *namecheapProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { // namecheap does not allow setting @ NS with basic DNS dc.Filter(func(r *models.RecordConfig) bool { @@ -249,9 +249,9 @@ func (n *namecheapProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, a return true }) - toReport, create, delete, modify, err := diff.NewCompat(dc).IncrementalDiff(actual) + toReport, create, delete, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(actual) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -283,7 +283,7 @@ func (n *namecheapProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, a }) } - return corrections, nil + return corrections, actualChangeCount, nil } func toRecords(result *nc.DomainDNSGetHostsResult, origin string) ([]*models.RecordConfig, error) { diff --git a/providers/namedotcom/records.go b/providers/namedotcom/records.go index 241d023b6..b457ba379 100644 --- a/providers/namedotcom/records.go +++ b/providers/namedotcom/records.go @@ -28,7 +28,7 @@ func (n *namedotcomProvider) GetZoneRecords(domain string, meta map[string]strin } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (n *namedotcomProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { +func (n *namedotcomProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { checkNSModifications(dc) for _, rec := range dc.Records { @@ -37,9 +37,9 @@ func (n *namedotcomProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, } } - toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(actual) + toReport, create, del, mod, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(actual) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -67,7 +67,7 @@ func (n *namedotcomProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, corrections = append(corrections, c) } - return corrections, nil + return corrections, actualChangeCount, nil } func checkNSModifications(dc *models.DomainConfig) { diff --git a/providers/netcup/netcupProvider.go b/providers/netcup/netcupProvider.go index 3483b387b..e3d336b7e 100644 --- a/providers/netcup/netcupProvider.go +++ b/providers/netcup/netcupProvider.go @@ -74,7 +74,7 @@ func (api *netcupProvider) GetNameservers(domain string) ([]*models.Nameserver, } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *netcupProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *netcupProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { domain := dc.Name // Setting the TTL is not supported for netcup @@ -91,9 +91,9 @@ func (api *netcupProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex } dc.Records = newRecords - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -133,5 +133,5 @@ func (api *netcupProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } diff --git a/providers/netlify/netlifyProvider.go b/providers/netlify/netlifyProvider.go index ad90aac5b..82c234dac 100644 --- a/providers/netlify/netlifyProvider.go +++ b/providers/netlify/netlifyProvider.go @@ -160,17 +160,17 @@ func (n *netlifyProvider) ListZones() ([]string, error) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (n *netlifyProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(records) +func (n *netlifyProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(records) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) zone, err := n.getZone(dc.Name) if err != nil { - return nil, err + return nil, 0, err } // Deletes first so changing type works etc. @@ -214,7 +214,7 @@ func (n *netlifyProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, rec corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } func toReq(rc *models.RecordConfig) *dnsRecordCreate { diff --git a/providers/ns1/ns1Provider.go b/providers/ns1/ns1Provider.go index d62b244b8..4d88b7287 100644 --- a/providers/ns1/ns1Provider.go +++ b/providers/ns1/ns1Provider.go @@ -198,7 +198,7 @@ func (n *nsone) getDomainCorrectionsDNSSEC(domain, toggleDNSSEC string) *models. } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (n *nsone) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (n *nsone) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction domain := dc.Name @@ -207,9 +207,9 @@ func (n *nsone) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecor corrections = append(corrections, dnssecCorrections) } - changes, err := diff2.ByRecordSet(existingRecords, dc, nil) + changes, actualChangeCount, err := diff2.ByRecordSet(existingRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -240,7 +240,7 @@ func (n *nsone) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecor } } - return corrections, nil + return corrections, actualChangeCount, nil } func (n *nsone) add(recs models.Records, domain string) error { diff --git a/providers/oracle/oracleProvider.go b/providers/oracle/oracleProvider.go index debf27614..58a3a3c55 100644 --- a/providers/oracle/oracleProvider.go +++ b/providers/oracle/oracleProvider.go @@ -213,7 +213,7 @@ func (o *oracleProvider) GetZoneRecords(zone string, meta map[string]string) (mo } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { var err error // Ensure we don't emit changes for attempted modification of built-in apex NSs @@ -234,9 +234,9 @@ func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis } } - toReport, create, dels, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, dels, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -258,7 +258,6 @@ func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis createRecords = append(createRecords, rec.Desired) desc += rec.String() + "\n" } - desc = desc[:len(desc)-1] } if len(dels) > 0 { @@ -266,7 +265,6 @@ func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis deleteRecords = append(deleteRecords, rec.Existing) desc += rec.String() + "\n" } - desc = desc[:len(desc)-1] } if len(modify) > 0 { @@ -275,7 +273,6 @@ func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis deleteRecords = append(deleteRecords, rec.Existing) desc += rec.String() + "\n" } - desc = desc[:len(desc)-1] } // There were corrections. Send them as one big batch: @@ -288,7 +285,7 @@ func (o *oracleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis }) } - return corrections, nil + return corrections, actualChangeCount, nil } func (o *oracleProvider) patch(createRecords, deleteRecords models.Records, domain string) error { diff --git a/providers/ovh/ovhProvider.go b/providers/ovh/ovhProvider.go index c78a5e3e1..006dae3ca 100644 --- a/providers/ovh/ovhProvider.go +++ b/providers/ovh/ovhProvider.go @@ -141,11 +141,11 @@ func (c *ovhProvider) GetZoneRecords(domain string, meta map[string]string) (mod } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *ovhProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { +func (c *ovhProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { - corrections, err := c.getDiff2DomainCorrections(dc, actual) + corrections, actualChangeCount, err := c.getDiff2DomainCorrections(dc, actual) if err != nil { - return nil, err + return nil, 0, err } // Only refresh zone if there's a real modification @@ -166,14 +166,14 @@ func (c *ovhProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual }) } - return corrections, nil + return corrections, actualChangeCount, nil } -func (c *ovhProvider) getDiff2DomainCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { +func (c *ovhProvider) getDiff2DomainCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction - instructions, err := diff2.ByRecord(actual, dc, nil) + instructions, actualChangeCount, err := diff2.ByRecord(actual, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, inst := range instructions { @@ -200,7 +200,7 @@ func (c *ovhProvider) getDiff2DomainCorrections(dc *models.DomainConfig, actual panic(fmt.Sprintf("unhandled inst.Type %s", inst.Type)) } } - return corrections, nil + return corrections, actualChangeCount, nil } func nativeToRecord(r *Record, origin string) (*models.RecordConfig, error) { diff --git a/providers/packetframe/packetframeProvider.go b/providers/packetframe/packetframeProvider.go index 7a9342a01..2d012e978 100644 --- a/providers/packetframe/packetframeProvider.go +++ b/providers/packetframe/packetframeProvider.go @@ -106,15 +106,15 @@ func (api *packetframeProvider) GetZoneRecords(domain string, meta map[string]st } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *packetframeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *packetframeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { zone, err := api.getZone(dc.Name) if err != nil { - return nil, fmt.Errorf("no such zone %q in Packetframe account", dc.Name) + return nil, 0, fmt.Errorf("no such zone %q in Packetframe account", dc.Name) } - toReport, create, dels, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, dels, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -122,7 +122,7 @@ func (api *packetframeProvider) GetZoneRecordsCorrections(dc *models.DomainConfi for _, m := range create { req, err := toReq(zone.ID, m.Desired) if err != nil { - return nil, err + return nil, 0, err } corr := &models.Correction{ Msg: m.String(), @@ -168,7 +168,7 @@ func (api *packetframeProvider) GetZoneRecordsCorrections(dc *models.DomainConfi corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } func toReq(zoneID string, rc *models.RecordConfig) (*domainRecord, error) { diff --git a/providers/porkbun/porkbunProvider.go b/providers/porkbun/porkbunProvider.go index 394fddafd..defa5b7cb 100644 --- a/providers/porkbun/porkbunProvider.go +++ b/providers/porkbun/porkbunProvider.go @@ -102,7 +102,7 @@ func genComparable(rec *models.RecordConfig) string { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (c *porkbunProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (c *porkbunProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction // Block changes to NS records for base domain @@ -128,9 +128,9 @@ func (c *porkbunProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi } } - changes, err := diff2.ByRecord(existingRecords, dc, genComparable) + changes, actualChangeCount, err := diff2.ByRecord(existingRecords, dc, genComparable) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { var corr *models.Correction @@ -140,7 +140,7 @@ func (c *porkbunProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi case diff2.CREATE: req, err := toReq(change.New[0]) if err != nil { - return nil, err + return nil, 0, err } corr = &models.Correction{ Msg: change.Msgs[0], @@ -155,7 +155,7 @@ func (c *porkbunProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi id := change.Old[0].Original.(*domainRecord).ID req, err := toReq(change.New[0]) if err != nil { - return nil, err + return nil, 0, err } corr = &models.Correction{ Msg: fmt.Sprintf("%s, porkbun ID: %s", change.Msgs[0], id), @@ -183,7 +183,7 @@ func (c *porkbunProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi corrections = append(corrections, corr) } - return corrections, nil + return corrections, actualChangeCount, nil } // GetZoneRecords gets the records of a zone and returns them in RecordConfig format. diff --git a/providers/powerdns/diff.go b/providers/powerdns/diff.go index 92a3354b3..fdd2ee201 100644 --- a/providers/powerdns/diff.go +++ b/providers/powerdns/diff.go @@ -11,10 +11,10 @@ import ( "github.com/mittwald/go-powerdns/apis/zones" ) -func (dsp *powerdnsProvider) getDiff2DomainCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { - changes, err := diff2.ByRecordSet(existing, dc, nil) +func (dsp *powerdnsProvider) getDiff2DomainCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { + changes, actualChangeCount, err := diff2.ByRecordSet(existing, dc, nil) if err != nil { - return nil, err + return nil, 0, err } var corrections []*models.Correction @@ -75,7 +75,7 @@ func (dsp *powerdnsProvider) getDiff2DomainCorrections(dc *models.DomainConfig, }, }) } - return corrections, nil + return corrections, actualChangeCount, nil } // buildRecordList returns a list of records for the PowerDNS resource record set from a change diff --git a/providers/powerdns/dns.go b/providers/powerdns/dns.go index 391018d06..a57fd0db2 100644 --- a/providers/powerdns/dns.go +++ b/providers/powerdns/dns.go @@ -45,20 +45,21 @@ func (dsp *powerdnsProvider) GetZoneRecords(domain string, meta map[string]strin } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (dsp *powerdnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (dsp *powerdnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { - corrections, err := dsp.getDiff2DomainCorrections(dc, existing) + corrections, actualChangeCount, err := dsp.getDiff2DomainCorrections(dc, existing) if err != nil { - return nil, err + return nil, 0, err } // DNSSec corrections dnssecCorrections, err := dsp.getDNSSECCorrections(dc) if err != nil { - return nil, err + return nil, 0, err } + actualChangeCount += len(dnssecCorrections) - return append(corrections, dnssecCorrections...), nil + return append(corrections, dnssecCorrections...), actualChangeCount, nil } // EnsureZoneExists creates a zone if it does not exist diff --git a/providers/providers.go b/providers/providers.go index fd36c2d8d..86ab34a57 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -171,8 +171,8 @@ func (n None) GetZoneRecords(domain string, meta map[string]string) (models.Reco } // GetZoneRecordsCorrections gets the records of a zone and returns them in RecordConfig format. -func (n None) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { - return nil, nil +func (n None) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { + return nil, 0, nil } // GetDomainCorrections returns corrections to update a domain. diff --git a/providers/realtimeregister/realtimeregisterProvider.go b/providers/realtimeregister/realtimeregisterProvider.go index 807b2d98d..fb433fa31 100644 --- a/providers/realtimeregister/realtimeregisterProvider.go +++ b/providers/realtimeregister/realtimeregisterProvider.go @@ -106,16 +106,16 @@ func (api *realtimeregisterAPI) GetZoneRecords(domain string, meta map[string]st return recordConfigs, nil } -func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { - msgs, changes, err := diff2.ByZone(existing, dc, nil) +func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { + msgs, changes, actualChangeCount, err := diff2.ByZone(existing, dc, nil) if err != nil { - return nil, err + return nil, 0, err } var corrections []*models.Correction if !changes { - return corrections, nil + return corrections, 0, nil } dnssec := api.Zones[dc.Name].Dnssec @@ -129,6 +129,7 @@ func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfi return nil }, }) + actualChangeCount++ } if !api.Zones[dc.Name].Dnssec && dc.AutoDNSSEC == "on" { @@ -140,6 +141,7 @@ func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfi return nil }, }) + actualChangeCount++ } if changes { @@ -162,7 +164,7 @@ func (api *realtimeregisterAPI) GetZoneRecordsCorrections(dc *models.DomainConfi }) } - return corrections, nil + return corrections, actualChangeCount, nil } func (api *realtimeregisterAPI) ListZones() ([]string, error) { diff --git a/providers/route53/route53Provider.go b/providers/route53/route53Provider.go index ad2c1c598..05d3fdcb1 100644 --- a/providers/route53/route53Provider.go +++ b/providers/route53/route53Provider.go @@ -282,10 +282,10 @@ func (r *route53Provider) getZoneRecords(zone r53Types.HostedZone) (models.Recor } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (r *route53Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (r *route53Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { zone, err := r.getZone(dc) if err != nil { - return nil, err + return nil, 0, err } // update zone_id to current zone.id if not specified by the user @@ -301,9 +301,9 @@ func (r *route53Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi // Amazon Route53 is a "ByRecordSet" API. // At each label:rtype pair, we either delete all records or UPSERT the desired records. - instructions, err := diff2.ByRecordSet(existingRecords, dc, nil) + instructions, actualChangeCount, err := diff2.ByRecordSet(existingRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } instructions = reorderInstructions(instructions) var reports []*models.Correction @@ -403,10 +403,10 @@ func (r *route53Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi addCorrection(descBatchStr, req) } if err := batcher.Err(); err != nil { - return nil, err + return nil, 0, err } - return append(reports, corrections...), nil + return append(reports, corrections...), actualChangeCount, nil } diff --git a/providers/rwth/dns.go b/providers/rwth/dns.go index cec9189b0..b1433b05d 100644 --- a/providers/rwth/dns.go +++ b/providers/rwth/dns.go @@ -29,12 +29,12 @@ func (api *rwthProvider) GetNameservers(domain string) ([]*models.Nameserver, er } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *rwthProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) { +func (api *rwthProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) { domain := dc.Name - toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) + toReport, create, del, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(existingRecords) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -70,5 +70,5 @@ func (api *rwthProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis }) } - return corrections, nil + return corrections, actualChangeCount, nil } diff --git a/providers/sakuracloud/records.go b/providers/sakuracloud/records.go index 6dd434fe0..126fb34e3 100644 --- a/providers/sakuracloud/records.go +++ b/providers/sakuracloud/records.go @@ -53,7 +53,7 @@ func (s *sakuracloudProvider) GetZoneRecords(domain string, meta map[string]stri } // GetZoneRecordsCorrections gets the records of a zone and returns them in RecordConfig format. -func (s *sakuracloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, error) { +func (s *sakuracloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction // The name servers for the Sakura cloud provider cannot be changed. @@ -65,12 +65,12 @@ func (s *sakuracloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, } } - msgs, changes, err := diff2.ByZone(existing, dc, nil) + msgs, changes, actualChangeCount, err := diff2.ByZone(existing, dc, nil) if err != nil { - return nil, err + return nil, 0, err } if !changes { - return nil, nil + return nil, actualChangeCount, nil } msg := strings.Join(msgs, "\n") @@ -87,5 +87,5 @@ func (s *sakuracloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, }, ) - return corrections, nil + return corrections, actualChangeCount, nil } diff --git a/providers/softlayer/softlayerProvider.go b/providers/softlayer/softlayerProvider.go index 81e4446f3..32f339d38 100644 --- a/providers/softlayer/softlayerProvider.go +++ b/providers/softlayer/softlayerProvider.go @@ -81,15 +81,15 @@ func (s *softlayerProvider) GetZoneRecords(domainName string, meta map[string]st } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (s *softlayerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) { +func (s *softlayerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, int, error) { domain, err := s.getDomain(&dc.Name) if err != nil { - return nil, err + return nil, 0, err } - toReport, create, deletes, modify, err := diff.NewCompat(dc).IncrementalDiff(actual) + toReport, create, deletes, modify, actualChangeCount, err := diff.NewCompat(dc).IncrementalDiff(actual) if err != nil { - return nil, err + return nil, 0, err } // Start corrections with the reports corrections := diff.GenerateMessageCorrections(toReport) @@ -117,7 +117,7 @@ func (s *softlayerProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, a }) } - return corrections, nil + return corrections, actualChangeCount, nil } func (s *softlayerProvider) getDomain(name *string) (*datatypes.Dns_Domain, error) { diff --git a/providers/transip/transipProvider.go b/providers/transip/transipProvider.go index a2e715473..a83acc397 100644 --- a/providers/transip/transipProvider.go +++ b/providers/transip/transipProvider.go @@ -114,20 +114,20 @@ func (n *transipProvider) ListZones() ([]string, error) { } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (n *transipProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, curRecords models.Records) ([]*models.Correction, error) { +func (n *transipProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, curRecords models.Records) ([]*models.Correction, int, error) { removeOtherNS(dc) - corrections, err := n.getCorrectionsUsingDiff2(dc, curRecords) - return corrections, err + corrections, actualChangeCount, err := n.getCorrectionsUsingDiff2(dc, curRecords) + return corrections, actualChangeCount, err } -func (n *transipProvider) getCorrectionsUsingDiff2(dc *models.DomainConfig, records models.Records) ([]*models.Correction, error) { +func (n *transipProvider) getCorrectionsUsingDiff2(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction - instructions, err := diff2.ByRecordSet(records, dc, nil) + instructions, actualChangeCount, err := diff2.ByRecordSet(records, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range instructions { @@ -136,7 +136,7 @@ func (n *transipProvider) getCorrectionsUsingDiff2(dc *models.DomainConfig, reco case diff2.DELETE: oldEntries, err := recordsToNative(change.Old, true) if err != nil { - return corrections, err + return corrections, 0, err } correction := change.CreateCorrection( wrapChangeFunction( @@ -149,7 +149,7 @@ func (n *transipProvider) getCorrectionsUsingDiff2(dc *models.DomainConfig, reco case diff2.CREATE: newEntries, err := recordsToNative(change.New, false) if err != nil { - return corrections, err + return corrections, 0, err } correction := change.CreateCorrection( wrapChangeFunction( @@ -163,7 +163,7 @@ func (n *transipProvider) getCorrectionsUsingDiff2(dc *models.DomainConfig, reco if canDirectApplyDNSEntries(change) { newEntries, err := recordsToNative(change.New, false) if err != nil { - return corrections, err + return corrections, 0, err } correction := change.CreateCorrection( wrapChangeFunction( @@ -184,7 +184,7 @@ func (n *transipProvider) getCorrectionsUsingDiff2(dc *models.DomainConfig, reco } - return corrections, nil + return corrections, actualChangeCount, nil } func (n *transipProvider) recreateRecordSet(dc *models.DomainConfig, change diff2.Change) []*models.Correction { diff --git a/providers/vultr/vultrProvider.go b/providers/vultr/vultrProvider.go index 0c6151945..25aa9143d 100644 --- a/providers/vultr/vultrProvider.go +++ b/providers/vultr/vultrProvider.go @@ -115,7 +115,7 @@ func (api *vultrProvider) GetZoneRecords(domain string, meta map[string]string) } // GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records. -func (api *vultrProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, curRecords models.Records) ([]*models.Correction, error) { +func (api *vultrProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, curRecords models.Records) ([]*models.Correction, int, error) { var corrections []*models.Correction for _, rec := range dc.Records { @@ -124,7 +124,7 @@ func (api *vultrProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, cur // These rtypes are hostnames, therefore need to be converted (unlike, for example, an AAAA record) t, err := idna.ToUnicode(rec.GetTargetField()) if err != nil { - return nil, err + return nil, 0, err } rec.SetTarget(t) default: @@ -132,10 +132,9 @@ func (api *vultrProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, cur } } - changes, err := diff2.ByRecord(curRecords, dc, nil) - + changes, actualChangeCount, err := diff2.ByRecord(curRecords, dc, nil) if err != nil { - return nil, err + return nil, 0, err } for _, change := range changes { @@ -172,7 +171,7 @@ func (api *vultrProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, cur } } - return corrections, nil + return corrections, actualChangeCount, nil } // GetNameservers gets the Vultr nameservers for a domain