mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-09 05:36:27 +08:00
ALIDNS: Use diff2
This commit is contained in:
parent
988a6596d2
commit
820cde51d1
2 changed files with 51 additions and 54 deletions
|
|
@ -1748,7 +1748,7 @@ func makeTests() []*TestGroup {
|
||||||
|
|
||||||
// IGNORE with changes
|
// IGNORE with changes
|
||||||
testgroup("IGNORE with modify",
|
testgroup("IGNORE with modify",
|
||||||
not("NAMECHEAP", "ALIDNS"), // Will fail until converted to use diff2 module.
|
not("NAMECHEAP"), // Will fail until converted to use diff2 module.
|
||||||
tc("Create some records",
|
tc("Create some records",
|
||||||
a("foo", "1.1.1.1"),
|
a("foo", "1.1.1.1"),
|
||||||
a("foo", "10.10.10.10"),
|
a("foo", "10.10.10.10"),
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v4/models"
|
"github.com/StackExchange/dnscontrol/v4/models"
|
||||||
"github.com/StackExchange/dnscontrol/v4/pkg/diff"
|
"github.com/StackExchange/dnscontrol/v4/pkg/diff2"
|
||||||
"github.com/StackExchange/dnscontrol/v4/pkg/printer"
|
|
||||||
"github.com/StackExchange/dnscontrol/v4/providers"
|
"github.com/StackExchange/dnscontrol/v4/providers"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
||||||
)
|
)
|
||||||
|
|
@ -109,76 +108,74 @@ func (a *aliDnsDsp) GetZoneRecords(domain string, meta map[string]string) (model
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeTrailingDot(record string) string {
|
||||||
|
return strings.TrimSuffix(record, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func deduplicateNameServerTargets(newRecs models.Records) models.Records {
|
||||||
|
dedupedMap := make(map[string]bool)
|
||||||
|
var deduped models.Records
|
||||||
|
for _, rec := range newRecs {
|
||||||
|
if !dedupedMap[rec.GetTargetField()] {
|
||||||
|
dedupedMap[rec.GetTargetField()] = true
|
||||||
|
deduped = append(deduped, rec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deduped
|
||||||
|
}
|
||||||
|
|
||||||
func (a *aliDnsDsp) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) {
|
func (a *aliDnsDsp) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) {
|
||||||
keysToUpdate, toReport, actualChangeCount, err := diff.NewCompat(dc).ChangedGroups(existingRecords)
|
var corrections []*models.Correction
|
||||||
|
|
||||||
|
// Azure is a "ByRecordSet" API.
|
||||||
|
changes, actualChangeCount, err := diff2.ByRecord(existingRecords, dc, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
// Start corrections with the reports
|
|
||||||
corrections := diff.GenerateMessageCorrections(toReport)
|
|
||||||
|
|
||||||
existingRecordsMap := make(map[models.RecordKey][]*models.RecordConfig)
|
for _, change := range changes {
|
||||||
for _, r := range existingRecords {
|
// Copy all param values to local variables to avoid overwrites
|
||||||
key := models.RecordKey{NameFQDN: r.NameFQDN, Type: r.Type}
|
msgs := change.MsgsJoined
|
||||||
existingRecordsMap[key] = append(existingRecordsMap[key], r)
|
dcn := dc.Name
|
||||||
}
|
chaKey := change.Key
|
||||||
|
|
||||||
desiredRecordsMap := dc.Records.GroupedByKey()
|
if change.Type == diff2.CHANGE || change.Type == diff2.CREATE {
|
||||||
|
if chaKey.Type == "NS" && dcn == removeTrailingDot(change.Key.NameFQDN) {
|
||||||
|
change.New = deduplicateNameServerTargets(change.New)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Deletes must occur first. For example, if replacing a existing CNAME with an A of the same name:
|
switch change.Type {
|
||||||
// DELETE CNAME foo.example.net
|
case diff2.REPORT:
|
||||||
// must occur before
|
corrections = append(corrections, &models.Correction{Msg: change.MsgsJoined})
|
||||||
// CREATE A foo.example.net
|
case diff2.CREATE:
|
||||||
// because both an A and a CNAME for the same name is not allowed.
|
changeNew := change.New
|
||||||
|
|
||||||
lastCorrections := []*models.Correction{} // creates and replaces last
|
|
||||||
|
|
||||||
for key, msg := range keysToUpdate {
|
|
||||||
existing, okExisting := existingRecordsMap[key]
|
|
||||||
desired, okDesired := desiredRecordsMap[key]
|
|
||||||
|
|
||||||
if okExisting && !okDesired {
|
|
||||||
// In the existing map but not in the desired map: Delete
|
|
||||||
corrections = append(corrections, &models.Correction{
|
corrections = append(corrections, &models.Correction{
|
||||||
Msg: strings.Join(msg, "\n "),
|
Msg: msgs,
|
||||||
F: func() error {
|
F: func() error {
|
||||||
return a.deleteRecordset(existing, dc.Name)
|
return a.createRecordset(changeNew, dcn)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
printer.Debugf("deleteRecordset: %s %s\n", key.NameFQDN, key.Type)
|
case diff2.CHANGE:
|
||||||
for _, rdata := range existing {
|
changeNew := change.New
|
||||||
printer.Debugf(" Rdata: %s\n", rdata.GetTargetCombined())
|
changeExisting := change.Old
|
||||||
}
|
corrections = append(corrections, &models.Correction{
|
||||||
} else if !okExisting && okDesired {
|
Msg: msgs,
|
||||||
// Not in the existing map but in the desired map: Create
|
|
||||||
lastCorrections = append(lastCorrections, &models.Correction{
|
|
||||||
Msg: strings.Join(msg, "\n "),
|
|
||||||
F: func() error {
|
F: func() error {
|
||||||
return a.createRecordset(desired, dc.Name)
|
return a.updateRecordset(changeExisting, changeNew, dcn)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
printer.Debugf("createRecordset: %s %s\n", key.NameFQDN, key.Type)
|
case diff2.DELETE:
|
||||||
for _, rdata := range desired {
|
corrections = append(corrections, &models.Correction{
|
||||||
printer.Debugf(" Rdata: %s\n", rdata.GetTargetCombined())
|
Msg: msgs,
|
||||||
}
|
|
||||||
} else if okExisting && okDesired {
|
|
||||||
// In the existing map and in the desired map: Replace
|
|
||||||
lastCorrections = append(lastCorrections, &models.Correction{
|
|
||||||
Msg: strings.Join(msg, "\n "),
|
|
||||||
F: func() error {
|
F: func() error {
|
||||||
return a.updateRecordset(existing, desired, dc.Name)
|
return a.deleteRecordset(change.Old, dcn)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
printer.Debugf("updateRecordset: %s %s\n", key.NameFQDN, key.Type)
|
default:
|
||||||
for _, rdata := range desired {
|
panic(fmt.Sprintf("unhandled change.Type %s", change.Type))
|
||||||
printer.Debugf(" Rdata: %s\n", rdata.GetTargetCombined())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append creates and updates after deletes
|
|
||||||
corrections = append(corrections, lastCorrections...)
|
|
||||||
|
|
||||||
printer.Debugf("Found %d corrections (actualChangeCount=%d)\n", len(corrections), actualChangeCount)
|
|
||||||
return corrections, actualChangeCount, nil
|
return corrections, actualChangeCount, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue