Skip to content

Commit

Permalink
Legacy systems can now process "report" messages
Browse files Browse the repository at this point in the history
  • Loading branch information
tlimoncelli committed Oct 1, 2023
1 parent dac3851 commit 402390c
Show file tree
Hide file tree
Showing 24 changed files with 109 additions and 89 deletions.
2 changes: 1 addition & 1 deletion pkg/diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ 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) (unchanged, create, toDelete, modify Changeset, err error)
IncrementalDiff(existing []*models.RecordConfig) (reportMsgs []string, create, toDelete, modify Changeset, 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, error)
Expand Down
19 changes: 9 additions & 10 deletions pkg/diff/diff2compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type differCompat struct {
// - The NewCompat() feature `extraValues` is not supported. That
// parameter must be set to nil. If you use that feature, consider
// one of the pkg/diff2/By*() functions.
func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (unchanged, toCreate, toDelete, toModify Changeset, err error) {
func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (reportMsgs []string, toCreate, toDelete, toModify Changeset, err error) {
instructions, err := diff2.ByRecord(existing, d.dc, nil)
if err != nil {
return nil, nil, nil, nil, err
Expand All @@ -55,15 +55,7 @@ func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (unchang
cor := Correlation{}
switch inst.Type {
case diff2.REPORT:
// Sadly the NewCompat function doesn't have an equivalent. We
// just output the messages now.
fmt.Print("INFO: ")
fmt.Println(inst.MsgsJoined)

// TODO(tlim): When diff1 is deleted, IncremtntalDiff should add a
// parameter to list the REPORT messages. It can also eliminate the
// first parameter (existing) since nobody uses that in the diff2
// world.
reportMsgs = append(reportMsgs, inst.Msgs...)
case diff2.CREATE:
cor.Desired = inst.New[0]
toCreate = append(toCreate, cor)
Expand All @@ -82,6 +74,13 @@ func (d *differCompat) IncrementalDiff(existing []*models.RecordConfig) (unchang
return
}

func GenerateMessageCorrections(msgs []string) (corrections []*models.Correction) {
for _, msg := range msgs {
corrections = append(corrections, &models.Correction{Msg: msg})
}
return
}

// ChangedGroups provides the same results as IncrementalDiff but grouped by key.
func (d *differCompat) ChangedGroups(existing []*models.RecordConfig) (map[models.RecordKey][]string, error) {
changedKeys := map[models.RecordKey][]string{}
Expand Down
5 changes: 3 additions & 2 deletions providers/cloudns/cloudnsProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@ func (c *cloudnsProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi
record.TTL = fixTTL(record.TTL)
}

var corrections []*models.Correction
_, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// Deletes first so changing type works etc.
for _, m := range del {
Expand Down
5 changes: 3 additions & 2 deletions providers/cscglobal/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,12 @@ func (client *providerClient) GetNameservers(domain string) ([]*models.Nameserve
func (client *providerClient) GetZoneRecordsCorrections(dc *models.DomainConfig, foundRecords models.Records) ([]*models.Correction, error) {
//txtutil.SplitSingleLongTxt(dc.Records) // Autosplit long TXT records

var corrections []*models.Correction
_, creates, dels, modifications, err := diff.NewCompat(dc).IncrementalDiff(foundRecords)
toReport, creates, dels, modifications, err := diff.NewCompat(dc).IncrementalDiff(foundRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// CSCGlobal has a unique API. A list of edits is sent in one API
// call. Edits aren't permitted if an existing edit is being
Expand Down
5 changes: 3 additions & 2 deletions providers/digitalocean/digitaloceanProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,12 @@ func (api *digitaloceanProvider) GetZoneRecordsCorrections(dc *models.DomainConf

ctx := context.Background()

var corrections []*models.Correction
_, toCreate, toDelete, toModify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, toCreate, toDelete, toModify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// Deletes first so changing type works etc.
for _, m := range toDelete {
Expand Down
9 changes: 5 additions & 4 deletions providers/dnsimple/dnsimpleProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,21 @@ func (c *dnsimpleProvider) GetZoneRecords(domain string, meta map[string]string)
}

func (c *dnsimpleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, actual models.Records) ([]*models.Correction, error) {
var corrections []*models.Correction

removeOtherApexNS(dc)

dnssecFixes, err := c.getDNSSECCorrections(dc)
if err != nil {
return nil, err
}
corrections = append(corrections, dnssecFixes...)

_, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(actual)
toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(actual)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)
// Next dnsSec fixes
corrections = append(corrections, dnssecFixes...)

for _, del := range del {
rec := del.Existing.Original.(dnsimpleapi.ZoneRecord)
Expand Down
5 changes: 3 additions & 2 deletions providers/dnsmadeeasy/dnsMadeEasyProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,12 @@ func (api *dnsMadeEasyProvider) GetZoneRecordsCorrections(dc *models.DomainConfi
}
}

var corrections []*models.Correction
_, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

var deleteRecordIds []int
deleteDescription := []string{"Batch deletion of records:"}
Expand Down
5 changes: 3 additions & 2 deletions providers/domainnameshop/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainCo
record.TTL = fixTTL(record.TTL)
}

var corrections []*models.Correction
_, create, delete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, delete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// Delete record
for _, r := range delete {
Expand Down
5 changes: 3 additions & 2 deletions providers/exoscale/exoscaleProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,12 @@ func (c *exoscaleProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex
}
domainID := *domain.ID

var corrections []*models.Correction
_, create, toDelete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, toDelete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

for _, del := range toDelete {
record := del.Existing.Original.(*egoscale.DNSDomainRecord)
Expand Down
10 changes: 6 additions & 4 deletions providers/gcloud/gcloudProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ type correctionValues struct {

// 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) {

txtutil.SplitSingleLongTxt(dc.Records) // Autosplit long TXT records

oldRRs, ok := g.oldRRsMap[dc.Name]
Expand All @@ -272,16 +271,20 @@ func (g *gcloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis
}

// first collect keys that have changed
_, create, delete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, toDelete, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, fmt.Errorf("incdiff error: %w", err)
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// Now generate all other corrections

changedKeys := map[key]string{}
for _, c := range create {
changedKeys[keyForRec(c.Desired)] = fmt.Sprintln(c)
}
for _, d := range delete {
for _, d := range toDelete {
changedKeys[keyForRec(d.Existing)] = fmt.Sprintln(d)
}
for _, m := range modify {
Expand Down Expand Up @@ -366,7 +369,6 @@ func (g *gcloudProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exis
}
// create a Correction for each gdns.Change
// that needs to be executed
corrections := []*models.Correction{}
makeCorrection := func(chg *gdns.Change, msgs string) {
runChange := func() error {
retry:
Expand Down
5 changes: 3 additions & 2 deletions providers/hetzner/hetznerProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,16 @@ 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) {
var corrections []*models.Correction
domain := dc.Name

txtutil.SplitSingleLongTxt(dc.Records) // Autosplit long TXT records

_, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

z, err := api.getZone(domain)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions providers/hexonet/records.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ 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) {
var corrections []*models.Correction

txtutil.SplitSingleLongTxt(dc.Records)

_, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(actual)
toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(actual)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

buf := &bytes.Buffer{}
// Print a list of changes. Generate an actual change that is the zone
Expand Down
47 changes: 24 additions & 23 deletions providers/hostingde/hostingdeProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,12 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig,
return nil, err
}

_, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(records)
toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(records)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// NOPURGE
if dc.KeepUnknown {
Expand Down Expand Up @@ -261,31 +263,30 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig,
return nil, nil
}

corrections := []*models.Correction{
{
Msg: fmt.Sprintf("\n%s", strings.Join(msg, "\n")),
F: func() error {
for i := 0; i < 10; i++ {
err := hp.updateZone(&zone.ZoneConfig, DNSSecOptions, create, del, mod)
if err == nil {
return nil
}
// Code:10205 indicates the zone is currently blocked due to a running zone update.
if !strings.Contains(err.Error(), "Code:10205") {
return err
}

// Exponential back-off retry.
// Base of 1.8 seemed like a good trade-off, retrying for approximately 45 seconds.
time.Sleep(time.Duration(math.Pow(1.8, float64(i))) * 100 * time.Millisecond)
corrections = append(corrections, &models.Correction{
Msg: fmt.Sprintf("\n%s", strings.Join(msg, "\n")),
F: func() error {
for i := 0; i < 10; i++ {
err := hp.updateZone(&zone.ZoneConfig, DNSSecOptions, create, del, mod)
if err == nil {
return nil
}
return fmt.Errorf("retry exhaustion: zone blocked for 10 attempts")
},
// Code:10205 indicates the zone is currently blocked due to a running zone update.
if !strings.Contains(err.Error(), "Code:10205") {
return err
}

// Exponential back-off retry.
// Base of 1.8 seemed like a good trade-off, retrying for approximately 45 seconds.
time.Sleep(time.Duration(math.Pow(1.8, float64(i))) * 100 * time.Millisecond)
}
return fmt.Errorf("retry exhaustion: zone blocked for 10 attempts")
},
}
},
)

if removeDNSSecEntries != nil {
correction := models.Correction{
correction := &models.Correction{
Msg: "Removing AutoDNSSEC Keys from Domain",
F: func() error {
err := hp.dnsSecKeyModify(dc.Name, nil, removeDNSSecEntries)
Expand All @@ -295,7 +296,7 @@ func (hp *hostingdeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig,
return nil
},
}
corrections = append(corrections, &correction)
corrections = append(corrections, correction)
}

return corrections, nil
Expand Down
5 changes: 3 additions & 2 deletions providers/inwx/inwxProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,12 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco
return nil, err
}

var corrections []*models.Correction
_, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(foundRecords)
toReport, create, del, mod, err := diff.NewCompat(dc).IncrementalDiff(foundRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

for _, d := range create {
des := d.Desired
Expand Down
5 changes: 3 additions & 2 deletions providers/linode/linodeProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ 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) {
var corrections []*models.Correction
// 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.
Expand All @@ -145,10 +144,12 @@ func (api *linodeProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, ex
return nil, fmt.Errorf("'%s' not a zone in Linode account", dc.Name)
}

_, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
toReport, create, del, modify, err := diff.NewCompat(dc).IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

// Deletes first so changing type works etc.
for _, m := range del {
Expand Down
6 changes: 4 additions & 2 deletions providers/loopia/loopiaProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ 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) {
var corrections []*models.Correction

if c.Debug {
debugRecords("GenerateZoneRecordsCorrections input:\n", existingRecords)
Expand All @@ -278,7 +277,7 @@ func (c *APIClient) GetZoneRecordsCorrections(dc *models.DomainConfig, existingR

var keysToUpdate map[models.RecordKey][]string
differ := diff.NewCompat(dc)
_, create, del, modify, err := differ.IncrementalDiff(existingRecords)
toReport, create, del, modify, err := differ.IncrementalDiff(existingRecords)
if err != nil {
return nil, err
}
Expand All @@ -287,6 +286,9 @@ func (c *APIClient) GetZoneRecordsCorrections(dc *models.DomainConfig, existingR
return nil, err
}

// Start corrections with the reports
corrections := diff.GenerateMessageCorrections(toReport)

for _, d := range create {
// fmt.Printf("a creation: subdomain: %+v, existingfqdn: %+v \n", d.Desired.Name, d.Desired.NameFQDN)
des := d.Desired
Expand Down
Loading

0 comments on commit 402390c

Please sign in to comment.