-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprovider.go
129 lines (101 loc) · 3.5 KB
/
provider.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package katapult
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/libdns/libdns"
)
// Provider facilitates DNS record manipulation with Katapult.
type Provider struct {
APIToken string `json:"api_token,omitempty"`
}
var errFailedToDeleteRecord = errors.New("failed to delete record")
// GetRecords lists all the records in the zone.
func (p *Provider) GetRecords(ctx context.Context, zone string) ([]libdns.Record, error) {
url := "/dns_zones/_/records?dns_zone[name]=" + RemoveTrailingDot(zone)
var apiResponse DNSRecordsAPIResponse
if err := p.DoRequest(ctx, http.MethodGet, url, nil, &apiResponse); err != nil {
return nil, err
}
var records []libdns.Record
for _, record := range apiResponse.DNSRecords {
records = append(records, p.ToLibDNSRecord(record))
}
return records, nil
}
// AppendRecords adds records to the zone. It returns the records that were added.
func (p *Provider) AppendRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error) {
var addedRecords []libdns.Record
url := "/dns_zones/_/records"
for _, record := range records {
properties, err := p.FromLibDNSRecord(record)
if err != nil {
return addedRecords, err
}
requestBody := map[string]interface{}{
"dns_zone": map[string]string{"name": RemoveTrailingDot(zone)},
"properties": properties,
}
var apiResponse DNSRecordAPIResponse
if err := p.DoRequest(ctx, http.MethodPost, url, requestBody, &apiResponse); err != nil {
return addedRecords, err
}
addedRecords = append(addedRecords, p.ToLibDNSRecord(apiResponse.DNSRecord))
}
return addedRecords, nil
}
// SetRecords sets the records in the zone, either by updating existing records or creating new ones.
// It returns the updated records.
func (p *Provider) SetRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error) {
var updatedRecords []libdns.Record
for _, record := range records {
var url string
var method string
if record.ID == "" {
url = "/dns_zones/_/records"
method = http.MethodPost
} else {
url = "/dns_records/" + record.ID
method = http.MethodPatch
}
properties, err := p.FromLibDNSRecord(record)
if err != nil {
return updatedRecords, err
}
requestBody := map[string]interface{}{
"dns_zone": map[string]string{"name": RemoveTrailingDot(zone)},
"properties": properties,
}
var apiResponse DNSRecordAPIResponse
if err := p.DoRequest(ctx, method, url, requestBody, &apiResponse); err != nil {
return updatedRecords, err
}
updatedRecords = append(updatedRecords, p.ToLibDNSRecord(apiResponse.DNSRecord))
}
return updatedRecords, nil
}
// DeleteRecords deletes the records from the zone. It returns the records that were deleted.
func (p *Provider) DeleteRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error) {
var deletedRecords []libdns.Record
for _, record := range records {
url := "/dns_records/" + record.ID
var apiResponse DeletionAPIResponse
if err := p.DoRequest(ctx, http.MethodDelete, url, nil, &apiResponse); err != nil {
return deletedRecords, err
}
if apiResponse.Deleted {
deletedRecords = append(deletedRecords, record)
} else {
return deletedRecords, fmt.Errorf("%w: %s", errFailedToDeleteRecord, record.ID)
}
}
return deletedRecords, nil
}
// Interface guards
var (
_ libdns.RecordGetter = (*Provider)(nil)
_ libdns.RecordAppender = (*Provider)(nil)
_ libdns.RecordSetter = (*Provider)(nil)
_ libdns.RecordDeleter = (*Provider)(nil)
)