Skip to content

Commit 78ed2ec

Browse files
authored
Merge pull request #4 from libdns/refactor-append
Cloud DNS Refactor
2 parents 9b5d2ae + 348cdc8 commit 78ed2ec

20 files changed

+3846
-1115
lines changed

client-delete.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package googleclouddns
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/libdns/libdns"
8+
"google.golang.org/api/dns/v1"
9+
)
10+
11+
// deleteCloudDNSRecord will delete the specified record set.
12+
func (p *Provider) deleteCloudDNSRecord(ctx context.Context, zone, name, recordType string, recordsToDelete, existingRecords libdnsRecords) (libdnsRecords, error) {
13+
if err := p.newService(ctx); err != nil {
14+
return nil, err
15+
}
16+
fullName := libdns.AbsoluteName(name, zone)
17+
gcdZone, err := p.getCloudDNSZone(zone)
18+
if err != nil {
19+
return nil, err
20+
}
21+
updatedRecordList := make(libdnsRecords, 0) // a list of records, if any, to keep for the Cloud DNS entry
22+
for _, record := range existingRecords {
23+
if recordsToDelete.doesNotHaveRecord(record) {
24+
updatedRecordList = append(updatedRecordList, record)
25+
continue
26+
}
27+
}
28+
if len(updatedRecordList) == 0 { // No records left with Cloud DNS entry, delete the whole thing
29+
_, err = p.service.ResourceRecordSets.Delete(p.Project, gcdZone, fullName, recordType).Context(ctx).Do()
30+
return recordsToDelete, err
31+
}
32+
// Let's patch the existing entry with the records left
33+
rrs := dns.ResourceRecordSet{
34+
Name: fullName,
35+
Rrdatas: make([]string, 0),
36+
Ttl: int64(updatedRecordList[0].TTL / time.Second),
37+
Type: recordType,
38+
}
39+
rrs.Rrdatas = updatedRecordList.prepValuesForCloudDNS()
40+
_, err = p.service.ResourceRecordSets.Patch(p.Project, gcdZone, rrs.Name, rrs.Type, &rrs).Context(ctx).Do()
41+
return recordsToDelete, err
42+
}

client-get.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package googleclouddns
2+
3+
import (
4+
"context"
5+
6+
"github.com/libdns/libdns"
7+
"google.golang.org/api/dns/v1"
8+
)
9+
10+
// getCloudDNSRecords returns all the records for the specified zone. It breaks up a single Google Record
11+
// with multiple Values into separate libdns.Records.
12+
func (p *Provider) getCloudDNSRecords(ctx context.Context, zone string) ([]libdns.Record, error) {
13+
if err := p.newService(ctx); err != nil {
14+
return nil, err
15+
}
16+
17+
gcdZone, err := p.getCloudDNSZone(zone)
18+
if err != nil {
19+
return nil, err
20+
}
21+
rrsReq := p.service.ResourceRecordSets.List(p.Project, gcdZone)
22+
records := make([]libdns.Record, 0)
23+
if err := rrsReq.Pages(ctx, func(page *dns.ResourceRecordSetsListResponse) error {
24+
for _, googleRecord := range page.Rrsets {
25+
records = append(records, convertToLibDNS(googleRecord, zone)...)
26+
}
27+
return nil
28+
}); err != nil {
29+
return nil, err
30+
}
31+
return records, nil
32+
}
33+
34+
// getCloudDNSRecord returns the record for the specified zone, name, and type. It breaks up a single Cloud DNS Record
35+
// with multiple Values into separate libdns.Records.
36+
func (p *Provider) getCloudDNSRecord(ctx context.Context, zone, name, recordType string) (libdnsRecords, error) {
37+
if err := p.newService(ctx); err != nil {
38+
return nil, err
39+
}
40+
gcdZone, err := p.getCloudDNSZone(zone)
41+
if err != nil {
42+
return nil, err
43+
}
44+
fullName := libdns.AbsoluteName(name, zone)
45+
rrs, err := p.service.ResourceRecordSets.Get(p.Project, gcdZone, fullName, recordType).Context(ctx).Do()
46+
if err != nil {
47+
return nil, err
48+
}
49+
return convertToLibDNS(rrs, zone), nil
50+
}

client-post.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package googleclouddns
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/libdns/libdns"
9+
"google.golang.org/api/dns/v1"
10+
"google.golang.org/api/googleapi"
11+
)
12+
13+
// postCloudDNSRecord will attempt to create a new Google Cloud DNS record set based on the libdns.Records or patch an existing one.
14+
func (p *Provider) postCloudDNSRecord(ctx context.Context, zone string, recordsToSend libdnsRecords) (libdnsRecords, error) {
15+
if err := p.newService(ctx); err != nil {
16+
return nil, err
17+
}
18+
gcdZone, err := p.getCloudDNSZone(zone)
19+
if err != nil {
20+
return nil, err
21+
}
22+
if len(recordsToSend) == 0 {
23+
return nil, fmt.Errorf("no records available to add to zone %s", zone)
24+
}
25+
name := recordsToSend[0].Name
26+
fullName := libdns.AbsoluteName(name, zone)
27+
rrs := dns.ResourceRecordSet{
28+
Name: fullName,
29+
Rrdatas: make([]string, 0),
30+
Ttl: int64(recordsToSend[0].TTL / time.Second),
31+
Type: recordsToSend[0].Type,
32+
}
33+
rrs.Rrdatas = recordsToSend.prepValuesForCloudDNS()
34+
googleRecord, err := p.service.ResourceRecordSets.Create(p.Project, gcdZone, &rrs).Context(ctx).Do()
35+
if err != nil {
36+
if gErr, ok := err.(*googleapi.Error); !ok || gErr.Code != 409 {
37+
return nil, err
38+
}
39+
// Record exists and we'd really like to get this libdns.Record into the zone so how about we try patching it instead...
40+
googleRecord, err = p.service.ResourceRecordSets.Patch(p.Project, gcdZone, rrs.Name, rrs.Type, &rrs).Context(ctx).Do()
41+
if err != nil {
42+
return nil, err
43+
}
44+
}
45+
return convertToLibDNS(googleRecord, zone), nil
46+
}

client.go

Lines changed: 1 addition & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import (
55
"fmt"
66
"time"
77

8-
"github.com/libdns/libdns"
98
"google.golang.org/api/dns/v1"
10-
"google.golang.org/api/googleapi"
119
"google.golang.org/api/option"
1210
)
1311

@@ -30,94 +28,10 @@ func (p *Provider) newService(ctx context.Context) error {
3028
return err
3129
}
3230

33-
// getCloudDNSRecords returns all the records for the specified zone. It breaks up a single Google Record
34-
// with multiple Values into separate libdns.Records.
35-
func (p *Provider) getCloudDNSRecords(ctx context.Context, zone string) ([]libdns.Record, error) {
36-
p.mutex.Lock()
37-
defer p.mutex.Unlock()
38-
if err := p.newService(ctx); err != nil {
39-
return nil, err
40-
}
41-
42-
gcdZone, err := p.getCloudDNSZone(zone)
43-
if err != nil {
44-
return nil, err
45-
}
46-
rrsReq := p.service.ResourceRecordSets.List(p.Project, gcdZone)
47-
records := make([]libdns.Record, 0)
48-
if err := rrsReq.Pages(ctx, func(page *dns.ResourceRecordSetsListResponse) error {
49-
for _, googleRecord := range page.Rrsets {
50-
records = append(records, convertToLibDNS(googleRecord, zone)...)
51-
}
52-
return nil
53-
}); err != nil {
54-
return nil, err
55-
}
56-
return records, nil
57-
}
58-
59-
// setCloudDNSRecord will attempt to create a new Google Cloud DNS record set based on the libdns.Records or patch an existing one if
60-
// it already exists and patch is true.
61-
func (p *Provider) setCloudDNSRecord(ctx context.Context, zone string, values []libdns.Record, patch bool) ([]libdns.Record, error) {
62-
p.mutex.Lock()
63-
defer p.mutex.Unlock()
64-
if err := p.newService(ctx); err != nil {
65-
return nil, err
66-
}
67-
68-
gcdZone, err := p.getCloudDNSZone(zone)
69-
if err != nil {
70-
return nil, err
71-
}
72-
if len(values) == 0 {
73-
return nil, fmt.Errorf("no records available to add to zone %s", zone)
74-
}
75-
name := values[0].Name
76-
fullName := libdns.AbsoluteName(name, zone)
77-
rrs := dns.ResourceRecordSet{
78-
Name: fullName,
79-
Rrdatas: make([]string, 0),
80-
Ttl: int64(values[0].TTL / time.Second),
81-
Type: values[0].Type,
82-
}
83-
for _, record := range values {
84-
rrs.Rrdatas = append(rrs.Rrdatas, record.Value)
85-
}
86-
googleRecord, err := p.service.ResourceRecordSets.Create(p.Project, gcdZone, &rrs).Context(ctx).Do()
87-
if err != nil {
88-
if gErr, ok := err.(*googleapi.Error); !ok || (gErr.Code == 409 && !patch) {
89-
return nil, err
90-
}
91-
// Record exists and we'd really like to get this libdns.Record into the zone so how about we try patching it instead...
92-
googleRecord, err = p.service.ResourceRecordSets.Patch(p.Project, gcdZone, rrs.Name, rrs.Type, &rrs).Context(ctx).Do()
93-
if err != nil {
94-
return nil, err
95-
}
96-
}
97-
return convertToLibDNS(googleRecord, zone), nil
98-
}
99-
100-
// deleteCloudDNSRecord will delete the specified record set.
101-
func (p *Provider) deleteCloudDNSRecord(ctx context.Context, zone, name, dnsType string) error {
102-
p.mutex.Lock()
103-
defer p.mutex.Unlock()
104-
if err := p.newService(ctx); err != nil {
105-
return err
106-
}
107-
108-
gcdZone, err := p.getCloudDNSZone(zone)
109-
if err != nil {
110-
return err
111-
}
112-
fullName := libdns.AbsoluteName(name, zone)
113-
_, err = p.service.ResourceRecordSets.Delete(p.Project, gcdZone, fullName, dnsType).Context(ctx).Do()
114-
return err
115-
}
116-
11731
// getCloudDNSZone will return the Google Cloud DNS zone name for the specified zone. The data is cached
11832
// for five minutes to avoid repeated calls to the GCP API servers.
11933
func (p *Provider) getCloudDNSZone(zone string) (string, error) {
120-
if p.zoneMap == nil || time.Now().Sub(p.zoneMapLastUpdated) > zoneMapTTL {
34+
if p.zoneMap == nil || time.Since(p.zoneMapLastUpdated) > zoneMapTTL {
12135
p.zoneMap = make(map[string]string)
12236
zonesLister := p.service.ManagedZones.List(p.Project)
12337
err := zonesLister.Pages(context.Background(), func(response *dns.ManagedZonesListResponse) error {
@@ -138,19 +52,3 @@ func (p *Provider) getCloudDNSZone(zone string) (string, error) {
13852
}
13953
return "", fmt.Errorf("unable to find Google managaged zone for domain %s", zone)
14054
}
141-
142-
func convertToLibDNS(googleRecord *dns.ResourceRecordSet, zone string) []libdns.Record {
143-
records := make([]libdns.Record, 0)
144-
for _, value := range googleRecord.Rrdatas {
145-
// there can be multiple values per record so
146-
// let's treat each one as a separate libdns Record
147-
record := libdns.Record{
148-
Type: googleRecord.Type,
149-
Name: libdns.RelativeName(googleRecord.Name, zone),
150-
Value: value,
151-
TTL: time.Duration(googleRecord.Ttl) * time.Second,
152-
}
153-
records = append(records, record)
154-
}
155-
return records
156-
}

0 commit comments

Comments
 (0)