22package civo
33
44import (
5+ "context"
56 "errors"
67 "fmt"
8+ "net/http"
79 "time"
810
9- "github.com/civo/civogo"
1011 "github.com/go-acme/lego/v4/challenge"
1112 "github.com/go-acme/lego/v4/challenge/dns01"
1213 "github.com/go-acme/lego/v4/platform/config/env"
14+ "github.com/go-acme/lego/v4/providers/dns/civo/internal"
1315)
1416
1517// Environment variables names.
@@ -21,6 +23,7 @@ const (
2123 EnvTTL = envNamespace + "TTL"
2224 EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
2325 EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
26+ EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
2427)
2528
2629const (
@@ -33,11 +36,12 @@ var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
3336
3437// Config is used to configure the creation of the DNSProvider.
3538type Config struct {
36- ProjectID string
37- Token string
39+ Token string
40+
3841 PropagationTimeout time.Duration
3942 PollingInterval time.Duration
4043 TTL int
44+ HTTPClient * http.Client
4145}
4246
4347// NewDefaultConfig returns a default configuration for the DNSProvider.
@@ -46,13 +50,16 @@ func NewDefaultConfig() *Config {
4650 TTL : env .GetOrDefaultInt (EnvTTL , minTTL ),
4751 PropagationTimeout : env .GetOrDefaultSecond (EnvPropagationTimeout , defaultPropagationTimeout ),
4852 PollingInterval : env .GetOrDefaultSecond (EnvPollingInterval , defaultPollingInterval ),
53+ HTTPClient : & http.Client {
54+ Timeout : env .GetOrDefaultSecond (EnvHTTPTimeout , 30 * time .Second ),
55+ },
4956 }
5057}
5158
5259// DNSProvider implements the challenge.Provider interface.
5360type DNSProvider struct {
5461 config * Config
55- client * civogo .Client
62+ client * internal .Client
5663}
5764
5865// NewDNSProvider returns a DNSProvider instance configured for CIVO.
@@ -84,7 +91,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
8491 }
8592
8693 // Create a Civo client - DNS is region independent, we can use any region
87- client , err := civogo .NewClient (config .Token , "LON1" )
94+ client , err := internal .NewClient (internal . OAuthStaticAccessToken ( config .HTTPClient , config . Token ) , "LON1" )
8895 if err != nil {
8996 return nil , fmt .Errorf ("civo: %w" , err )
9097 }
@@ -96,14 +103,16 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
96103func (d * DNSProvider ) Present (domain , token , keyAuth string ) error {
97104 info := dns01 .GetChallengeInfo (domain , keyAuth )
98105
106+ ctx := context .Background ()
107+
99108 authZone , err := dns01 .FindZoneByFqdn (info .EffectiveFQDN )
100109 if err != nil {
101110 return fmt .Errorf ("civo: could not find zone for domain %q: %w" , domain , err )
102111 }
103112
104113 zone := dns01 .UnFqdn (authZone )
105114
106- dnsDomain , err := d .client . GetDNSDomain ( zone )
115+ domainID , err := d .getDomainIDByName ( ctx , zone )
107116 if err != nil {
108117 return fmt .Errorf ("civo: %w" , err )
109118 }
@@ -113,10 +122,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
113122 return fmt .Errorf ("civo: %w" , err )
114123 }
115124
116- _ , err = d .client .CreateDNSRecord (dnsDomain . ID , & civogo. DNSRecordConfig {
125+ _ , err = d .client .CreateDNSRecord (ctx , domainID , internal. Record {
117126 Name : subDomain ,
118127 Value : info .Value ,
119- Type : civogo . DNSRecordTypeTXT ,
128+ Type : "TXT" ,
120129 TTL : d .config .TTL ,
121130 })
122131 if err != nil {
@@ -130,19 +139,21 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
130139func (d * DNSProvider ) CleanUp (domain , token , keyAuth string ) error {
131140 info := dns01 .GetChallengeInfo (domain , keyAuth )
132141
142+ ctx := context .Background ()
143+
133144 authZone , err := dns01 .FindZoneByFqdn (info .EffectiveFQDN )
134145 if err != nil {
135146 return fmt .Errorf ("civo: could not find zone for domain %q: %w" , domain , err )
136147 }
137148
138149 zone := dns01 .UnFqdn (authZone )
139150
140- dnsDomain , err := d .client . GetDNSDomain ( zone )
151+ domainID , err := d .getDomainIDByName ( ctx , zone )
141152 if err != nil {
142153 return fmt .Errorf ("civo: %w" , err )
143154 }
144155
145- dnsRecords , err := d .client .ListDNSRecords (dnsDomain . ID )
156+ dnsRecords , err := d .client .ListDNSRecords (ctx , domainID )
146157 if err != nil {
147158 return fmt .Errorf ("civo: %w" , err )
148159 }
@@ -152,15 +163,15 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
152163 return fmt .Errorf ("civo: %w" , err )
153164 }
154165
155- var dnsRecord civogo. DNSRecord
166+ var dnsRecord internal. Record
156167 for _ , entry := range dnsRecords {
157168 if entry .Name == subDomain && entry .Value == info .Value {
158169 dnsRecord = entry
159170 break
160171 }
161172 }
162173
163- _ , err = d .client .DeleteDNSRecord (& dnsRecord )
174+ err = d .client .DeleteDNSRecord (ctx , dnsRecord )
164175 if err != nil {
165176 return fmt .Errorf ("civo: %w" , err )
166177 }
@@ -173,3 +184,18 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
173184func (d * DNSProvider ) Timeout () (timeout , interval time.Duration ) {
174185 return d .config .PropagationTimeout , d .config .PollingInterval
175186}
187+
188+ func (d * DNSProvider ) getDomainIDByName (ctx context.Context , domain string ) (string , error ) {
189+ domains , err := d .client .ListDomains (ctx )
190+ if err != nil {
191+ return "" , fmt .Errorf ("list domains: %w" , err )
192+ }
193+
194+ for _ , d := range domains {
195+ if d .Name == domain {
196+ return d .ID , nil
197+ }
198+ }
199+
200+ return "" , fmt .Errorf ("domain %q not found" , domain )
201+ }
0 commit comments