diff --git a/providers/dns/ns1/ns1.go b/providers/dns/ns1/ns1.go index 40dff6c6..05397f27 100644 --- a/providers/dns/ns1/ns1.go +++ b/providers/dns/ns1/ns1.go @@ -85,7 +85,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value, _ := acme.DNS01Record(domain, keyAuth) - zone, err := d.getHostedZone(domain) + zone, err := d.getHostedZone(fqdn) if err != nil { return fmt.Errorf("ns1: %v", err) } @@ -93,7 +93,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { record := d.newTxtRecord(zone, fqdn, value, d.config.TTL) _, err = d.client.Records.Create(record) if err != nil && err != rest.ErrRecordExists { - return fmt.Errorf("ns1: %v", err) + return fmt.Errorf("ns1: failed to create record [zone: %q, fqdn: %q]: %v", zone.Zone, fqdn, err) } return nil @@ -103,14 +103,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { fqdn, _, _ := acme.DNS01Record(domain, keyAuth) - zone, err := d.getHostedZone(domain) + zone, err := d.getHostedZone(fqdn) if err != nil { return fmt.Errorf("ns1: %v", err) } name := acme.UnFqdn(fqdn) _, err = d.client.Records.Delete(zone.Zone, name, "TXT") - return fmt.Errorf("ns1: %v", err) + return fmt.Errorf("ns1: failed to delete record [zone: %q, domain: %q]: %v", zone.Zone, name, err) } // Timeout returns the timeout and interval to use when checking for DNS propagation. @@ -119,15 +119,15 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } -func (d *DNSProvider) getHostedZone(domain string) (*dns.Zone, error) { - authZone, err := getAuthZone(domain) +func (d *DNSProvider) getHostedZone(fqdn string) (*dns.Zone, error) { + authZone, err := getAuthZone(fqdn) if err != nil { - return nil, fmt.Errorf("ns1: %v", err) + return nil, fmt.Errorf("failed to extract auth zone from fqdn %q: %v", fqdn, err) } zone, _, err := d.client.Zones.Get(authZone) if err != nil { - return nil, fmt.Errorf("ns1: %v", err) + return nil, fmt.Errorf("failed to get zone [authZone: %q, fqdn: %q]: %v", authZone, fqdn, err) } return zone, nil @@ -139,11 +139,7 @@ func getAuthZone(fqdn string) (string, error) { return "", err } - if strings.HasSuffix(authZone, ".") { - authZone = authZone[:len(authZone)-len(".")] - } - - return authZone, err + return strings.TrimSuffix(authZone, "."), nil } func (d *DNSProvider) newTxtRecord(zone *dns.Zone, fqdn, value string, ttl int) *dns.Record { diff --git a/providers/dns/ns1/ns1_test.go b/providers/dns/ns1/ns1_test.go index f370e74a..cf0c2c27 100644 --- a/providers/dns/ns1/ns1_test.go +++ b/providers/dns/ns1/ns1_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -26,6 +27,57 @@ func restoreEnv() { os.Setenv("NS1_API_KEY", apiKey) } +func Test_getAuthZone(t *testing.T) { + type expected struct { + AuthZone string + Error string + } + + testCases := []struct { + desc string + fqdn string + expected expected + }{ + { + desc: "valid fqdn", + fqdn: "_acme-challenge.myhost.sub.example.com.", + expected: expected{ + AuthZone: "example.com", + }, + }, + { + desc: "invalid fqdn", + fqdn: "_acme-challenge.myhost.sub.example.com", + expected: expected{ + Error: "dns: domain must be fully qualified", + }, + }, + { + desc: "invalid authority", + fqdn: "_acme-challenge.myhost.sub.domain.tld.", + expected: expected{ + Error: "could not find the start of authority", + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + authZone, err := getAuthZone(test.fqdn) + + if len(test.expected.Error) > 0 { + assert.EqualError(t, err, test.expected.Error) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected.AuthZone, authZone) + } + }) + } +} + func TestNewDNSProviderValid(t *testing.T) { defer restoreEnv() os.Setenv("NS1_API_KEY", "")