forked from go-acme/lego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
112 lines (90 loc) · 2.31 KB
/
client.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
package sakuracloud
import (
"context"
"fmt"
"sync"
"github.com/LukasDeco/lego/v4/challenge/dns01"
"github.com/sacloud/iaas-api-go"
"github.com/sacloud/iaas-api-go/search"
)
// This mutex is required for concurrent updates.
// see: https://github.com/go-acme/lego/pull/850
var mu sync.Mutex
func (d *DNSProvider) addTXTRecord(fqdn, value string, ttl int) error {
mu.Lock()
defer mu.Unlock()
zone, err := d.getHostedZone(fqdn)
if err != nil {
return err
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Name)
if err != nil {
return err
}
records := append(zone.Records, &iaas.DNSRecord{
Name: subDomain,
Type: "TXT",
RData: value,
TTL: ttl,
})
_, err = d.client.UpdateSettings(context.Background(), zone.ID, &iaas.DNSUpdateSettingsRequest{
Records: records,
SettingsHash: zone.SettingsHash,
})
if err != nil {
return fmt.Errorf("API call failed: %w", err)
}
return nil
}
func (d *DNSProvider) cleanupTXTRecord(fqdn, value string) error {
mu.Lock()
defer mu.Unlock()
zone, err := d.getHostedZone(fqdn)
if err != nil {
return err
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Name)
if err != nil {
return err
}
var updRecords iaas.DNSRecords
for _, r := range zone.Records {
if !(r.Name == subDomain && r.Type == "TXT" && r.RData == value) {
updRecords = append(updRecords, r)
}
}
settings := &iaas.DNSUpdateSettingsRequest{
Records: updRecords,
SettingsHash: zone.SettingsHash,
}
_, err = d.client.UpdateSettings(context.Background(), zone.ID, settings)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
}
return nil
}
func (d *DNSProvider) getHostedZone(domain string) (*iaas.DNS, error) {
authZone, err := dns01.FindZoneByFqdn(domain)
if err != nil {
return nil, err
}
zoneName := dns01.UnFqdn(authZone)
conditions := &iaas.FindCondition{
Filter: search.Filter{
search.Key("Name"): search.ExactMatch(zoneName),
},
}
res, err := d.client.Find(context.Background(), conditions)
if err != nil {
if iaas.IsNotFoundError(err) {
return nil, fmt.Errorf("zone %s not found on SakuraCloud DNS: %w", zoneName, err)
}
return nil, fmt.Errorf("API call failed: %w", err)
}
for _, zone := range res.DNS {
if zone.Name == zoneName {
return zone, nil
}
}
return nil, fmt.Errorf("zone %s not found", zoneName)
}