Skip to content

Commit

Permalink
Bug 1898417 - GCP: the dns targets in Google Cloud DNS is not updated…
Browse files Browse the repository at this point in the history
… after recreating loadbalancer service
  • Loading branch information
miheer committed Dec 15, 2020
1 parent b554813 commit 32d3c02
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 6 deletions.
4 changes: 4 additions & 0 deletions pkg/dns/aws/dns.go
Expand Up @@ -361,6 +361,10 @@ func (m *Provider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
return m.change(record, zone, deleteAction)
}

func (m *Provider) Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error {
return m.change(record, zone, upsertAction)
}

// change will perform an action on a record. The target must correspond to the
// hostname of an ELB which will be automatically discovered.
func (m *Provider) change(record *iov1.DNSRecord, zone configv1.DNSZone, action action) error {
Expand Down
4 changes: 4 additions & 0 deletions pkg/dns/azure/dns.go
Expand Up @@ -125,6 +125,10 @@ func (m *provider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
return err
}

func (m *provider) Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error {
return m.Ensure(record, zone)
}

// getARecordName extracts the ARecord subdomain name from the full domain string.
// azure defines the ARecord Name as the subdomain name only.
func getARecordName(recordDomain string, zoneName string) (string, error) {
Expand Down
8 changes: 6 additions & 2 deletions pkg/dns/dns.go
Expand Up @@ -13,11 +13,15 @@ type Provider interface {

// Delete will delete record.
Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error

//Replace will replace the record
Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error
}

var _ Provider = &FakeProvider{}

type FakeProvider struct{}

func (_ *FakeProvider) Ensure(record *iov1.DNSRecord, zone configv1.DNSZone) error { return nil }
func (_ *FakeProvider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error { return nil }
func (_ *FakeProvider) Ensure(record *iov1.DNSRecord, zone configv1.DNSZone) error { return nil }
func (_ *FakeProvider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error { return nil }
func (_ *FakeProvider) Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error { return nil }
25 changes: 25 additions & 0 deletions pkg/dns/gcp/provider.go
Expand Up @@ -2,6 +2,8 @@ package gcp

import (
"context"
"fmt"
"log"
"net/http"

"google.golang.org/api/googleapi"
Expand Down Expand Up @@ -57,6 +59,29 @@ func (p *Provider) Ensure(record *iov1.DNSRecord, zone configv1.DNSZone) error {
return err
}

func (p *Provider) Replace(record *iov1.DNSRecord, zone configv1.DNSZone) error {
ctx := context.Background()
oldRecord := p.dnsService.ResourceRecordSets.List(p.config.Project, zone.ID).Name(record.Name)
if err := oldRecord.Pages(ctx, func(page *gdnsv1.ResourceRecordSetsListResponse) error {
for _, resourceRecordSet := range page.Rrsets {
log.Println(fmt.Printf("%#v\n", resourceRecordSet))
change := &gdnsv1.Change{Deletions: []*gdnsv1.ResourceRecordSet{resourceRecordSet}}
call := p.dnsService.Changes.Create(p.config.Project, zone.ID, change)
_, err := call.Do()
if ae, ok := err.(*googleapi.Error); ok && ae.Code == http.StatusNotFound {
return nil
}
}
return nil
}); err != nil {
log.Fatal(err)
}
if err := p.Ensure(record, zone); err != nil {
return err
}
return nil
}

func (p *Provider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
change := &gdnsv1.Change{Deletions: []*gdnsv1.ResourceRecordSet{resourceRecordSet(record)}}
call := p.dnsService.Changes.Create(p.config.Project, zone.ID, change)
Expand Down
25 changes: 21 additions & 4 deletions pkg/operator/controller/dns/controller.go
Expand Up @@ -251,17 +251,34 @@ func (r *reconciler) publishRecordToZones(zones []configv1.DNSZone, record *iov1
// Only publish the record if the DNSRecord has been modified
// (which would mean the target could have changed) or its
// status does not indicate that it has already been published.
if record.Generation == record.Status.ObservedGeneration && recordIsAlreadyPublishedToZone(record, &zone) {
log.Info("skipping zone to which the DNS record is already published", "record", record.Spec, "dnszone", zone)
continue
}

condition := iov1.DNSZoneCondition{
Status: string(operatorv1.ConditionUnknown),
Type: iov1.DNSRecordFailedConditionType,
LastTransitionTime: metav1.Now(),
}

if record.Generation != record.Status.ObservedGeneration && recordIsAlreadyPublishedToZone(record, &zone) {
log.Info("replacing DNS record", "record", record.Spec, "dnszone", zone)

if err := r.dnsProvider.Replace(record, zone); err != nil {
log.Error(err, "failed to replace DNS record to zone", "record", record.Spec, "dnszone", zone)
condition.Status = string(operatorv1.ConditionTrue)
condition.Reason = "ProviderError"
condition.Message = fmt.Sprintf("The DNS provider failed to replace the record: %v", err)
result.RequeueAfter = 30 * time.Second
} else {
log.Info("replaced DNS record to zone", "record", record.Spec, "dnszone", zone)
condition.Status = string(operatorv1.ConditionFalse)
condition.Reason = "ProviderSuccess"
condition.Message = "The DNS provider succeeded in replacing the record"
}

} else if record.Generation == record.Status.ObservedGeneration && recordIsAlreadyPublishedToZone(record, &zone) {
log.Info("skipping zone to which the DNS record is already published", "record", record.Spec, "dnszone", zone)
continue
}

if err := r.dnsProvider.Ensure(record, zone); err != nil {
log.Error(err, "failed to publish DNS record to zone", "record", record.Spec, "dnszone", zone)
condition.Status = string(operatorv1.ConditionTrue)
Expand Down

0 comments on commit 32d3c02

Please sign in to comment.