From 21f6cd8a12bc16bb5b3dd4f513ebc4896121ed7f Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Tue, 9 Oct 2018 18:51:49 +0200 Subject: [PATCH] dnsimple: fix challenge. (#666) --- providers/dns/dnsimple/dnsimple.go | 27 ++-- providers/dns/dnsimple/dnsimple_test.go | 173 +++++++++++++++--------- 2 files changed, 121 insertions(+), 79 deletions(-) diff --git a/providers/dns/dnsimple/dnsimple.go b/providers/dns/dnsimple/dnsimple.go index 3b40dc5e..8f52cac6 100644 --- a/providers/dns/dnsimple/dnsimple.go +++ b/providers/dns/dnsimple/dnsimple.go @@ -78,7 +78,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { client.BaseURL = config.BaseURL } - return &DNSProvider{client: client}, nil + return &DNSProvider{client: client, config: config}, nil } // Present creates a TXT record to fulfill the dns-01 challenge. @@ -87,18 +87,18 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { zoneName, err := d.getHostedZone(domain) if err != nil { - return err + return fmt.Errorf("dnsimple: %v", err) } accountID, err := d.getAccountID() if err != nil { - return err + return fmt.Errorf("dnsimple: %v", err) } - recordAttributes := d.newTxtRecord(zoneName, fqdn, value, d.config.TTL) + recordAttributes := newTxtRecord(zoneName, fqdn, value, d.config.TTL) _, err = d.client.Zones.CreateRecord(accountID, zoneName, recordAttributes) if err != nil { - return fmt.Errorf("API call failed: %v", err) + return fmt.Errorf("dnsimple: API call failed: %v", err) } return nil @@ -110,22 +110,23 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { records, err := d.findTxtRecords(domain, fqdn) if err != nil { - return err + return fmt.Errorf("dnsimple: %v", err) } accountID, err := d.getAccountID() if err != nil { - return err + return fmt.Errorf("dnsimple: %v", err) } + var lastErr error for _, rec := range records { _, err := d.client.Zones.DeleteRecord(accountID, rec.ZoneID, rec.ID) if err != nil { - return err + lastErr = fmt.Errorf("dnsimple: %v", err) } } - return nil + return lastErr } // Timeout returns the timeout and interval to use when checking for DNS propagation. @@ -177,7 +178,7 @@ func (d *DNSProvider) findTxtRecords(domain, fqdn string) ([]dnsimple.ZoneRecord return nil, err } - recordName := d.extractRecordName(fqdn, zoneName) + recordName := extractRecordName(fqdn, zoneName) result, err := d.client.Zones.ListRecords(accountID, zoneName, &dnsimple.ZoneRecordListOptions{Name: recordName, Type: "TXT", ListOptions: dnsimple.ListOptions{}}) if err != nil { @@ -187,8 +188,8 @@ func (d *DNSProvider) findTxtRecords(domain, fqdn string) ([]dnsimple.ZoneRecord return result.Data, nil } -func (d *DNSProvider) newTxtRecord(zoneName, fqdn, value string, ttl int) dnsimple.ZoneRecord { - name := d.extractRecordName(fqdn, zoneName) +func newTxtRecord(zoneName, fqdn, value string, ttl int) dnsimple.ZoneRecord { + name := extractRecordName(fqdn, zoneName) return dnsimple.ZoneRecord{ Type: "TXT", @@ -198,7 +199,7 @@ func (d *DNSProvider) newTxtRecord(zoneName, fqdn, value string, ttl int) dnsimp } } -func (d *DNSProvider) extractRecordName(fqdn, domain string) string { +func extractRecordName(fqdn, domain string) string { name := acme.UnFqdn(fqdn) if idx := strings.Index(name, "."+domain); idx != -1 { return name[:idx] diff --git a/providers/dns/dnsimple/dnsimple_test.go b/providers/dns/dnsimple/dnsimple_test.go index c3780c0c..652a1832 100644 --- a/providers/dns/dnsimple/dnsimple_test.go +++ b/providers/dns/dnsimple/dnsimple_test.go @@ -38,84 +38,125 @@ func restoreEnv() { os.Setenv("DNSIMPLE_BASE_URL", dnsimpleBaseURL) } -// -// NewDNSProvider -// +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + userAgent string + envVars map[string]string + expected string + }{ + { + desc: "success", + userAgent: "lego", + envVars: map[string]string{ + "DNSIMPLE_OAUTH_TOKEN": "my_token", + }, + }, + { + desc: "success: base url", + envVars: map[string]string{ + "DNSIMPLE_OAUTH_TOKEN": "my_token", + "DNSIMPLE_BASE_URL": "https://api.dnsimple.test", + }, + }, + { + desc: "missing oauth token", + envVars: map[string]string{ + "DNSIMPLE_OAUTH_TOKEN": "", + }, + expected: "dnsimple: OAuth token is missing", + }, + } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("DNSIMPLE_OAUTH_TOKEN", "123") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + for key, value := range test.envVars { + if len(value) == 0 { + os.Unsetenv(key) + } else { + os.Setenv(key, value) + } + } - acme.UserAgent = "lego" + if test.userAgent != "" { + acme.UserAgent = test.userAgent + } - provider, err := NewDNSProvider() + p, err := NewDNSProvider() - assert.NotNil(t, provider) - assert.Equal(t, "lego", provider.client.UserAgent) - assert.NoError(t, err) + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + + baseURL := os.Getenv("DNSIMPLE_BASE_URL") + if baseURL != "" { + assert.Equal(t, baseURL, p.client.BaseURL) + } + + if test.userAgent != "" { + assert.Equal(t, "lego", p.client.UserAgent) + } + + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidWithBaseUrl(t *testing.T) { - defer restoreEnv() - os.Setenv("DNSIMPLE_OAUTH_TOKEN", "123") - os.Setenv("DNSIMPLE_BASE_URL", "https://api.dnsimple.test") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + accessToken string + baseURL string + expected string + }{ + { + desc: "success", + accessToken: "my_token", + baseURL: "", + }, + { + desc: "success: base url", + accessToken: "my_token", + baseURL: "https://api.dnsimple.test", + }, + { + desc: "missing oauth token", + expected: "dnsimple: OAuth token is missing", + }, + } - provider, err := NewDNSProvider() + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("DNSIMPLE_OAUTH_TOKEN") + os.Unsetenv("DNSIMPLE_BASE_URL") - assert.NotNil(t, provider) - assert.NoError(t, err) + config := NewDefaultConfig() + config.AccessToken = test.accessToken + config.BaseURL = test.baseURL - assert.Equal(t, provider.client.BaseURL, "https://api.dnsimple.test") -} + p, err := NewDNSProviderConfig(config) -func TestNewDNSProviderInvalidWithMissingOauthToken(t *testing.T) { - defer restoreEnv() - os.Setenv("DNSIMPLE_OAUTH_TOKEN", "") + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) - provider, err := NewDNSProvider() + if test.baseURL != "" { + assert.Equal(t, test.baseURL, p.client.BaseURL) + } - assert.Nil(t, provider) - assert.EqualError(t, err, "dnsimple: OAuth token is missing") -} - -// -// NewDNSProviderCredentials -// - -func TestNewDNSProviderCredentialsValid(t *testing.T) { - config := NewDefaultConfig() - config.AccessToken = "123" - config.BaseURL = "" - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - require.NotNil(t, provider) - - assert.Equal(t, "lego", provider.client.UserAgent) - assert.NoError(t, err) -} - -func TestNewDNSProviderCredentialsValidWithBaseUrl(t *testing.T) { - config := NewDefaultConfig() - config.AccessToken = "123" - config.BaseURL = "https://api.dnsimple.test" - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - require.NotNil(t, provider) - - assert.Equal(t, provider.client.BaseURL, "https://api.dnsimple.test") -} - -func TestNewDNSProviderCredentialsInvalidWithMissingOauthToken(t *testing.T) { - config := NewDefaultConfig() - config.AccessToken = "" - config.BaseURL = "" - - provider, err := NewDNSProviderConfig(config) - - assert.Nil(t, provider) - assert.EqualError(t, err, "dnsimple: OAuth token is missing") + } else { + require.EqualError(t, err, test.expected) + } + }) + } } //