Skip to content

Commit

Permalink
refactor and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mircea-pavel-anton committed Oct 29, 2024
1 parent 877f346 commit a721602
Show file tree
Hide file tree
Showing 2 changed files with 461 additions and 91 deletions.
123 changes: 82 additions & 41 deletions internal/mikrotik/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,47 +64,6 @@ func (p *MikrotikProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, e
return endpoints, nil
}

func cleanupChanges(changes *plan.Changes) *plan.Changes {
for oldIndex, old := range changes.UpdateOld {
for newIndex, new := range changes.UpdateNew {
if old.DNSName == new.DNSName && old.Targets[0] == new.Targets[0] && old.RecordTTL == new.RecordTTL {
needUpdate := false

oldComment, _ := old.GetProviderSpecificProperty("comment")
newComment, _ := new.GetProviderSpecificProperty("webhook/comment")
if oldComment != newComment {
needUpdate = true
}

oldMatchSubdomain, _ := old.GetProviderSpecificProperty("match-subdomain")
newMatchSubdomain, _ := new.GetProviderSpecificProperty("webhook/match-subdomain")
if oldMatchSubdomain != newMatchSubdomain {
needUpdate = true
}

oldAddressList, _ := old.GetProviderSpecificProperty("address-list")
newAddressList, _ := new.GetProviderSpecificProperty("webhook/address-list")
if oldAddressList != newAddressList {
needUpdate = true
}

oldRegexp, _ := old.GetProviderSpecificProperty("regexp")
newRegexp, _ := new.GetProviderSpecificProperty("webhook/regexp")
if oldRegexp != newRegexp {
needUpdate = true
}

if !needUpdate {
changes.UpdateOld = append(changes.UpdateOld[:oldIndex], changes.UpdateOld[oldIndex+1:]...)
changes.UpdateNew = append(changes.UpdateNew[:newIndex], changes.UpdateNew[newIndex+1:]...)
}
}
}
}

return changes
}

// ApplyChanges applies a given set of changes in the DNS provider.
func (p *MikrotikProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error {
changes = cleanupChanges(changes)
Expand All @@ -128,3 +87,85 @@ func (p *MikrotikProvider) ApplyChanges(ctx context.Context, changes *plan.Chang
func (p *MikrotikProvider) GetDomainFilter() endpoint.DomainFilterInterface {
return p.domainFilter
}

// ================================================================================================
// UTILS
// ================================================================================================
func getProviderSpecific(ep *endpoint.Endpoint, ps string) string {
value, valueExists := ep.GetProviderSpecificProperty(ps)
if !valueExists {
value, _ = ep.GetProviderSpecificProperty(fmt.Sprintf("webhook/%s", ps))
}
return value
}

func isEndpointMatching(a *endpoint.Endpoint, b *endpoint.Endpoint) bool {
if a.DNSName != b.DNSName || a.Targets[0] != b.Targets[0] || a.RecordTTL != b.RecordTTL {
return false
}

aComment := getProviderSpecific(a, "comment")
bComment := getProviderSpecific(b, "comment")
if aComment != bComment {
return false
}

aMatchSubdomain := getProviderSpecific(a, "match-subdomain")
bMatchSubdomain := getProviderSpecific(b, "match-subdomain")
if aMatchSubdomain != bMatchSubdomain {
return false
}

aAddressList := getProviderSpecific(a, "address-list")
bAddressList := getProviderSpecific(b, "address-list")
if aAddressList != bAddressList {
return false
}

aRegexp := getProviderSpecific(a, "regexp")
bRegexp := getProviderSpecific(b, "regexp")
return aRegexp == bRegexp
}

func contains(haystack []*endpoint.Endpoint, needle *endpoint.Endpoint) bool {
for _, v := range haystack {
if isEndpointMatching(needle, v) {
return true
}
}
return false
}

func cleanupChanges(changes *plan.Changes) *plan.Changes {
// Initialize new plan -> we don't really need to worry about Create or Delete changes.
// Only updates are sketchy
newChanges := &plan.Changes{
Create: changes.Create,
Delete: changes.Delete,
UpdateOld: []*endpoint.Endpoint{},
UpdateNew: []*endpoint.Endpoint{},
}

duplicates := []*endpoint.Endpoint{}

for _, old := range changes.UpdateOld {
for _, new := range changes.UpdateNew {
if isEndpointMatching(old, new) {
duplicates = append(duplicates, old)
}
}
}

for _, old := range changes.UpdateOld {
if !contains(duplicates, old) {
newChanges.UpdateOld = append(newChanges.UpdateOld, old)
}
}
for _, new := range changes.UpdateNew {
if !contains(duplicates, new) {
newChanges.UpdateNew = append(newChanges.UpdateNew, new)
}
}

return newChanges
}
Loading

0 comments on commit a721602

Please sign in to comment.