diff --git a/acme/challenges.go b/acme/challenges.go index 1140b107..d10f82b8 100644 --- a/acme/challenges.go +++ b/acme/challenges.go @@ -7,9 +7,11 @@ const ( // HTTP01 is the "http-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http // Note: HTTP01ChallengePath returns the URL path to fulfill this challenge HTTP01 = Challenge("http-01") + // DNS01 is the "dns-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#dns // Note: DNS01Record returns a DNS record which will fulfill this challenge DNS01 = Challenge("dns-01") + // TLSALPN01 is the "tls-alpn-01" ACME challenge https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01 TLSALPN01 = Challenge("tls-alpn-01") ) diff --git a/acme/client.go b/acme/client.go index 7af45033..4908d592 100644 --- a/acme/client.go +++ b/acme/client.go @@ -412,7 +412,7 @@ DNSNames: // the whole certificate will fail. func (c *Client) ObtainCertificate(domains []string, bundle bool, privKey crypto.PrivateKey, mustStaple bool) (*CertificateResource, error) { if len(domains) == 0 { - return nil, errors.New("No domains to obtain a certificate for") + return nil, errors.New("no domains to obtain a certificate for") } if bundle { diff --git a/acme/client_test.go b/acme/client_test.go index b18047a0..e14444ee 100644 --- a/acme/client_test.go +++ b/acme/client_test.go @@ -217,7 +217,7 @@ func TestValidate(t *testing.T) { err := validate(j, "example.com", ts.URL, challenge{Type: "http-01", Token: "token"}) if test.want == "" { - assert.NoError(t, err) + require.NoError(t, err) } else { assert.Error(t, err) assert.Contains(t, err.Error(), test.want) @@ -262,7 +262,7 @@ func TestGetChallenges(t *testing.T) { require.NoError(t, err, "Could not create client") _, err = client.createOrderForIdentifiers([]string{"example.com"}) - assert.NoError(t, err) + require.NoError(t, err) } func TestResolveAccountByKey(t *testing.T) { diff --git a/acme/http_challenge_test.go b/acme/http_challenge_test.go index ba0e8bf7..17c4a4e7 100644 --- a/acme/http_challenge_test.go +++ b/acme/http_challenge_test.go @@ -48,7 +48,7 @@ func TestHTTPChallenge(t *testing.T) { clientChallenge := challenge{Type: string(HTTP01), Token: "http1"} err = solver.Solve(clientChallenge, "localhost:23457") - assert.NoError(t, err) + require.NoError(t, err) } func TestHTTPChallengeInvalidPort(t *testing.T) { diff --git a/acme/tls_alpn_challenge_test.go b/acme/tls_alpn_challenge_test.go index 4b090177..b8426593 100644 --- a/acme/tls_alpn_challenge_test.go +++ b/acme/tls_alpn_challenge_test.go @@ -20,7 +20,7 @@ func TestTLSALPNChallenge(t *testing.T) { conn, err := tls.Dial("tcp", domain, &tls.Config{ InsecureSkipVerify: true, }) - assert.NoError(t, err, "Expected to connect to challenge server without an error") + require.NoError(t, err, "Expected to connect to challenge server without an error") // Expect the server to only return one certificate connState := conn.ConnectionState() @@ -67,7 +67,7 @@ func TestTLSALPNChallenge(t *testing.T) { clientChallenge := challenge{Type: string(TLSALPN01), Token: "tlsalpn1"} err = solver.Solve(clientChallenge, domain) - assert.NoError(t, err) + require.NoError(t, err) } func TestTLSALPNChallengeInvalidPort(t *testing.T) { diff --git a/cli.go b/cli.go index 102bb5a4..9f57e825 100644 --- a/cli.go +++ b/cli.go @@ -87,7 +87,7 @@ func main() { { Name: "dnshelp", Usage: "Shows additional help for the --dns global option", - Action: dnshelp, + Action: dnsHelp, }, } @@ -187,7 +187,7 @@ func main() { } } -func dnshelp(c *cli.Context) error { +func dnsHelp(_ *cli.Context) error { fmt.Printf( `Credentials for DNS providers must be passed through environment variables. diff --git a/providers/dns/alidns/alidns_test.go b/providers/dns/alidns/alidns_test.go index ee4f6233..d809cdbf 100644 --- a/providers/dns/alidns/alidns_test.go +++ b/providers/dns/alidns/alidns_test.go @@ -5,91 +5,171 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - alidnsLiveTest bool - alidnsAPIKey string - alidnsSecretKey string - alidnsDomain string + liveTest bool + envTestAPIKey string + envTestSecretKey string + envTestDomain string ) func init() { - alidnsAPIKey = os.Getenv("ALICLOUD_ACCESS_KEY") - alidnsSecretKey = os.Getenv("ALICLOUD_SECRET_KEY") - alidnsDomain = os.Getenv("ALIDNS_DOMAIN") + envTestAPIKey = os.Getenv("ALICLOUD_ACCESS_KEY") + envTestSecretKey = os.Getenv("ALICLOUD_SECRET_KEY") + envTestDomain = os.Getenv("ALIDNS_DOMAIN") - if len(alidnsAPIKey) > 0 && len(alidnsSecretKey) > 0 && len(alidnsDomain) > 0 { - alidnsLiveTest = true + if len(envTestAPIKey) > 0 && len(envTestSecretKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("ALICLOUD_ACCESS_KEY", alidnsAPIKey) - os.Setenv("ALICLOUD_SECRET_KEY", alidnsSecretKey) + os.Setenv("ALICLOUD_ACCESS_KEY", envTestAPIKey) + os.Setenv("ALICLOUD_SECRET_KEY", envTestSecretKey) } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("ALICLOUD_ACCESS_KEY", "") - os.Setenv("ALICLOUD_SECRET_KEY", "") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "ALICLOUD_ACCESS_KEY": "123", + "ALICLOUD_SECRET_KEY": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "ALICLOUD_ACCESS_KEY": "", + "ALICLOUD_SECRET_KEY": "", + }, + expected: "alicloud: some credentials information are missing: ALICLOUD_ACCESS_KEY,ALICLOUD_SECRET_KEY", + }, + { + desc: "missing access key", + envVars: map[string]string{ + "ALICLOUD_ACCESS_KEY": "", + "ALICLOUD_SECRET_KEY": "456", + }, + expected: "alicloud: some credentials information are missing: ALICLOUD_ACCESS_KEY", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "ALICLOUD_ACCESS_KEY": "123", + "ALICLOUD_SECRET_KEY": "", + }, + expected: "alicloud: some credentials information are missing: ALICLOUD_SECRET_KEY", + }, + } - config := NewDefaultConfig() - config.APIKey = "123" - config.SecretKey = "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) + } + } - _, err := NewDNSProviderConfig(config) - assert.NoError(t, err) + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("ALICLOUD_ACCESS_KEY", "123") - os.Setenv("ALICLOUD_SECRET_KEY", "123") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + secretKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + secretKey: "456", + }, + { + desc: "missing credentials", + expected: "alicloud: credentials missing", + }, + { + desc: "missing api key", + secretKey: "456", + expected: "alicloud: credentials missing", + }, + { + desc: "missing secret key", + apiKey: "123", + expected: "alicloud: credentials missing", + }, + } - _, err := NewDNSProvider() - assert.NoError(t, err) + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("ALICLOUD_ACCESS_KEY") + os.Unsetenv("ALICLOUD_SECRET_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.SecretKey = test.secretKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("ALICLOUD_ACCESS_KEY", "") - os.Setenv("ALICLOUD_SECRET_KEY", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "alicloud: some credentials information are missing: ALICLOUD_ACCESS_KEY,ALICLOUD_SECRET_KEY") -} - -func TestCloudXNSPresent(t *testing.T) { - if !alidnsLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.APIKey = alidnsAPIKey - config.SecretKey = alidnsSecretKey + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - - err = provider.Present(alidnsDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestLivednspodCleanUp(t *testing.T) { - if !alidnsLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - config := NewDefaultConfig() - config.APIKey = alidnsAPIKey - config.SecretKey = alidnsSecretKey + time.Sleep(1 * time.Second) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - err = provider.CleanUp(alidnsDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/auroradns/auroradns_test.go b/providers/dns/auroradns/auroradns_test.go index 81ce3740..1d9c8152 100644 --- a/providers/dns/auroradns/auroradns_test.go +++ b/providers/dns/auroradns/auroradns_test.go @@ -5,36 +5,185 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -var fakeAuroraDNSUserID = "asdf1234" -var fakeAuroraDNSKey = "key" +var ( + envTestUserID string + envTestKey string +) -func TestAuroraDNSPresent(t *testing.T) { - var requestReceived bool +func init() { + envTestUserID = os.Getenv("AURORA_USER_ID") + envTestKey = os.Getenv("AURORA_KEY") +} - mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodGet && r.URL.Path == "/zones" { - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `[{ +func restoreEnv() { + os.Setenv("AURORA_USER_ID", envTestUserID) + os.Setenv("AURORA_KEY", envTestKey) +} + +func setupTest() (*DNSProvider, *http.ServeMux, func()) { + handler := http.NewServeMux() + server := httptest.NewServer(handler) + + config := NewDefaultConfig() + config.UserID = "asdf1234" + config.Key = "key" + config.BaseURL = server.URL + + provider, err := NewDNSProviderConfig(config) + if err != nil { + panic(err) + } + + return provider, handler, server.Close +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "AURORA_USER_ID": "123", + "AURORA_KEY": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "AURORA_USER_ID": "", + "AURORA_KEY": "", + }, + expected: "aurora: some credentials information are missing: AURORA_USER_ID,AURORA_KEY", + }, + { + desc: "missing user id", + envVars: map[string]string{ + "AURORA_USER_ID": "", + "AURORA_KEY": "456", + }, + expected: "aurora: some credentials information are missing: AURORA_USER_ID", + }, + { + desc: "missing key", + envVars: map[string]string{ + "AURORA_USER_ID": "123", + "AURORA_KEY": "", + }, + expected: "aurora: some credentials information are missing: AURORA_KEY", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + userID string + key string + expected string + }{ + { + desc: "success", + userID: "123", + key: "456", + }, + { + desc: "missing credentials", + userID: "", + key: "", + expected: "aurora: some credentials information are missing", + }, + { + desc: "missing user id", + userID: "", + key: "456", + expected: "aurora: some credentials information are missing", + }, + { + desc: "missing key", + userID: "123", + key: "", + expected: "aurora: some credentials information are missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("AURORA_USER_ID") + os.Unsetenv("AURORA_KEY") + + config := NewDefaultConfig() + config.UserID = test.userID + config.Key = test.key + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestDNSProvider_Present(t *testing.T) { + provider, mux, tearDown := setupTest() + defer tearDown() + + mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method, "method") + + w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, `[{ "id": "c56a4180-65aa-42ec-a945-5fd21dec0538", "name": "example.com" }]`) - return - } + }) - requestReceived = true - - assert.Equal(t, http.MethodPost, r.Method, "method") - assert.Equal(t, "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records", r.URL.Path, "Path") + mux.HandleFunc("/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPost, r.Method) assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type") reqBody, err := ioutil.ReadAll(r.Body) - require.NoError(t, err, "reading request body") + require.NoError(t, err) assert.Equal(t, `{"type":"TXT","name":"_acme-challenge","content":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI","ttl":300}`, string(reqBody)) w.WriteHeader(http.StatusCreated) @@ -44,74 +193,50 @@ func TestAuroraDNSPresent(t *testing.T) { "name": "_acme-challenge", "ttl": 300 }`) - })) + }) - defer mock.Close() - - config := NewDefaultConfig() - config.UserID = fakeAuroraDNSUserID - config.Key = fakeAuroraDNSKey - config.BaseURL = mock.URL - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - require.NotNil(t, provider) - - err = provider.Present("example.com", "", "foobar") + err := provider.Present("example.com", "", "foobar") require.NoError(t, err, "fail to create TXT record") - - assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't") } -func TestAuroraDNSCleanUp(t *testing.T) { - var requestReceived bool +func TestDNSProvider_CleanUp(t *testing.T) { + provider, mux, tearDown := setupTest() + defer tearDown() - mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodGet && r.URL.Path == "/zones" { - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `[{ + mux.HandleFunc("/zones", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method) + + w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, `[{ "id": "c56a4180-65aa-42ec-a945-5fd21dec0538", "name": "example.com" }]`) - return - } + }) - if r.Method == http.MethodPost && r.URL.Path == "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records" { - w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ + mux.HandleFunc("/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPost, r.Method) + + w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, `{ "id": "ec56a4180-65aa-42ec-a945-5fd21dec0538", "type": "TXT", "name": "_acme-challenge", "ttl": 300 }`) - return - } + }) - requestReceived = true + mux.HandleFunc("/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records/ec56a4180-65aa-42ec-a945-5fd21dec0538", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodDelete, r.Method) - assert.Equal(t, http.MethodDelete, r.Method, "method") - assert.Equal(t, "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records/ec56a4180-65aa-42ec-a945-5fd21dec0538", r.URL.Path, "Path") assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type") w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{}`) - })) - defer mock.Close() + }) - config := NewDefaultConfig() - config.UserID = fakeAuroraDNSUserID - config.Key = fakeAuroraDNSKey - config.BaseURL = mock.URL - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - require.NotNil(t, provider) - - err = provider.Present("example.com", "", "foobar") + err := provider.Present("example.com", "", "foobar") require.NoError(t, err, "fail to create TXT record") err = provider.CleanUp("example.com", "", "foobar") require.NoError(t, err, "fail to remove TXT record") - - assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't") } diff --git a/providers/dns/azure/azure_test.go b/providers/dns/azure/azure_test.go index 85dc14c9..1019ecc2 100644 --- a/providers/dns/azure/azure_test.go +++ b/providers/dns/azure/azure_test.go @@ -5,112 +5,270 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - azureLiveTest bool - azureClientID string - azureClientSecret string - azureSubscriptionID string - azureTenantID string - azureResourceGroup string - azureDomain string + liveTest bool + envTestClientID string + envTestClientSecret string + envTestSubscriptionID string + envTestTenantID string + envTestResourceGroup string + envTestDomain string ) func init() { - azureClientID = os.Getenv("AZURE_CLIENT_ID") - azureClientSecret = os.Getenv("AZURE_CLIENT_SECRET") - azureSubscriptionID = os.Getenv("AZURE_SUBSCRIPTION_ID") - azureTenantID = os.Getenv("AZURE_TENANT_ID") - azureResourceGroup = os.Getenv("AZURE_RESOURCE_GROUP") - azureDomain = os.Getenv("AZURE_DOMAIN") - if len(azureClientID) > 0 && len(azureClientSecret) > 0 { - azureLiveTest = true + envTestClientID = os.Getenv("AZURE_CLIENT_ID") + envTestClientSecret = os.Getenv("AZURE_CLIENT_SECRET") + envTestSubscriptionID = os.Getenv("AZURE_SUBSCRIPTION_ID") + envTestTenantID = os.Getenv("AZURE_TENANT_ID") + envTestResourceGroup = os.Getenv("AZURE_RESOURCE_GROUP") + envTestDomain = os.Getenv("AZURE_DOMAIN") + + if len(envTestClientID) > 0 && len(envTestClientSecret) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("AZURE_CLIENT_ID", azureClientID) - os.Setenv("AZURE_SUBSCRIPTION_ID", azureSubscriptionID) + os.Setenv("AZURE_CLIENT_ID", envTestClientID) + os.Setenv("AZURE_CLIENT_SECRET", envTestClientSecret) + os.Setenv("AZURE_SUBSCRIPTION_ID", envTestSubscriptionID) + os.Setenv("AZURE_TENANT_ID", envTestTenantID) + os.Setenv("AZURE_RESOURCE_GROUP", envTestResourceGroup) } -func TestNewDNSProviderValid(t *testing.T) { - if !azureLiveTest { - t.Skip("skipping live test (requires credentials)") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "A", + "AZURE_CLIENT_SECRET": "B", + "AZURE_SUBSCRIPTION_ID": "C", + "AZURE_TENANT_ID": "D", + "AZURE_RESOURCE_GROUP": "E", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "", + "AZURE_CLIENT_SECRET": "", + "AZURE_SUBSCRIPTION_ID": "", + "AZURE_TENANT_ID": "", + "AZURE_RESOURCE_GROUP": "", + }, + expected: "azure: some credentials information are missing: AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_SUBSCRIPTION_ID,AZURE_TENANT_ID,AZURE_RESOURCE_GROUP", + }, + { + desc: "missing client id", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "", + "AZURE_CLIENT_SECRET": "B", + "AZURE_SUBSCRIPTION_ID": "C", + "AZURE_TENANT_ID": "D", + "AZURE_RESOURCE_GROUP": "E", + }, + expected: "azure: some credentials information are missing: AZURE_CLIENT_ID", + }, + { + desc: "missing client secret", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "A", + "AZURE_CLIENT_SECRET": "", + "AZURE_SUBSCRIPTION_ID": "C", + "AZURE_TENANT_ID": "D", + "AZURE_RESOURCE_GROUP": "E", + }, + expected: "azure: some credentials information are missing: AZURE_CLIENT_SECRET", + }, + { + desc: "missing subscription id", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "A", + "AZURE_CLIENT_SECRET": "B", + "AZURE_SUBSCRIPTION_ID": "", + "AZURE_TENANT_ID": "D", + "AZURE_RESOURCE_GROUP": "E", + }, + expected: "azure: some credentials information are missing: AZURE_SUBSCRIPTION_ID", + }, + { + desc: "missing tenant id", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "A", + "AZURE_CLIENT_SECRET": "B", + "AZURE_SUBSCRIPTION_ID": "C", + "AZURE_TENANT_ID": "", + "AZURE_RESOURCE_GROUP": "E", + }, + expected: "azure: some credentials information are missing: AZURE_TENANT_ID", + }, + { + desc: "missing resource group", + envVars: map[string]string{ + "AZURE_CLIENT_ID": "A", + "AZURE_CLIENT_SECRET": "B", + "AZURE_SUBSCRIPTION_ID": "C", + "AZURE_TENANT_ID": "D", + "AZURE_RESOURCE_GROUP": "", + }, + expected: "azure: some credentials information are missing: AZURE_RESOURCE_GROUP", + }, } - defer restoreEnv() - os.Setenv("AZURE_CLIENT_ID", "") + 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) + } + } - config := NewDefaultConfig() - config.ClientID = azureClientID - config.ClientSecret = azureClientSecret - config.SubscriptionID = azureSubscriptionID - config.TenantID = azureTenantID - config.ResourceGroup = azureResourceGroup + p, err := NewDNSProvider() - _, err := NewDNSProviderConfig(config) - assert.NoError(t, err) + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - if !azureLiveTest { - t.Skip("skipping live test (requires credentials)") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + clientID string + clientSecret string + subscriptionID string + tenantID string + resourceGroup string + expected string + }{ + { + desc: "success", + clientID: "A", + clientSecret: "B", + subscriptionID: "C", + tenantID: "D", + resourceGroup: "E", + }, + { + desc: "missing credentials", + expected: "azure: some credentials information are missing", + }, + { + desc: "missing client id", + clientID: "", + clientSecret: "B", + subscriptionID: "C", + tenantID: "D", + resourceGroup: "E", + expected: "azure: some credentials information are missing", + }, + { + desc: "missing client secret", + clientID: "A", + clientSecret: "", + subscriptionID: "C", + tenantID: "D", + resourceGroup: "E", + expected: "azure: some credentials information are missing", + }, + { + desc: "missing subscription id", + clientID: "A", + clientSecret: "B", + subscriptionID: "", + tenantID: "D", + resourceGroup: "E", + expected: "azure: some credentials information are missing", + }, + { + desc: "missing tenant id", + clientID: "A", + clientSecret: "B", + subscriptionID: "C", + tenantID: "", + resourceGroup: "E", + expected: "azure: some credentials information are missing", + }, + { + desc: "missing resource group", + clientID: "A", + clientSecret: "B", + subscriptionID: "C", + tenantID: "D", + resourceGroup: "", + expected: "azure: some credentials information are missing", + }, } - defer restoreEnv() - os.Setenv("AZURE_CLIENT_ID", "other") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("AZURE_CLIENT_ID") + os.Unsetenv("AZURE_CLIENT_SECRET") + os.Unsetenv("AZURE_SUBSCRIPTION_ID") + os.Unsetenv("AZURE_TENANT_ID") + os.Unsetenv("AZURE_RESOURCE_GROUP") - _, err := NewDNSProvider() - assert.NoError(t, err) + config := NewDefaultConfig() + config.ClientID = test.clientID + config.ClientSecret = test.clientSecret + config.SubscriptionID = test.subscriptionID + config.TenantID = test.tenantID + config.ResourceGroup = test.resourceGroup + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("AZURE_SUBSCRIPTION_ID", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "azure: some credentials information are missing: AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_SUBSCRIPTION_ID,AZURE_TENANT_ID,AZURE_RESOURCE_GROUP") -} - -func TestLiveAzurePresent(t *testing.T) { - if !azureLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.ClientID = azureClientID - config.ClientSecret = azureClientSecret - config.SubscriptionID = azureSubscriptionID - config.TenantID = azureTenantID - config.ResourceGroup = azureResourceGroup + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - - err = provider.Present(azureDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestLiveAzureCleanUp(t *testing.T) { - if !azureLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.ClientID = azureClientID - config.ClientSecret = azureClientSecret - config.SubscriptionID = azureSubscriptionID - config.TenantID = azureTenantID - config.ResourceGroup = azureResourceGroup + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - provider, err := NewDNSProviderConfig(config) + time.Sleep(1 * time.Second) - time.Sleep(time.Second * 1) - - assert.NoError(t, err) - - err = provider.CleanUp(azureDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/bluecat/bluecat_test.go b/providers/dns/bluecat/bluecat_test.go index 0362e58a..15649a8d 100644 --- a/providers/dns/bluecat/bluecat_test.go +++ b/providers/dns/bluecat/bluecat_test.go @@ -3,61 +3,277 @@ package bluecat import ( "os" "testing" - "time" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - bluecatLiveTest bool - bluecatServer string - bluecatUserName string - bluecatPassword string - bluecatConfigName string - bluecatDNSView string - bluecatDomain string + liveTest bool + envTestServer string + envTestUserName string + envTestPassword string + envTestConfigName string + envTestDNSView string + envTestDomain string ) func init() { - bluecatServer = os.Getenv("BLUECAT_SERVER_URL") - bluecatUserName = os.Getenv("BLUECAT_USER_NAME") - bluecatPassword = os.Getenv("BLUECAT_PASSWORD") - bluecatDomain = os.Getenv("BLUECAT_DOMAIN") - bluecatConfigName = os.Getenv("BLUECAT_CONFIG_NAME") - bluecatDNSView = os.Getenv("BLUECAT_DNS_VIEW") - if len(bluecatServer) > 0 && - len(bluecatDomain) > 0 && - len(bluecatUserName) > 0 && - len(bluecatPassword) > 0 && - len(bluecatConfigName) > 0 && - len(bluecatDNSView) > 0 { - bluecatLiveTest = true + envTestServer = os.Getenv("BLUECAT_SERVER_URL") + envTestUserName = os.Getenv("BLUECAT_USER_NAME") + envTestPassword = os.Getenv("BLUECAT_PASSWORD") + envTestDomain = os.Getenv("BLUECAT_DOMAIN") + envTestConfigName = os.Getenv("BLUECAT_CONFIG_NAME") + envTestDNSView = os.Getenv("BLUECAT_DNS_VIEW") + + if len(envTestServer) > 0 && + len(envTestDomain) > 0 && + len(envTestUserName) > 0 && + len(envTestPassword) > 0 && + len(envTestConfigName) > 0 && + len(envTestDNSView) > 0 { + liveTest = true } } -func TestLiveBluecatPresent(t *testing.T) { - if !bluecatLiveTest { +func restoreEnv() { + os.Setenv("BLUECAT_SERVER_URL", envTestServer) + os.Setenv("BLUECAT_USER_NAME", envTestUserName) + os.Setenv("BLUECAT_PASSWORD", envTestPassword) + os.Setenv("BLUECAT_CONFIG_NAME", envTestConfigName) + os.Setenv("BLUECAT_DNS_VIEW", envTestDNSView) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "http://localhost", + "BLUECAT_USER_NAME": "A", + "BLUECAT_PASSWORD": "B", + "BLUECAT_CONFIG_NAME": "C", + "BLUECAT_DNS_VIEW": "D", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "", + "BLUECAT_USER_NAME": "", + "BLUECAT_PASSWORD": "", + "BLUECAT_CONFIG_NAME": "", + "BLUECAT_DNS_VIEW": "", + }, + expected: "bluecat: some credentials information are missing: BLUECAT_SERVER_URL,BLUECAT_USER_NAME,BLUECAT_PASSWORD,BLUECAT_CONFIG_NAME,BLUECAT_DNS_VIEW", + }, + { + desc: "missing server url", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "", + "BLUECAT_USER_NAME": "A", + "BLUECAT_PASSWORD": "B", + "BLUECAT_CONFIG_NAME": "C", + "BLUECAT_DNS_VIEW": "D", + }, + expected: "bluecat: some credentials information are missing: BLUECAT_SERVER_URL", + }, + { + desc: "missing username", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "http://localhost", + "BLUECAT_USER_NAME": "", + "BLUECAT_PASSWORD": "B", + "BLUECAT_CONFIG_NAME": "C", + "BLUECAT_DNS_VIEW": "D", + }, + expected: "bluecat: some credentials information are missing: BLUECAT_USER_NAME", + }, + { + desc: "missing password", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "http://localhost", + "BLUECAT_USER_NAME": "A", + "BLUECAT_PASSWORD": "", + "BLUECAT_CONFIG_NAME": "C", + "BLUECAT_DNS_VIEW": "D", + }, + expected: "bluecat: some credentials information are missing: BLUECAT_PASSWORD", + }, + { + desc: "missing config name", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "http://localhost", + "BLUECAT_USER_NAME": "A", + "BLUECAT_PASSWORD": "B", + "BLUECAT_CONFIG_NAME": "", + "BLUECAT_DNS_VIEW": "D", + }, + expected: "bluecat: some credentials information are missing: BLUECAT_CONFIG_NAME", + }, + { + desc: "missing DNS view", + envVars: map[string]string{ + "BLUECAT_SERVER_URL": "http://localhost", + "BLUECAT_USER_NAME": "A", + "BLUECAT_PASSWORD": "B", + "BLUECAT_CONFIG_NAME": "C", + "BLUECAT_DNS_VIEW": "", + }, + expected: "bluecat: some credentials information are missing: BLUECAT_DNS_VIEW", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + baseURL string + userName string + password string + configName string + dnsView string + expected string + }{ + { + desc: "success", + baseURL: "http://localhost", + userName: "A", + password: "B", + configName: "C", + dnsView: "D", + }, + { + desc: "missing credentials", + expected: "bluecat: credentials missing", + }, + { + desc: "missing base URL", + baseURL: "", + userName: "A", + password: "B", + configName: "C", + dnsView: "D", + expected: "bluecat: credentials missing", + }, + { + desc: "missing username", + baseURL: "http://localhost", + userName: "", + password: "B", + configName: "C", + dnsView: "D", + expected: "bluecat: credentials missing", + }, + { + desc: "missing password", + baseURL: "http://localhost", + userName: "A", + password: "", + configName: "C", + dnsView: "D", + expected: "bluecat: credentials missing", + }, + { + desc: "missing config name", + baseURL: "http://localhost", + userName: "A", + password: "B", + configName: "", + dnsView: "D", + expected: "bluecat: credentials missing", + }, + { + desc: "missing DNS view", + baseURL: "http://localhost", + userName: "A", + password: "B", + configName: "C", + dnsView: "", + expected: "bluecat: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("BLUECAT_SERVER_URL") + os.Unsetenv("BLUECAT_USER_NAME") + os.Unsetenv("BLUECAT_PASSWORD") + os.Unsetenv("BLUECAT_CONFIG_NAME") + os.Unsetenv("BLUECAT_DNS_VIEW") + + config := NewDefaultConfig() + config.BaseURL = test.baseURL + config.UserName = test.userName + config.Password = test.password + config.ConfigName = test.configName + config.DNSView = test.dnsView + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.Present(bluecatDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestLiveBluecatCleanUp(t *testing.T) { - if !bluecatLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) + time.Sleep(time.Second * 1) - provider, err := NewDNSProvider() - assert.NoError(t, err) - - err = provider.CleanUp(bluecatDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/cloudflare/cloudflare_test.go b/providers/dns/cloudflare/cloudflare_test.go index 9214f32c..5605cd03 100644 --- a/providers/dns/cloudflare/cloudflare_test.go +++ b/providers/dns/cloudflare/cloudflare_test.go @@ -10,24 +10,24 @@ import ( ) var ( - cflareLiveTest bool - cflareEmail string - cflareAPIKey string - cflareDomain string + liveTest bool + envTestEmail string + envTestAPIKey string + envTestDomain string ) func init() { - cflareEmail = os.Getenv("CLOUDFLARE_EMAIL") - cflareAPIKey = os.Getenv("CLOUDFLARE_API_KEY") - cflareDomain = os.Getenv("CLOUDFLARE_DOMAIN") - if len(cflareEmail) > 0 && len(cflareAPIKey) > 0 && len(cflareDomain) > 0 { - cflareLiveTest = true + envTestEmail = os.Getenv("CLOUDFLARE_EMAIL") + envTestAPIKey = os.Getenv("CLOUDFLARE_API_KEY") + envTestDomain = os.Getenv("CLOUDFLARE_DOMAIN") + if len(envTestEmail) > 0 && len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("CLOUDFLARE_EMAIL", cflareEmail) - os.Setenv("CLOUDFLARE_API_KEY", cflareAPIKey) + os.Setenv("CLOUDFLARE_EMAIL", envTestEmail) + os.Setenv("CLOUDFLARE_API_KEY", envTestAPIKey) } func TestNewDNSProvider(t *testing.T) { @@ -83,8 +83,10 @@ func TestNewDNSProvider(t *testing.T) { p, err := NewDNSProvider() if len(test.expected) == 0 { - assert.NoError(t, err) - assert.NotNil(t, p) + require.NoError(t, err) + require.NotNil(t, p) + assert.NotNil(t, p.config) + assert.NotNil(t, p.client) } else { require.EqualError(t, err, test.expected) } @@ -133,8 +135,10 @@ func TestNewDNSProviderConfig(t *testing.T) { p, err := NewDNSProviderConfig(config) if len(test.expected) == 0 { - assert.NoError(t, err) - assert.NotNil(t, p) + require.NoError(t, err) + require.NotNil(t, p) + assert.NotNil(t, p.config) + assert.NotNil(t, p.client) } else { require.EqualError(t, err, test.expected) } @@ -142,36 +146,36 @@ func TestNewDNSProviderConfig(t *testing.T) { } } -func TestCloudFlarePresent(t *testing.T) { - if !cflareLiveTest { +func TestPresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } config := NewDefaultConfig() - config.AuthEmail = cflareEmail - config.AuthKey = cflareAPIKey + config.AuthEmail = envTestEmail + config.AuthKey = envTestAPIKey provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.Present(cflareDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -func TestCloudFlareCleanUp(t *testing.T) { - if !cflareLiveTest { +func TestCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } time.Sleep(time.Second * 2) config := NewDefaultConfig() - config.AuthEmail = cflareEmail - config.AuthKey = cflareAPIKey + config.AuthEmail = envTestEmail + config.AuthKey = envTestAPIKey provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.CleanUp(cflareDomain, "", "123d==") + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/cloudxns/cloudxns_test.go b/providers/dns/cloudxns/cloudxns_test.go index aa1ddf27..83c5d32f 100644 --- a/providers/dns/cloudxns/cloudxns_test.go +++ b/providers/dns/cloudxns/cloudxns_test.go @@ -5,79 +5,169 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - cxLiveTest bool - cxAPIKey string - cxSecretKey string - cxDomain string + liveTest bool + envTestAPIKey string + envTestSecretKey string + envTestDomain string ) func init() { - cxAPIKey = os.Getenv("CLOUDXNS_API_KEY") - cxSecretKey = os.Getenv("CLOUDXNS_SECRET_KEY") - cxDomain = os.Getenv("CLOUDXNS_DOMAIN") - if len(cxAPIKey) > 0 && len(cxSecretKey) > 0 && len(cxDomain) > 0 { - cxLiveTest = true + envTestAPIKey = os.Getenv("CLOUDXNS_API_KEY") + envTestSecretKey = os.Getenv("CLOUDXNS_SECRET_KEY") + envTestDomain = os.Getenv("CLOUDXNS_DOMAIN") + + if len(envTestAPIKey) > 0 && len(envTestSecretKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("CLOUDXNS_API_KEY", cxAPIKey) - os.Setenv("CLOUDXNS_SECRET_KEY", cxSecretKey) + os.Setenv("CLOUDXNS_API_KEY", envTestAPIKey) + os.Setenv("CLOUDXNS_SECRET_KEY", envTestSecretKey) } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("CLOUDXNS_API_KEY", "") - os.Setenv("CLOUDXNS_SECRET_KEY", "") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "CLOUDXNS_API_KEY": "123", + "CLOUDXNS_SECRET_KEY": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "CLOUDXNS_API_KEY": "", + "CLOUDXNS_SECRET_KEY": "", + }, + expected: "CloudXNS: some credentials information are missing: CLOUDXNS_API_KEY,CLOUDXNS_SECRET_KEY", + }, + { + desc: "missing API key", + envVars: map[string]string{ + "CLOUDXNS_API_KEY": "", + "CLOUDXNS_SECRET_KEY": "456", + }, + expected: "CloudXNS: some credentials information are missing: CLOUDXNS_API_KEY", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "CLOUDXNS_API_KEY": "123", + "CLOUDXNS_SECRET_KEY": "", + }, + expected: "CloudXNS: some credentials information are missing: CLOUDXNS_SECRET_KEY", + }, + } - _, err := NewDNSProviderCredentials("123", "123") - assert.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("CLOUDXNS_API_KEY", "123") - os.Setenv("CLOUDXNS_SECRET_KEY", "123") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + secretKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + secretKey: "456", + }, + { + desc: "missing credentials", + expected: "CloudXNS: credentials missing: apiKey", + }, + { + desc: "missing api key", + secretKey: "456", + expected: "CloudXNS: credentials missing: apiKey", + }, + { + desc: "missing secret key", + apiKey: "123", + expected: "CloudXNS: credentials missing: secretKey", + }, + } - _, err := NewDNSProvider() - assert.NoError(t, err) + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("CLOUDXNS_API_KEY") + os.Unsetenv("CLOUDXNS_SECRET_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.SecretKey = test.secretKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("CLOUDXNS_API_KEY", "") - os.Setenv("CLOUDXNS_SECRET_KEY", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "CloudXNS: some credentials information are missing: CLOUDXNS_API_KEY,CLOUDXNS_SECRET_KEY") -} - -func TestCloudXNSPresent(t *testing.T) { - if !cxLiveTest { +func TestPresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(cxAPIKey, cxSecretKey) - assert.NoError(t, err) + provider, err := NewDNSProviderCredentials(envTestAPIKey, envTestSecretKey) + require.NoError(t, err) - err = provider.Present(cxDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestCloudXNSCleanUp(t *testing.T) { - if !cxLiveTest { +func TestCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } time.Sleep(time.Second * 2) - provider, err := NewDNSProviderCredentials(cxAPIKey, cxSecretKey) - assert.NoError(t, err) + provider, err := NewDNSProviderCredentials(envTestAPIKey, envTestSecretKey) + require.NoError(t, err) - err = provider.CleanUp(cxDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/digitalocean/digitalocean_test.go b/providers/dns/digitalocean/digitalocean_test.go index 49a1be92..89005de1 100644 --- a/providers/dns/digitalocean/digitalocean_test.go +++ b/providers/dns/digitalocean/digitalocean_test.go @@ -5,31 +5,146 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -var fakeDigitalOceanAuth = "asdf1234" +var ( + envTestAuthToken string +) -func TestDigitalOceanPresent(t *testing.T) { - var requestReceived bool +func init() { + envTestAuthToken = os.Getenv("DO_AUTH_TOKEN") +} - mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - requestReceived = true +func restoreEnv() { + os.Setenv("DO_AUTH_TOKEN", envTestAuthToken) +} +func setupTest() (*DNSProvider, *http.ServeMux, func()) { + handler := http.NewServeMux() + server := httptest.NewServer(handler) + + config := NewDefaultConfig() + config.AuthToken = "asdf1234" + config.BaseURL = server.URL + + provider, err := NewDNSProviderConfig(config) + if err != nil { + panic(err) + } + + return provider, handler, server.Close +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "DO_AUTH_TOKEN": "123", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "DO_AUTH_TOKEN": "", + }, + expected: "digitalocean: some credentials information are missing: DO_AUTH_TOKEN", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.recordIDs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + authToken string + expected string + }{ + { + desc: "success", + authToken: "123", + }, + { + desc: "missing credentials", + expected: "digitalocean: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("DO_AUTH_TOKEN") + os.Unsetenv("ALICLOUD_SECRET_KEY") + + config := NewDefaultConfig() + config.AuthToken = test.authToken + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.recordIDs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestDNSProvider_Present(t *testing.T) { + provider, mux, tearDown := setupTest() + defer tearDown() + + mux.HandleFunc("/v2/domains/example.com/records", func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPost, r.Method, "method") - assert.Equal(t, "/v2/domains/example.com/records", r.URL.Path, "Path") + assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type") assert.Equal(t, "Bearer asdf1234", r.Header.Get("Authorization"), "Authorization") reqBody, err := ioutil.ReadAll(r.Body) - require.NoError(t, err, "reading request body") - assert.Equal(t, `{"type":"TXT","name":"_acme-challenge.example.com.","data":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI","ttl":30}`, string(reqBody)) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + + expectedReqBody := `{"type":"TXT","name":"_acme-challenge.example.com.","data":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI","ttl":30}` + assert.Equal(t, expectedReqBody, string(reqBody)) w.WriteHeader(http.StatusCreated) - fmt.Fprintf(w, `{ + _, err = fmt.Fprintf(w, `{ "domain_record": { "id": 1234567, "type": "TXT", @@ -40,53 +155,35 @@ func TestDigitalOceanPresent(t *testing.T) { "weight": null } }`) - })) - defer mock.Close() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + }) - config := NewDefaultConfig() - config.AuthToken = fakeDigitalOceanAuth - config.BaseURL = mock.URL - - provider, err := NewDNSProviderConfig(config) + err := provider.Present("example.com", "", "foobar") require.NoError(t, err) - require.NotNil(t, provider) - - err = provider.Present("example.com", "", "foobar") - require.NoError(t, err, "fail to create TXT record") - - assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't") } -func TestDigitalOceanCleanUp(t *testing.T) { - var requestReceived bool - - mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - requestReceived = true +func TestDNSProvider_CleanUp(t *testing.T) { + provider, mux, tearDown := setupTest() + defer tearDown() + mux.HandleFunc("/v2/domains/example.com/records/1234567", func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodDelete, r.Method, "method") + assert.Equal(t, "/v2/domains/example.com/records/1234567", r.URL.Path, "Path") + // NOTE: Even though the body is empty, DigitalOcean API docs still show setting this Content-Type... assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type") assert.Equal(t, "Bearer asdf1234", r.Header.Get("Authorization"), "Authorization") w.WriteHeader(http.StatusNoContent) - })) - defer mock.Close() - - config := NewDefaultConfig() - config.AuthToken = fakeDigitalOceanAuth - config.BaseURL = mock.URL - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - require.NotNil(t, provider) + }) provider.recordIDsMu.Lock() provider.recordIDs["_acme-challenge.example.com."] = 1234567 provider.recordIDsMu.Unlock() - err = provider.CleanUp("example.com", "", "") + err := provider.CleanUp("example.com", "", "") require.NoError(t, err, "fail to remove TXT record") - - assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't") } diff --git a/providers/dns/dns_providers_test.go b/providers/dns/dns_providers_test.go index 29c366c8..c953a2b2 100644 --- a/providers/dns/dns_providers_test.go +++ b/providers/dns/dns_providers_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/xenolf/lego/providers/dns/exoscale" ) @@ -29,7 +30,7 @@ func TestKnownDNSProviderSuccess(t *testing.T) { os.Setenv("EXOSCALE_API_SECRET", "123") provider, err := NewDNSChallengeProviderByName("exoscale") - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, provider) assert.IsType(t, &exoscale.DNSProvider{}, provider, "Not loaded correct DNS provider") diff --git a/providers/dns/dnsimple/dnsimple_test.go b/providers/dns/dnsimple/dnsimple_test.go index 652a1832..e5adaac2 100644 --- a/providers/dns/dnsimple/dnsimple_test.go +++ b/providers/dns/dnsimple/dnsimple_test.go @@ -11,31 +11,31 @@ import ( ) var ( - dnsimpleLiveTest bool - dnsimpleOauthToken string - dnsimpleDomain string - dnsimpleBaseURL string + liveTest bool + envTestOauthToken string + envTestDomain string + envTestBaseURL string ) func init() { - dnsimpleOauthToken = os.Getenv("DNSIMPLE_OAUTH_TOKEN") - dnsimpleDomain = os.Getenv("DNSIMPLE_DOMAIN") - dnsimpleBaseURL = "https://api.sandbox.dnsimple.com" + envTestOauthToken = os.Getenv("DNSIMPLE_OAUTH_TOKEN") + envTestDomain = os.Getenv("DNSIMPLE_DOMAIN") + envTestBaseURL = "https://api.sandbox.fake.com" - if len(dnsimpleOauthToken) > 0 && len(dnsimpleDomain) > 0 { + if len(envTestOauthToken) > 0 && len(envTestDomain) > 0 { baseURL := os.Getenv("DNSIMPLE_BASE_URL") if baseURL != "" { - dnsimpleBaseURL = baseURL + envTestBaseURL = baseURL } - dnsimpleLiveTest = true + liveTest = true } } func restoreEnv() { - os.Setenv("DNSIMPLE_OAUTH_TOKEN", dnsimpleOauthToken) - os.Setenv("DNSIMPLE_BASE_URL", dnsimpleBaseURL) + os.Setenv("DNSIMPLE_OAUTH_TOKEN", envTestOauthToken) + os.Setenv("DNSIMPLE_BASE_URL", envTestBaseURL) } func TestNewDNSProvider(t *testing.T) { @@ -159,44 +159,30 @@ func TestNewDNSProviderConfig(t *testing.T) { } } -// -// Present -// - -func TestLiveDNSimplePresent(t *testing.T) { - if !dnsimpleLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.AccessToken = dnsimpleOauthToken - config.BaseURL = dnsimpleBaseURL + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - - err = provider.Present(dnsimpleDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -// -// Cleanup -// - -func TestLiveDNSimpleCleanUp(t *testing.T) { - if !dnsimpleLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - config := NewDefaultConfig() - config.AccessToken = dnsimpleOauthToken - config.BaseURL = dnsimpleBaseURL + time.Sleep(1 * time.Second) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - - err = provider.CleanUp(dnsimpleDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/dnsmadeeasy/client.go b/providers/dns/dnsmadeeasy/client.go index 54e87dcc..ba0727b9 100644 --- a/providers/dns/dnsmadeeasy/client.go +++ b/providers/dns/dnsmadeeasy/client.go @@ -38,11 +38,11 @@ type Client struct { // NewClient creates a DNSMadeEasy client func NewClient(apiKey string, apiSecret string) (*Client, error) { if apiKey == "" { - return nil, fmt.Errorf("DNSMadeEasy: credentials missing: API key") + return nil, fmt.Errorf("credentials missing: API key") } if apiSecret == "" { - return nil, fmt.Errorf("DNSMadeEasy: credentials missing: API secret") + return nil, fmt.Errorf("credentials missing: API secret") } return &Client{ diff --git a/providers/dns/dnsmadeeasy/dnsmadeeasy.go b/providers/dns/dnsmadeeasy/dnsmadeeasy.go index c0f580d5..519a4451 100644 --- a/providers/dns/dnsmadeeasy/dnsmadeeasy.go +++ b/providers/dns/dnsmadeeasy/dnsmadeeasy.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/http" - "strconv" "strings" "time" @@ -18,6 +17,7 @@ type Config struct { BaseURL string APIKey string APISecret string + Sandbox bool HTTPClient *http.Client PropagationTimeout time.Duration PollingInterval time.Duration @@ -55,15 +55,8 @@ func NewDNSProvider() (*DNSProvider, error) { return nil, fmt.Errorf("dnsmadeeasy: %v", err) } - var baseURL string - if sandbox, _ := strconv.ParseBool(env.GetOrFile("DNSMADEEASY_SANDBOX")); sandbox { - baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0" - } else { - baseURL = "https://api.dnsmadeeasy.com/V2.0" - } - config := NewDefaultConfig() - config.BaseURL = baseURL + config.Sandbox = env.GetOrDefaultBool("DNSMADEEASY_SANDBOX", false) config.APIKey = values["DNSMADEEASY_API_KEY"] config.APISecret = values["DNSMADEEASY_API_SECRET"] @@ -88,8 +81,15 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("dnsmadeeasy: the configuration of the DNS provider is nil") } - if config.BaseURL == "" { - return nil, fmt.Errorf("dnsmadeeasy: base URL missing") + var baseURL string + if config.Sandbox { + baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0" + } else { + if len(config.BaseURL) > 0 { + baseURL = config.BaseURL + } else { + baseURL = "https://api.dnsmadeeasy.com/V2.0" + } } client, err := NewClient(config.APIKey, config.APISecret) @@ -98,7 +98,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { } client.HTTPClient = config.HTTPClient - client.BaseURL = config.BaseURL + client.BaseURL = baseURL return &DNSProvider{ client: client, diff --git a/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go b/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go index 8d6e27ac..5217a83c 100644 --- a/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go +++ b/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go @@ -4,35 +4,159 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - testLive bool - testAPIKey string - testAPISecret string - testDomain string + liveTest bool + envTestAPIKey string + envTestAPISecret string + envTestDomain string ) func init() { - testAPIKey = os.Getenv("DNSMADEEASY_API_KEY") - testAPISecret = os.Getenv("DNSMADEEASY_API_SECRET") - testDomain = os.Getenv("DNSMADEEASY_DOMAIN") + envTestAPIKey = os.Getenv("DNSMADEEASY_API_KEY") + envTestAPISecret = os.Getenv("DNSMADEEASY_API_SECRET") + envTestDomain = os.Getenv("DNSMADEEASY_DOMAIN") + os.Setenv("DNSMADEEASY_SANDBOX", "true") - testLive = len(testAPIKey) > 0 && len(testAPISecret) > 0 + + liveTest = len(envTestAPIKey) > 0 && len(envTestAPISecret) > 0 } -func TestPresentAndCleanup(t *testing.T) { - if !testLive { +func restoreEnv() { + os.Setenv("DNSMADEEASY_API_KEY", envTestAPIKey) + os.Setenv("DNSMADEEASY_API_SECRET", envTestAPISecret) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "DNSMADEEASY_API_KEY": "123", + "DNSMADEEASY_API_SECRET": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "DNSMADEEASY_API_KEY": "", + "DNSMADEEASY_API_SECRET": "", + }, + expected: "dnsmadeeasy: some credentials information are missing: DNSMADEEASY_API_KEY,DNSMADEEASY_API_SECRET", + }, + { + desc: "missing access key", + envVars: map[string]string{ + "DNSMADEEASY_API_KEY": "", + "DNSMADEEASY_API_SECRET": "456", + }, + expected: "dnsmadeeasy: some credentials information are missing: DNSMADEEASY_API_KEY", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "DNSMADEEASY_API_KEY": "123", + "DNSMADEEASY_API_SECRET": "", + }, + expected: "dnsmadeeasy: some credentials information are missing: DNSMADEEASY_API_SECRET", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + apiSecret string + expected string + }{ + { + desc: "success", + apiKey: "123", + apiSecret: "456", + }, + { + desc: "missing credentials", + expected: "dnsmadeeasy: credentials missing: API key", + }, + { + desc: "missing api key", + apiSecret: "456", + expected: "dnsmadeeasy: credentials missing: API key", + }, + { + desc: "missing secret key", + apiKey: "123", + expected: "dnsmadeeasy: credentials missing: API secret", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("DNSMADEEASY_API_KEY") + os.Unsetenv("DNSMADEEASY_API_SECRET") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.APISecret = test.apiSecret + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresentAndCleanup(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.Present(testDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) - err = provider.CleanUp(testDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/dnspod/dnspod_test.go b/providers/dns/dnspod/dnspod_test.go index 95fac006..8108ac21 100644 --- a/providers/dns/dnspod/dnspod_test.go +++ b/providers/dns/dnspod/dnspod_test.go @@ -5,81 +5,136 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - dnspodLiveTest bool - dnspodAPIKey string - dnspodDomain string + liveTest bool + envTestAPIKey string + envTestDomain string ) func init() { - dnspodAPIKey = os.Getenv("DNSPOD_API_KEY") - dnspodDomain = os.Getenv("DNSPOD_DOMAIN") - if len(dnspodAPIKey) > 0 && len(dnspodDomain) > 0 { - dnspodLiveTest = true + envTestAPIKey = os.Getenv("DNSPOD_API_KEY") + envTestDomain = os.Getenv("DNSPOD_DOMAIN") + + if len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("DNSPOD_API_KEY", dnspodAPIKey) + os.Setenv("DNSPOD_API_KEY", envTestAPIKey) } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("DNSPOD_API_KEY", "") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "DNSPOD_API_KEY": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "DNSPOD_API_KEY": "", + }, + expected: "dnspod: some credentials information are missing: DNSPOD_API_KEY", + }, + } - config := NewDefaultConfig() - config.LoginToken = "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) + } + } - _, err := NewDNSProviderConfig(config) - assert.NoError(t, err) -} -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("DNSPOD_API_KEY", "123") + p, err := NewDNSProvider() - _, err := NewDNSProvider() - 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) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("DNSPOD_API_KEY", "") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + loginToken string + expected string + }{ + { + desc: "success", + loginToken: "123", + }, + { + desc: "missing credentials", + expected: "dnspod: credentials missing", + }, + } - _, err := NewDNSProvider() - assert.EqualError(t, err, "dnspod: some credentials information are missing: DNSPOD_API_KEY") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("DNSPOD_API_KEY") + + config := NewDefaultConfig() + config.LoginToken = test.loginToken + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestLivednspodPresent(t *testing.T) { - if !dnspodLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.LoginToken = dnspodAPIKey + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - - err = provider.Present(dnspodDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestLivednspodCleanUp(t *testing.T) { - if !dnspodLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) - config := NewDefaultConfig() - config.LoginToken = dnspodAPIKey + time.Sleep(1 * time.Second) - provider, err := NewDNSProviderConfig(config) - assert.NoError(t, err) - - err = provider.CleanUp(dnspodDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/duckdns/duckdns_test.go b/providers/dns/duckdns/duckdns_test.go index a078a26d..d2aac729 100644 --- a/providers/dns/duckdns/duckdns_test.go +++ b/providers/dns/duckdns/duckdns_test.go @@ -5,65 +5,133 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - duckdnsLiveTest bool - duckdnsToken string - duckdnsDomain string + liveTest bool + envTestToken string + envTestDomain string ) func init() { - duckdnsToken = os.Getenv("DUCKDNS_TOKEN") - duckdnsDomain = os.Getenv("DUCKDNS_DOMAIN") - if len(duckdnsToken) > 0 && len(duckdnsDomain) > 0 { - duckdnsLiveTest = true + envTestToken = os.Getenv("DUCKDNS_TOKEN") + envTestDomain = os.Getenv("DUCKDNS_DOMAIN") + if len(envTestToken) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("DUCKDNS_TOKEN", duckdnsToken) + os.Setenv("DUCKDNS_TOKEN", envTestToken) } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("DUCKDNS_TOKEN", "123") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "DUCKDNS_TOKEN": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "DUCKDNS_TOKEN": "", + }, + expected: "duckdns: some credentials information are missing: DUCKDNS_TOKEN", + }, + } - _, err := NewDNSProvider() - assert.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("DUCKDNS_TOKEN", "") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + token string + expected string + }{ + { + desc: "success", + token: "123", + }, + { + desc: "missing credentials", + expected: "duckdns: credentials missing", + }, + } - _, err := NewDNSProvider() - assert.EqualError(t, err, "duckdns: some credentials information are missing: DUCKDNS_TOKEN") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("DUCKDNS_TOKEN") + + config := NewDefaultConfig() + config.Token = test.token + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestLiveDuckdnsPresent(t *testing.T) { - if !duckdnsLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.Present(duckdnsDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestLiveDuckdnsCleanUp(t *testing.T) { - if !duckdnsLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 10) - + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.CleanUp(duckdnsDomain, "", "123d==") - assert.NoError(t, err) + time.Sleep(10 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/dyn/dyn_test.go b/providers/dns/dyn/dyn_test.go index 5bbca10c..47cf8f83 100644 --- a/providers/dns/dyn/dyn_test.go +++ b/providers/dns/dyn/dyn_test.go @@ -5,50 +5,198 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - dynLiveTest bool - dynCustomerName string - dynUserName string - dynPassword string - dynDomain string + liveTest bool + envTestCustomerName string + envTestUserName string + envTestPassword string + envTestDomain string ) func init() { - dynCustomerName = os.Getenv("DYN_CUSTOMER_NAME") - dynUserName = os.Getenv("DYN_USER_NAME") - dynPassword = os.Getenv("DYN_PASSWORD") - dynDomain = os.Getenv("DYN_DOMAIN") - if len(dynCustomerName) > 0 && len(dynUserName) > 0 && len(dynPassword) > 0 && len(dynDomain) > 0 { - dynLiveTest = true + envTestCustomerName = os.Getenv("DYN_CUSTOMER_NAME") + envTestUserName = os.Getenv("DYN_USER_NAME") + envTestPassword = os.Getenv("DYN_PASSWORD") + envTestDomain = os.Getenv("DYN_DOMAIN") + + if len(envTestCustomerName) > 0 && len(envTestUserName) > 0 && len(envTestPassword) > 0 && len(envTestDomain) > 0 { + liveTest = true } } -func TestLiveDynPresent(t *testing.T) { - if !dynLiveTest { +func restoreEnv() { + os.Setenv("DYN_CUSTOMER_NAME", envTestCustomerName) + os.Setenv("DYN_USER_NAME", envTestUserName) + os.Setenv("DYN_PASSWORD", envTestPassword) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "DYN_CUSTOMER_NAME": "A", + "DYN_USER_NAME": "B", + "DYN_PASSWORD": "C", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "DYN_CUSTOMER_NAME": "", + "DYN_USER_NAME": "", + "DYN_PASSWORD": "", + }, + expected: "dyn: some credentials information are missing: DYN_CUSTOMER_NAME,DYN_USER_NAME,DYN_PASSWORD", + }, + { + desc: "missing customer name", + envVars: map[string]string{ + "DYN_CUSTOMER_NAME": "", + "DYN_USER_NAME": "B", + "DYN_PASSWORD": "C", + }, + expected: "dyn: some credentials information are missing: DYN_CUSTOMER_NAME", + }, + { + desc: "missing password", + envVars: map[string]string{ + "DYN_CUSTOMER_NAME": "A", + "DYN_USER_NAME": "", + "DYN_PASSWORD": "C", + }, + expected: "dyn: some credentials information are missing: DYN_USER_NAME", + }, + { + desc: "missing username", + envVars: map[string]string{ + "DYN_CUSTOMER_NAME": "A", + "DYN_USER_NAME": "B", + "DYN_PASSWORD": "", + }, + expected: "dyn: some credentials information are missing: DYN_PASSWORD", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + customerName string + password string + userName string + expected string + }{ + { + desc: "success", + customerName: "A", + password: "B", + userName: "C", + }, + { + desc: "missing credentials", + expected: "dyn: credentials missing", + }, + { + desc: "missing customer name", + customerName: "", + password: "B", + userName: "C", + expected: "dyn: credentials missing", + }, + { + desc: "missing password", + customerName: "A", + password: "", + userName: "C", + expected: "dyn: credentials missing", + }, + { + desc: "missing username", + customerName: "A", + password: "B", + userName: "", + expected: "dyn: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("DNSPOD_API_KEY") + + config := NewDefaultConfig() + config.CustomerName = test.customerName + config.Password = test.password + config.UserName = test.userName + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(dynDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestLiveDynCleanUp(t *testing.T) { - if !dynLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.CleanUp(dynDomain, "", "123d==") - assert.NoError(t, err) + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/exoscale/exoscale_test.go b/providers/dns/exoscale/exoscale_test.go index 0dacc653..84056e72 100644 --- a/providers/dns/exoscale/exoscale_test.go +++ b/providers/dns/exoscale/exoscale_test.go @@ -10,55 +10,141 @@ import ( ) var ( - exoscaleLiveTest bool - exoscaleAPIKey string - exoscaleAPISecret string - exoscaleDomain string + liveTest bool + envTestAPIKey string + envTestAPISecret string + envTestDomain string ) func init() { - exoscaleAPISecret = os.Getenv("EXOSCALE_API_SECRET") - exoscaleAPIKey = os.Getenv("EXOSCALE_API_KEY") - exoscaleDomain = os.Getenv("EXOSCALE_DOMAIN") - if len(exoscaleAPIKey) > 0 && len(exoscaleAPISecret) > 0 && len(exoscaleDomain) > 0 { - exoscaleLiveTest = true + envTestAPISecret = os.Getenv("EXOSCALE_API_SECRET") + envTestAPIKey = os.Getenv("EXOSCALE_API_KEY") + envTestDomain = os.Getenv("EXOSCALE_DOMAIN") + + if len(envTestAPIKey) > 0 && len(envTestAPISecret) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("EXOSCALE_API_KEY", exoscaleAPIKey) - os.Setenv("EXOSCALE_API_SECRET", exoscaleAPISecret) + os.Setenv("EXOSCALE_API_KEY", envTestAPIKey) + os.Setenv("EXOSCALE_API_SECRET", envTestAPISecret) } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("EXOSCALE_API_KEY", "") - os.Setenv("EXOSCALE_API_SECRET", "") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "EXOSCALE_API_KEY": "123", + "EXOSCALE_API_SECRET": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "EXOSCALE_API_KEY": "", + "EXOSCALE_API_SECRET": "", + }, + expected: "exoscale: some credentials information are missing: EXOSCALE_API_KEY,EXOSCALE_API_SECRET", + }, + { + desc: "missing access key", + envVars: map[string]string{ + "EXOSCALE_API_KEY": "", + "EXOSCALE_API_SECRET": "456", + }, + expected: "exoscale: some credentials information are missing: EXOSCALE_API_KEY", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "EXOSCALE_API_KEY": "123", + "EXOSCALE_API_SECRET": "", + }, + expected: "exoscale: some credentials information are missing: EXOSCALE_API_SECRET", + }, + } - config := NewDefaultConfig() - config.APIKey = "example@example.com" - config.APISecret = "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) + } + } - _, err := NewDNSProviderConfig(config) - require.NoError(t, err) + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("EXOSCALE_API_KEY", "example@example.com") - os.Setenv("EXOSCALE_API_SECRET", "123") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + apiSecret string + expected string + }{ + { + desc: "success", + apiKey: "123", + apiSecret: "456", + }, + { + desc: "missing credentials", + expected: "exoscale: credentials missing", + }, + { + desc: "missing api key", + apiSecret: "456", + expected: "exoscale: credentials missing", + }, + { + desc: "missing secret key", + apiKey: "123", + expected: "exoscale: credentials missing", + }, + } - _, err := NewDNSProvider() - require.NoError(t, err) -} + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("EXOSCALE_API_KEY") + os.Unsetenv("EXOSCALE_API_SECRET") -func TestNewDNSProviderMissingCredErr(t *testing.T) { - os.Setenv("EXOSCALE_API_KEY", "") - os.Setenv("EXOSCALE_API_SECRET", "") - defer restoreEnv() + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.APISecret = test.apiSecret - _, err := NewDNSProvider() - assert.EqualError(t, err, "exoscale: some credentials information are missing: EXOSCALE_API_KEY,EXOSCALE_API_SECRET") + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func TestDNSProvider_FindZoneAndRecordName(t *testing.T) { @@ -113,40 +199,34 @@ func TestDNSProvider_FindZoneAndRecordName(t *testing.T) { } } -func TestLiveExoscalePresent(t *testing.T) { - if !exoscaleLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.APIKey = exoscaleAPIKey - config.APISecret = exoscaleAPISecret - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(exoscaleDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) // Present Twice to handle create / update - err = provider.Present(exoscaleDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -func TestLiveExoscaleCleanUp(t *testing.T) { - if !exoscaleLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - - config := NewDefaultConfig() - config.APIKey = exoscaleAPIKey - config.APISecret = exoscaleAPISecret - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(exoscaleDomain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/fastdns/fastdns.go b/providers/dns/fastdns/fastdns.go index 7fb6b3c0..9ef6cb0e 100644 --- a/providers/dns/fastdns/fastdns.go +++ b/providers/dns/fastdns/fastdns.go @@ -77,7 +77,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { } if config.ClientToken == "" || config.ClientSecret == "" || config.AccessToken == "" || config.Host == "" { - return nil, fmt.Errorf("FastDNS credentials are missing") + return nil, fmt.Errorf("fastdns: credentials are missing") } return &DNSProvider{config: config}, nil diff --git a/providers/dns/fastdns/fastdns_test.go b/providers/dns/fastdns/fastdns_test.go index abd21236..30ff9aa0 100644 --- a/providers/dns/fastdns/fastdns_test.go +++ b/providers/dns/fastdns/fastdns_test.go @@ -10,92 +10,203 @@ import ( ) var ( - fastdnsLiveTest bool - host string - clientToken string - clientSecret string - accessToken string - testDomain string + liveTest bool + envTestHost string + envTestClientToken string + envTestClientSecret string + envTestAccessToken string + envTestDomain string ) func init() { - host = os.Getenv("AKAMAI_HOST") - clientToken = os.Getenv("AKAMAI_CLIENT_TOKEN") - clientSecret = os.Getenv("AKAMAI_CLIENT_SECRET") - accessToken = os.Getenv("AKAMAI_ACCESS_TOKEN") - testDomain = os.Getenv("AKAMAI_TEST_DOMAIN") + envTestHost = os.Getenv("AKAMAI_HOST") + envTestClientToken = os.Getenv("AKAMAI_CLIENT_TOKEN") + envTestClientSecret = os.Getenv("AKAMAI_CLIENT_SECRET") + envTestAccessToken = os.Getenv("AKAMAI_ACCESS_TOKEN") + envTestDomain = os.Getenv("AKAMAI_TEST_DOMAIN") - if len(host) > 0 && len(clientToken) > 0 && len(clientSecret) > 0 && len(accessToken) > 0 { - fastdnsLiveTest = true + if len(envTestHost) > 0 && len(envTestClientToken) > 0 && len(envTestClientSecret) > 0 && len(envTestAccessToken) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("AKAMAI_HOST", host) - os.Setenv("AKAMAI_CLIENT_TOKEN", clientToken) - os.Setenv("AKAMAI_CLIENT_SECRET", clientSecret) - os.Setenv("AKAMAI_ACCESS_TOKEN", accessToken) + os.Setenv("AKAMAI_HOST", envTestHost) + os.Setenv("AKAMAI_CLIENT_TOKEN", envTestClientToken) + os.Setenv("AKAMAI_CLIENT_SECRET", envTestClientSecret) + os.Setenv("AKAMAI_ACCESS_TOKEN", envTestAccessToken) } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("AKAMAI_HOST", "") - os.Setenv("AKAMAI_CLIENT_TOKEN", "") - os.Setenv("AKAMAI_CLIENT_SECRET", "") - os.Setenv("AKAMAI_ACCESS_TOKEN", "") - - config := NewDefaultConfig() - config.Host = "somehost" - config.ClientToken = "someclienttoken" - config.ClientSecret = "someclientsecret" - config.AccessToken = "someaccesstoken" - - _, err := NewDNSProviderConfig(config) - require.NoError(t, err) -} - -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("AKAMAI_HOST", "somehost") - os.Setenv("AKAMAI_CLIENT_TOKEN", "someclienttoken") - os.Setenv("AKAMAI_CLIENT_SECRET", "someclientsecret") - os.Setenv("AKAMAI_ACCESS_TOKEN", "someaccesstoken") - - _, err := NewDNSProvider() - require.NoError(t, err) -} - -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("AKAMAI_HOST", "") - os.Setenv("AKAMAI_CLIENT_TOKEN", "") - os.Setenv("AKAMAI_CLIENT_SECRET", "") - os.Setenv("AKAMAI_ACCESS_TOKEN", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "fastdns: some credentials information are missing: AKAMAI_HOST,AKAMAI_CLIENT_TOKEN,AKAMAI_CLIENT_SECRET,AKAMAI_ACCESS_TOKEN") -} - -func TestLiveFastdnsPresent(t *testing.T) { - if !fastdnsLiveTest { - t.Skip("skipping live test") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "AKAMAI_HOST": "A", + "AKAMAI_CLIENT_TOKEN": "B", + "AKAMAI_CLIENT_SECRET": "C", + "AKAMAI_ACCESS_TOKEN": "D", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "AKAMAI_HOST": "", + "AKAMAI_CLIENT_TOKEN": "", + "AKAMAI_CLIENT_SECRET": "", + "AKAMAI_ACCESS_TOKEN": "", + }, + expected: "fastdns: some credentials information are missing: AKAMAI_HOST,AKAMAI_CLIENT_TOKEN,AKAMAI_CLIENT_SECRET,AKAMAI_ACCESS_TOKEN", + }, + { + desc: "missing host", + envVars: map[string]string{ + "AKAMAI_HOST": "", + "AKAMAI_CLIENT_TOKEN": "B", + "AKAMAI_CLIENT_SECRET": "C", + "AKAMAI_ACCESS_TOKEN": "D", + }, + expected: "fastdns: some credentials information are missing: AKAMAI_HOST", + }, + { + desc: "missing client token", + envVars: map[string]string{ + "AKAMAI_HOST": "A", + "AKAMAI_CLIENT_TOKEN": "", + "AKAMAI_CLIENT_SECRET": "C", + "AKAMAI_ACCESS_TOKEN": "D", + }, + expected: "fastdns: some credentials information are missing: AKAMAI_CLIENT_TOKEN", + }, + { + desc: "missing client secret", + envVars: map[string]string{ + "AKAMAI_HOST": "A", + "AKAMAI_CLIENT_TOKEN": "B", + "AKAMAI_CLIENT_SECRET": "", + "AKAMAI_ACCESS_TOKEN": "D", + }, + expected: "fastdns: some credentials information are missing: AKAMAI_CLIENT_SECRET", + }, + { + desc: "missing access token", + envVars: map[string]string{ + "AKAMAI_HOST": "A", + "AKAMAI_CLIENT_TOKEN": "B", + "AKAMAI_CLIENT_SECRET": "C", + "AKAMAI_ACCESS_TOKEN": "", + }, + expected: "fastdns: some credentials information are missing: AKAMAI_ACCESS_TOKEN", + }, } - config := NewDefaultConfig() - config.Host = host - config.ClientToken = clientToken - config.ClientSecret = clientSecret - config.AccessToken = accessToken + 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) + } + } - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) + p, err := NewDNSProvider() - err = provider.Present(testDomain, "", "123d==") - require.NoError(t, err) + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} - // Present Twice to handle create / update - err = provider.Present(testDomain, "", "123d==") - require.NoError(t, err) +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + host string + clientToken string + clientSecret string + accessToken string + expected string + }{ + { + desc: "success", + host: "A", + clientToken: "B", + clientSecret: "C", + accessToken: "D", + }, + { + desc: "missing credentials", + expected: "fastdns: credentials are missing", + }, + { + desc: "missing host", + host: "", + clientToken: "B", + clientSecret: "C", + accessToken: "D", + expected: "fastdns: credentials are missing", + }, + { + desc: "missing client token", + host: "A", + clientToken: "", + clientSecret: "C", + accessToken: "D", + expected: "fastdns: credentials are missing", + }, + { + desc: "missing client secret", + host: "A", + clientToken: "B", + clientSecret: "", + accessToken: "B", + expected: "fastdns: credentials are missing", + }, + { + desc: "missing access token", + host: "A", + clientToken: "B", + clientSecret: "C", + accessToken: "", + expected: "fastdns: credentials are missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("AKAMAI_HOST") + os.Unsetenv("AKAMAI_CLIENT_TOKEN") + os.Unsetenv("AKAMAI_CLIENT_SECRET") + os.Unsetenv("AKAMAI_ACCESS_TOKEN") + + config := NewDefaultConfig() + config.ClientToken = test.clientToken + config.ClientSecret = test.clientSecret + config.Host = test.host + config.AccessToken = test.accessToken + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func TestDNSProvider_findZoneAndRecordName(t *testing.T) { @@ -152,22 +263,39 @@ func TestDNSProvider_findZoneAndRecordName(t *testing.T) { } } -func TestLiveFastdnsCleanUp(t *testing.T) { - if !fastdnsLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { + t.Skip("skipping live test") + } + + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) + + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) + + // Present Twice to handle create / update + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) +} + +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } time.Sleep(time.Second * 1) config := NewDefaultConfig() - config.Host = host - config.ClientToken = clientToken - config.ClientSecret = clientSecret - config.AccessToken = accessToken + config.Host = envTestHost + config.ClientToken = envTestClientToken + config.ClientSecret = envTestClientSecret + config.AccessToken = envTestAccessToken provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.CleanUp(testDomain, "", "123d==") + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/gandi/gandi_test.go b/providers/dns/gandi/gandi_test.go index ea416232..cf1779e8 100644 --- a/providers/dns/gandi/gandi_test.go +++ b/providers/dns/gandi/gandi_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" "regexp" "strings" "testing" @@ -12,6 +13,104 @@ import ( "github.com/stretchr/testify/require" ) +var ( + envTestAPIKey string +) + +func init() { + envTestAPIKey = os.Getenv("GANDI_API_KEY") +} + +func restoreEnv() { + os.Setenv("GANDI_API_KEY", envTestAPIKey) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "GANDI_API_KEY": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "GANDI_API_KEY": "", + }, + expected: "gandi: some credentials information are missing: GANDI_API_KEY", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.inProgressFQDNs) + require.NotNil(t, p.inProgressAuthZones) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + }, + { + desc: "missing credentials", + expected: "gandi: no API Key given", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("GANDI_API_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.inProgressFQDNs) + require.NotNil(t, p.inProgressAuthZones) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + // TestDNSProvider runs Present and CleanUp against a fake Gandi RPC // Server, whose responses are predetermined for particular requests. func TestDNSProvider(t *testing.T) { diff --git a/providers/dns/gandiv5/gandiv5.go b/providers/dns/gandiv5/gandiv5.go index 04e9fa19..0962d159 100644 --- a/providers/dns/gandiv5/gandiv5.go +++ b/providers/dns/gandiv5/gandiv5.go @@ -102,6 +102,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { config.BaseURL = defaultBaseURL } + if config.TTL < minTTL { + return nil, fmt.Errorf("gandiv5: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + return &DNSProvider{ config: config, inProgressFQDNs: make(map[string]inProgressInfo), @@ -112,10 +116,6 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value, _ := acme.DNS01Record(domain, keyAuth) - if d.config.TTL < minTTL { - d.config.TTL = minTTL // 300 is gandi minimum value for ttl - } - // find authZone authZone, err := findZoneByFqdn(fqdn, acme.RecursiveNameservers) if err != nil { diff --git a/providers/dns/gandiv5/gandiv5_test.go b/providers/dns/gandiv5/gandiv5_test.go index 0cc5e825..693a0b82 100644 --- a/providers/dns/gandiv5/gandiv5_test.go +++ b/providers/dns/gandiv5/gandiv5_test.go @@ -5,14 +5,110 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" "regexp" "testing" - "github.com/xenolf/lego/log" - "github.com/stretchr/testify/require" + "github.com/xenolf/lego/log" ) +var ( + envTestAPIKey string +) + +func init() { + envTestAPIKey = os.Getenv("GANDIV5_API_KEY") +} + +func restoreEnv() { + os.Setenv("GANDIV5_API_KEY", envTestAPIKey) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "GANDIV5_API_KEY": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "GANDIV5_API_KEY": "", + }, + expected: "gandi: some credentials information are missing: GANDIV5_API_KEY", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.inProgressFQDNs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + }, + { + desc: "missing credentials", + expected: "gandiv5: no API Key given", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("GANDIV5_API_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.inProgressFQDNs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + // TestDNSProvider runs Present and CleanUp against a fake Gandi RPC // Server, whose responses are predetermined for particular requests. func TestDNSProvider(t *testing.T) { diff --git a/providers/dns/gcloud/fixtures/gce_account_service_file.json b/providers/dns/gcloud/fixtures/gce_account_service_file.json new file mode 100644 index 00000000..c9b61682 --- /dev/null +++ b/providers/dns/gcloud/fixtures/gce_account_service_file.json @@ -0,0 +1,11 @@ +{ + "project_id": "A", + "type": "service_account", + "client_email": "foo@bar.com", + "private_key_id": "pki", + "private_key": "pk", + "token_uri": "/token", + "client_secret": "secret", + "client_id": "C", + "refresh_token": "D" +} \ No newline at end of file diff --git a/providers/dns/gcloud/googlecloud_test.go b/providers/dns/gcloud/googlecloud_test.go index ec94a79d..e374396a 100644 --- a/providers/dns/gcloud/googlecloud_test.go +++ b/providers/dns/gcloud/googlecloud_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/net/context" "golang.org/x/oauth2/google" @@ -13,93 +12,168 @@ import ( ) var ( - gcloudLiveTest bool - gcloudProject string - gcloudDomain string + liveTest bool + envTestProject string + envTestServiceAccountFile string + envTestGoogleApplicationCredentials string + envTestDomain string ) func init() { - gcloudProject = os.Getenv("GCE_PROJECT") - gcloudDomain = os.Getenv("GCE_DOMAIN") + envTestProject = os.Getenv("GCE_PROJECT") + envTestServiceAccountFile = os.Getenv("GCE_SERVICE_ACCOUNT_FILE") + envTestGoogleApplicationCredentials = os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") + envTestDomain = os.Getenv("GCE_DOMAIN") + _, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope) - if err == nil && len(gcloudProject) > 0 && len(gcloudDomain) > 0 { - gcloudLiveTest = true + if err == nil && len(envTestProject) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("GCE_PROJECT", gcloudProject) + os.Setenv("GCE_PROJECT", envTestProject) + os.Setenv("GCE_SERVICE_ACCOUNT_FILE", envTestServiceAccountFile) + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", envTestGoogleApplicationCredentials) } -func TestNewDNSProviderValid(t *testing.T) { - if !gcloudLiveTest { - t.Skip("skipping live test (requires credentials)") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "invalid credentials", + envVars: map[string]string{ + "GCE_PROJECT": "123", + "GCE_SERVICE_ACCOUNT_FILE": "", + // as Travis run on GCE, we have to alter env + "GOOGLE_APPLICATION_CREDENTIALS": "not-a-secret-file", + }, + expected: "googlecloud: unable to get Google Cloud client: google: error getting credentials using GOOGLE_APPLICATION_CREDENTIALS environment variable: open not-a-secret-file: no such file or directory", + }, + { + desc: "missing project", + envVars: map[string]string{ + "GCE_PROJECT": "", + "GCE_SERVICE_ACCOUNT_FILE": "", + }, + expected: "googlecloud: project name missing", + }, + { + desc: "success", + envVars: map[string]string{ + "GCE_PROJECT": "", + "GCE_SERVICE_ACCOUNT_FILE": "fixtures/gce_account_service_file.json", + }, + }, } - defer restoreEnv() - os.Setenv("GCE_PROJECT", "") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() - _, err := NewDNSProviderCredentials("my-project") - require.NoError(t, err) + for key, value := range test.envVars { + if len(value) == 0 { + os.Unsetenv(key) + } else { + os.Setenv(key, value) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - if !gcloudLiveTest { - t.Skip("skipping live test (requires credentials)") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + project string + expected string + }{ + { + desc: "invalid project", + project: "123", + expected: "googlecloud: unable to create Google Cloud DNS service: client is nil", + }, + { + desc: "missing project", + expected: "googlecloud: unable to create Google Cloud DNS service: client is nil", + }, } - defer restoreEnv() - os.Setenv("GCE_PROJECT", "my-project") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("GCE_PROJECT") + os.Unsetenv("GCE_SERVICE_ACCOUNT_FILE") - _, err := NewDNSProvider() - require.NoError(t, err) + config := NewDefaultConfig() + config.Project = test.project + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("GCE_PROJECT", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "googlecloud: project name missing") -} - -func TestLiveGoogleCloudPresent(t *testing.T) { - if !gcloudLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(gcloudProject) + provider, err := NewDNSProviderCredentials(envTestProject) require.NoError(t, err) - err = provider.Present(gcloudDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -func TestLiveGoogleCloudPresentMultiple(t *testing.T) { - if !gcloudLiveTest { +func TestLivePresentMultiple(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(gcloudProject) + provider, err := NewDNSProviderCredentials(envTestProject) require.NoError(t, err) // Check that we're able to create multiple entries - err = provider.Present(gcloudDomain, "1", "123d==") + err = provider.Present(envTestDomain, "1", "123d==") require.NoError(t, err) - err = provider.Present(gcloudDomain, "2", "123d==") + + err = provider.Present(envTestDomain, "2", "123d==") require.NoError(t, err) } -func TestLiveGoogleCloudCleanUp(t *testing.T) { - if !gcloudLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - - provider, err := NewDNSProviderCredentials(gcloudProject) + provider, err := NewDNSProviderCredentials(envTestProject) require.NoError(t, err) - err = provider.CleanUp(gcloudDomain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/glesys/glesys.go b/providers/dns/glesys/glesys.go index 69f61f77..4aab8744 100644 --- a/providers/dns/glesys/glesys.go +++ b/providers/dns/glesys/glesys.go @@ -93,6 +93,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, fmt.Errorf("glesys: incomplete credentials provided") } + if config.TTL < minTTL { + return nil, fmt.Errorf("glesys: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + return &DNSProvider{ config: config, activeRecords: make(map[string]int), @@ -103,9 +107,6 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value, _ := acme.DNS01Record(domain, keyAuth) - if d.config.TTL < minTTL { - d.config.TTL = minTTL // 60 is GleSYS minimum value for ttl - } // find authZone authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers) if err != nil { diff --git a/providers/dns/glesys/glesys_test.go b/providers/dns/glesys/glesys_test.go index ccb5d5e8..7a0b9971 100644 --- a/providers/dns/glesys/glesys_test.go +++ b/providers/dns/glesys/glesys_test.go @@ -4,58 +4,170 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - glesysAPIUser string - glesysAPIKey string - glesysDomain string - glesysLiveTest bool + liveTest bool + envTestAPIUser string + envTestAPIKey string + envTestDomain string ) func init() { - glesysAPIUser = os.Getenv("GLESYS_API_USER") - glesysAPIKey = os.Getenv("GLESYS_API_KEY") - glesysDomain = os.Getenv("GLESYS_DOMAIN") + envTestAPIUser = os.Getenv("GLESYS_API_USER") + envTestAPIKey = os.Getenv("GLESYS_API_KEY") - if len(glesysAPIUser) > 0 && len(glesysAPIKey) > 0 && len(glesysDomain) > 0 { - glesysLiveTest = true + if len(envTestAPIUser) > 0 && len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } +func restoreEnv() { + os.Setenv("GLESYS_API_USER", envTestAPIUser) + os.Setenv("GLESYS_API_KEY", envTestAPIKey) +} + func TestNewDNSProvider(t *testing.T) { - provider, err := NewDNSProvider() + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "GLESYS_API_USER": "A", + "GLESYS_API_KEY": "B", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "GLESYS_API_USER": "", + "GLESYS_API_KEY": "", + }, + expected: "glesys: some credentials information are missing: GLESYS_API_USER,GLESYS_API_KEY", + }, + { + desc: "missing api user", + envVars: map[string]string{ + "GLESYS_API_USER": "", + "GLESYS_API_KEY": "B", + }, + expected: "glesys: some credentials information are missing: GLESYS_API_USER", + }, + { + desc: "missing api key", + envVars: map[string]string{ + "GLESYS_API_USER": "A", + "GLESYS_API_KEY": "", + }, + expected: "glesys: some credentials information are missing: GLESYS_API_KEY", + }, + } - if !glesysLiveTest { - assert.Error(t, err) - } else { - assert.NotNil(t, provider) - assert.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.activeRecords) + } else { + require.EqualError(t, err, test.expected) + } + }) } } -func TestDNSProvider_Present(t *testing.T) { - if !glesysLiveTest { +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiUser string + apiKey string + expected string + }{ + { + desc: "success", + apiUser: "A", + apiKey: "B", + }, + { + desc: "missing credentials", + expected: "glesys: incomplete credentials provided", + }, + { + desc: "missing api user", + apiUser: "", + apiKey: "B", + expected: "glesys: incomplete credentials provided", + }, + { + desc: "missing api key", + apiUser: "A", + apiKey: "", + expected: "glesys: incomplete credentials provided", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("GLESYS_API_USER") + os.Unsetenv("GLESYS_API_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.APIUser = test.apiUser + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.activeRecords) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(glesysDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -func TestDNSProvider_CleanUp(t *testing.T) { - if !glesysLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(glesysDomain, "", "123d==") + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/godaddy/godaddy_test.go b/providers/dns/godaddy/godaddy_test.go index de84d827..d0c5bf2a 100644 --- a/providers/dns/godaddy/godaddy_test.go +++ b/providers/dns/godaddy/godaddy_test.go @@ -4,57 +4,167 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( - godaddyAPIKey string - godaddyAPISecret string - godaddyDomain string - godaddyLiveTest bool + liveTest bool + envTestAPIKey string + envTestAPISecret string + envTestDomain string ) func init() { - godaddyAPIKey = os.Getenv("GODADDY_API_KEY") - godaddyAPISecret = os.Getenv("GODADDY_API_SECRET") - godaddyDomain = os.Getenv("GODADDY_DOMAIN") + envTestAPIKey = os.Getenv("GODADDY_API_KEY") + envTestAPISecret = os.Getenv("GODADDY_API_SECRET") + envTestDomain = os.Getenv("GODADDY_DOMAIN") - if len(godaddyAPIKey) > 0 && len(godaddyAPISecret) > 0 && len(godaddyDomain) > 0 { - godaddyLiveTest = true + if len(envTestAPIKey) > 0 && len(envTestAPISecret) > 0 && len(envTestDomain) > 0 { + liveTest = true } } +func restoreEnv() { + os.Setenv("GODADDY_API_KEY", envTestAPIKey) + os.Setenv("GODADDY_API_SECRET", envTestAPISecret) +} + func TestNewDNSProvider(t *testing.T) { - provider, err := NewDNSProvider() + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "GODADDY_API_KEY": "123", + "GODADDY_API_SECRET": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "GODADDY_API_KEY": "", + "GODADDY_API_SECRET": "", + }, + expected: "godaddy: some credentials information are missing: GODADDY_API_KEY,GODADDY_API_SECRET", + }, + { + desc: "missing access key", + envVars: map[string]string{ + "GODADDY_API_KEY": "", + "GODADDY_API_SECRET": "456", + }, + expected: "godaddy: some credentials information are missing: GODADDY_API_KEY", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "GODADDY_API_KEY": "123", + "GODADDY_API_SECRET": "", + }, + expected: "godaddy: some credentials information are missing: GODADDY_API_SECRET", + }, + } - if !godaddyLiveTest { - assert.Error(t, err) - } else { - assert.NotNil(t, provider) - assert.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) } } -func TestDNSProvider_Present(t *testing.T) { - if !godaddyLiveTest { +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + apiSecret string + expected string + }{ + { + desc: "success", + apiKey: "123", + apiSecret: "456", + }, + { + desc: "missing credentials", + expected: "godaddy: credentials missing", + }, + { + desc: "missing api key", + apiSecret: "456", + expected: "godaddy: credentials missing", + }, + { + desc: "missing secret key", + apiKey: "123", + expected: "godaddy: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("GODADDY_API_KEY") + os.Unsetenv("GODADDY_API_SECRET") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.APISecret = test.apiSecret + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.Present(godaddyDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestDNSProvider_CleanUp(t *testing.T) { - if !godaddyLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.CleanUp(godaddyDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/hostingde/hostingde_test.go b/providers/dns/hostingde/hostingde_test.go index c948c2aa..d1cd9662 100644 --- a/providers/dns/hostingde/hostingde_test.go +++ b/providers/dns/hostingde/hostingde_test.go @@ -5,100 +5,170 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - hostingdeLiveTest bool - hostingdeAPIKey string - hostingdeZone string - hostingdeDomain string + liveTest bool + envTestAPIKey string + envTestZone string + envTestDomain string ) func init() { - hostingdeAPIKey = os.Getenv("HOSTINGDE_API_KEY") - hostingdeZone = os.Getenv("HOSTINGDE_ZONE_NAME") - hostingdeDomain = os.Getenv("HOSTINGDE_DOMAIN") - if len(hostingdeZone) > 0 && len(hostingdeAPIKey) > 0 && len(hostingdeDomain) > 0 { - hostingdeLiveTest = true + envTestAPIKey = os.Getenv("HOSTINGDE_API_KEY") + envTestZone = os.Getenv("HOSTINGDE_ZONE_NAME") + envTestDomain = os.Getenv("HOSTINGDE_DOMAIN") + if len(envTestZone) > 0 && len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("HOSTINGDE_ZONE_NAME", hostingdeZone) - os.Setenv("HOSTINGDE_API_KEY", hostingdeAPIKey) + os.Setenv("HOSTINGDE_ZONE_NAME", envTestZone) + os.Setenv("HOSTINGDE_API_KEY", envTestAPIKey) } -func TestNewDNSProviderValid(t *testing.T) { - os.Setenv("HOSTINGDE_ZONE_NAME", "") - os.Setenv("HOSTINGDE_API_KEY", "") - defer restoreEnv() +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "HOSTINGDE_API_KEY": "123", + "HOSTINGDE_ZONE_NAME": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "HOSTINGDE_API_KEY": "", + "HOSTINGDE_ZONE_NAME": "", + }, + expected: "hostingde: some credentials information are missing: HOSTINGDE_API_KEY,HOSTINGDE_ZONE_NAME", + }, + { + desc: "missing access key", + envVars: map[string]string{ + "HOSTINGDE_API_KEY": "", + "HOSTINGDE_ZONE_NAME": "456", + }, + expected: "hostingde: some credentials information are missing: HOSTINGDE_API_KEY", + }, + { + desc: "missing zone name", + envVars: map[string]string{ + "HOSTINGDE_API_KEY": "123", + "HOSTINGDE_ZONE_NAME": "", + }, + expected: "hostingde: some credentials information are missing: HOSTINGDE_ZONE_NAME", + }, + } - config := NewDefaultConfig() - config.APIKey = "123" - config.ZoneName = "example.com" + 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) + } + } - _, err := NewDNSProviderConfig(config) - assert.NoError(t, err) + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.recordIDs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("HOSTINGDE_ZONE_NAME", "example.com") - os.Setenv("HOSTINGDE_API_KEY", "123") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + zoneName string + expected string + }{ + { + desc: "success", + apiKey: "123", + zoneName: "456", + }, + { + desc: "missing credentials", + expected: "hostingde: API key missing", + }, + { + desc: "missing api key", + zoneName: "456", + expected: "hostingde: API key missing", + }, + { + desc: "missing zone name", + apiKey: "123", + expected: "hostingde: Zone Name missing", + }, + } - _, err := NewDNSProvider() - assert.NoError(t, err) + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("HOSTINGDE_API_KEY") + os.Unsetenv("HOSTINGDE_ZONE_NAME") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.ZoneName = test.zoneName + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.recordIDs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("HOSTINGDE_ZONE_NAME", "") - os.Setenv("HOSTINGDE_API_KEY", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "hostingde: some credentials information are missing: HOSTINGDE_API_KEY,HOSTINGDE_ZONE_NAME") -} - -func TestNewDNSProviderMissingCredErrSingle(t *testing.T) { - defer restoreEnv() - os.Setenv("HOSTINGDE_ZONE_NAME", "example.com") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "hostingde: some credentials information are missing: HOSTINGDE_API_KEY") -} - -func TestHostingdePresent(t *testing.T) { - if !hostingdeLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.APIKey = hostingdeZone - config.ZoneName = hostingdeAPIKey - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(hostingdeDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestHostingdeCleanUp(t *testing.T) { - if !hostingdeLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 2) - - config := NewDefaultConfig() - config.APIKey = hostingdeZone - config.ZoneName = hostingdeAPIKey - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(hostingdeDomain, "", "123d==") - assert.NoError(t, err) + time.Sleep(2 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/iij/iij_test.go b/providers/dns/iij/iij_test.go index 1bcc76c8..76c3fd5b 100644 --- a/providers/dns/iij/iij_test.go +++ b/providers/dns/iij/iij_test.go @@ -9,30 +9,173 @@ import ( ) var ( - apiAccessKeyEnv string - apiSecretKeyEnv string - doServiceCodeEnv string - testDomain string - liveTest bool + liveTest bool + envTestAPIAccessKey string + envTestAPISecretKeyEnv string + envTestDoServiceCodeEnv string + envTestDomain string ) func init() { - apiAccessKeyEnv = os.Getenv("IIJ_API_ACCESS_KEY") - apiSecretKeyEnv = os.Getenv("IIJ_API_SECRET_KEY") - doServiceCodeEnv = os.Getenv("IIJ_DO_SERVICE_CODE") + envTestAPIAccessKey = os.Getenv("IIJ_API_ACCESS_KEY") + envTestAPISecretKeyEnv = os.Getenv("IIJ_API_SECRET_KEY") + envTestDoServiceCodeEnv = os.Getenv("IIJ_DO_SERVICE_CODE") - testDomain = os.Getenv("IIJ_API_TESTDOMAIN") + envTestDomain = os.Getenv("IIJ_API_TESTDOMAIN") - if len(apiAccessKeyEnv) > 0 && len(apiSecretKeyEnv) > 0 && len(doServiceCodeEnv) > 0 && len(testDomain) > 0 { + if len(envTestAPIAccessKey) > 0 && len(envTestAPISecretKeyEnv) > 0 && len(envTestDoServiceCodeEnv) > 0 && len(envTestDomain) > 0 { liveTest = true } } func restoreEnv() { - os.Setenv("IIJ_API_ACCESS_KEY", apiAccessKeyEnv) - os.Setenv("IIJ_API_SECRET_KEY", apiSecretKeyEnv) - os.Setenv("IIJ_DO_SERVICE_CODE", doServiceCodeEnv) - os.Setenv("IIJ_API_TESTDOMAIN", testDomain) + os.Setenv("IIJ_API_ACCESS_KEY", envTestAPIAccessKey) + os.Setenv("IIJ_API_SECRET_KEY", envTestAPISecretKeyEnv) + os.Setenv("IIJ_DO_SERVICE_CODE", envTestDoServiceCodeEnv) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "IIJ_API_ACCESS_KEY": "A", + "IIJ_API_SECRET_KEY": "B", + "IIJ_DO_SERVICE_CODE": "C", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "IIJ_API_ACCESS_KEY": "", + "IIJ_API_SECRET_KEY": "", + "IIJ_DO_SERVICE_CODE": "", + }, + expected: "iij: some credentials information are missing: IIJ_API_ACCESS_KEY,IIJ_API_SECRET_KEY,IIJ_DO_SERVICE_CODE", + }, + { + desc: "missing api access key", + envVars: map[string]string{ + "IIJ_API_ACCESS_KEY": "", + "IIJ_API_SECRET_KEY": "B", + "IIJ_DO_SERVICE_CODE": "C", + }, + expected: "iij: some credentials information are missing: IIJ_API_ACCESS_KEY", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "IIJ_API_ACCESS_KEY": "A", + "IIJ_API_SECRET_KEY": "", + "IIJ_DO_SERVICE_CODE": "C", + }, + expected: "iij: some credentials information are missing: IIJ_API_SECRET_KEY", + }, + { + desc: "missing do service code", + envVars: map[string]string{ + "IIJ_API_ACCESS_KEY": "A", + "IIJ_API_SECRET_KEY": "B", + "IIJ_DO_SERVICE_CODE": "", + }, + expected: "iij: some credentials information are missing: IIJ_DO_SERVICE_CODE", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.api) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + accessKey string + secretKey string + doServiceCode string + expected string + }{ + { + desc: "success", + accessKey: "A", + secretKey: "B", + doServiceCode: "C", + }, + { + desc: "missing credentials", + expected: "iij: credentials missing", + }, + { + desc: "missing access key", + accessKey: "", + secretKey: "B", + doServiceCode: "C", + expected: "iij: credentials missing", + }, + { + desc: "missing secret key", + accessKey: "A", + secretKey: "", + doServiceCode: "C", + expected: "iij: credentials missing", + }, + { + desc: "missing do service code", + accessKey: "A", + secretKey: "B", + doServiceCode: "", + expected: "iij: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("IIJ_API_ACCESS_KEY") + os.Unsetenv("IIJ_API_SECRET_KEY") + os.Unsetenv("IIJ_DO_SERVICE_CODE") + + config := NewDefaultConfig() + config.AccessKey = test.accessKey + config.SecretKey = test.secretKey + config.DoServiceCode = test.doServiceCode + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.api) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func TestSplitDomain(t *testing.T) { @@ -88,45 +231,28 @@ func TestSplitDomain(t *testing.T) { } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("IIJ_API_ACCESS_KEY", "") - os.Setenv("IIJ_API_SECRET_KEY", "") - os.Setenv("IIJ_DO_SERVICE_CODE", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "iij: some credentials information are missing: IIJ_API_ACCESS_KEY,IIJ_API_SECRET_KEY,IIJ_DO_SERVICE_CODE") -} - -func TestNewDNSProvider(t *testing.T) { - if !liveTest { - t.Skip("skipping live test") - } - - _, err := NewDNSProvider() - assert.NoError(t, err) -} - -func TestDNSProvider_Present(t *testing.T) { +func TestLivePresent(t *testing.T) { if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.Present(testDomain, "", "123d==") - assert.NoError(t, err) + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) } -func TestDNSProvider_CleanUp(t *testing.T) { +func TestLiveCleanUp(t *testing.T) { if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - err = provider.CleanUp(testDomain, "", "123d==") - assert.NoError(t, err) + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) } diff --git a/providers/dns/lightsail/lightsail_integration_test.go b/providers/dns/lightsail/lightsail_integration_test.go index b81e1a55..729cc900 100644 --- a/providers/dns/lightsail/lightsail_integration_test.go +++ b/providers/dns/lightsail/lightsail_integration_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestLightsailTTL(t *testing.T) { +func TestLiveTTL(t *testing.T) { m, err := testGetAndPreCheck() if err != nil { t.Skip(err.Error()) @@ -20,14 +20,14 @@ func TestLightsailTTL(t *testing.T) { provider, err := NewDNSProvider() require.NoError(t, err) - lightsailDomain := m["lightsailDomain"] + domain := m["lightsailDomain"] - err = provider.Present(lightsailDomain, "foo", "bar") + err = provider.Present(domain, "foo", "bar") require.NoError(t, err) - // we need a separate Lightshail client here as the one in the DNS provider is + // we need a separate Lightsail client here as the one in the DNS provider is // unexported. - fqdn := "_acme-challenge." + lightsailDomain + fqdn := "_acme-challenge." + domain sess, err := session.NewSession() require.NoError(t, err) @@ -35,14 +35,14 @@ func TestLightsailTTL(t *testing.T) { require.NoError(t, err) defer func() { - errC := provider.CleanUp(lightsailDomain, "foo", "bar") + errC := provider.CleanUp(domain, "foo", "bar") if errC != nil { t.Log(errC) } }() params := &lightsail.GetDomainInput{ - DomainName: aws.String(lightsailDomain), + DomainName: aws.String(domain), } resp, err := svc.GetDomain(params) @@ -55,7 +55,7 @@ func TestLightsailTTL(t *testing.T) { } } - t.Fatalf("Could not find a TXT record for _acme-challenge.%s", lightsailDomain) + t.Fatalf("Could not find a TXT record for _acme-challenge.%s", domain) } func testGetAndPreCheck() (map[string]string, error) { diff --git a/providers/dns/lightsail/lightsail_test.go b/providers/dns/lightsail/lightsail_test.go index cf0ca84e..da53257c 100644 --- a/providers/dns/lightsail/lightsail_test.go +++ b/providers/dns/lightsail/lightsail_test.go @@ -13,24 +13,24 @@ import ( ) var ( - lightsailSecret string - lightsailKey string - lightsailZone string + envTestSecret string + envTestKey string + envTestZone string ) func init() { - lightsailKey = os.Getenv("AWS_ACCESS_KEY_ID") - lightsailSecret = os.Getenv("AWS_SECRET_ACCESS_KEY") + envTestKey = os.Getenv("AWS_ACCESS_KEY_ID") + envTestSecret = os.Getenv("AWS_SECRET_ACCESS_KEY") } func restoreEnv() { - os.Setenv("AWS_ACCESS_KEY_ID", lightsailKey) - os.Setenv("AWS_SECRET_ACCESS_KEY", lightsailSecret) + os.Setenv("AWS_ACCESS_KEY_ID", envTestKey) + os.Setenv("AWS_SECRET_ACCESS_KEY", envTestSecret) os.Setenv("AWS_REGION", "us-east-1") - os.Setenv("AWS_HOSTED_ZONE_ID", lightsailZone) + os.Setenv("AWS_HOSTED_ZONE_ID", envTestZone) } -func makeLightsailProvider(ts *httptest.Server) (*DNSProvider, error) { +func makeProvider(ts *httptest.Server) (*DNSProvider, error) { config := &aws.Config{ Credentials: credentials.NewStaticCredentials("abc", "123", " "), Endpoint: aws.String(ts.URL), @@ -66,7 +66,7 @@ func TestCredentialsFromEnv(t *testing.T) { require.NoError(t, err, "Expected credentials to be set from environment") } -func TestLightsailPresent(t *testing.T) { +func TestDNSProvider_Present(t *testing.T) { mockResponses := map[string]MockResponse{ "/": {StatusCode: 200, Body: ""}, } @@ -74,7 +74,7 @@ func TestLightsailPresent(t *testing.T) { ts := newMockServer(t, mockResponses) defer ts.Close() - provider, err := makeLightsailProvider(ts) + provider, err := makeProvider(ts) require.NoError(t, err) domain := "example.com" diff --git a/providers/dns/linode/linode_test.go b/providers/dns/linode/linode_test.go index 702da864..1b9d9365 100644 --- a/providers/dns/linode/linode_test.go +++ b/providers/dns/linode/linode_test.go @@ -16,7 +16,7 @@ import ( ) type ( - LinodeResponse struct { + apiResponse struct { Action string `json:"ACTION"` Data interface{} `json:"DATA"` Errors []linode.ResponseError `json:"ERRORARRAY"` @@ -29,38 +29,41 @@ type ( ) var ( - apiKey string - isTestLive bool + apiKey string + liveTest bool ) func init() { apiKey = os.Getenv("LINODE_API_KEY") - isTestLive = len(apiKey) != 0 + + liveTest = len(apiKey) != 0 } func restoreEnv() { os.Setenv("LINODE_API_KEY", apiKey) } -func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server { +func newMockServer(responses MockResponseMap) *httptest.Server { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Ensure that we support the requested action. action := r.URL.Query().Get("api_action") resp, ok := responses[action] if !ok { - require.FailNowf(t, "Unsupported mock action: %q", action) + http.Error(w, fmt.Sprintf("Unsupported mock action: %q", action), http.StatusInternalServerError) + return } // Build the response that the server will return. - linodeResponse := LinodeResponse{ + response := apiResponse{ Action: action, Data: resp.Response, Errors: resp.Errors, } - rawResponse, err := json.Marshal(linodeResponse) + + rawResponse, err := json.Marshal(response) if err != nil { - msg := fmt.Sprintf("Failed to JSON encode response: %v", err) - require.FailNow(t, msg) + http.Error(w, fmt.Sprintf("Failed to JSON encode response: %v", err), http.StatusInternalServerError) + return } // Send the response. @@ -77,35 +80,88 @@ func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server { return srv } -func TestNewDNSProviderWithEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("LINODE_API_KEY", "testing") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "LINODE_API_KEY": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "LINODE_API_KEY": "", + }, + expected: "linode: some credentials information are missing: LINODE_API_KEY", + }, + } - _, err := NewDNSProvider() - require.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderWithoutEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("LINODE_API_KEY", "") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + }, + { + desc: "missing credentials", + expected: "linode: credentials missing", + }, + } - _, err := NewDNSProvider() - assert.EqualError(t, err, "linode: some credentials information are missing: LINODE_API_KEY") -} + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("LINODE_API_KEY") -func TestNewDNSProviderWithKey(t *testing.T) { - config := NewDefaultConfig() - config.APIKey = "testing" + config := NewDefaultConfig() + config.APIKey = test.apiKey - _, err := NewDNSProviderConfig(config) - require.NoError(t, err) -} + p, err := NewDNSProviderConfig(config) -func TestNewDNSProviderWithoutKey(t *testing.T) { - config := NewDefaultConfig() - - _, err := NewDNSProviderConfig(config) - assert.EqualError(t, err, "linode: credentials missing") + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func TestDNSProvider_Present(t *testing.T) { @@ -180,11 +236,10 @@ func TestDNSProvider_Present(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { + server := newMockServer(test.mockResponses) + defer server.Close() - mockSrv := newMockServer(t, test.mockResponses) - defer mockSrv.Close() - - p.client.ToLinode().SetEndpoint(mockSrv.URL) + p.client.ToLinode().SetEndpoint(server.URL) err = p.Present(domain, "", keyAuth) if len(test.expectedError) == 0 { @@ -196,13 +251,6 @@ func TestDNSProvider_Present(t *testing.T) { } } -func TestDNSProvider_PresentLive(t *testing.T) { - if !isTestLive { - t.Skip("Skipping live test") - } - // TODO implement this test -} - func TestDNSProvider_CleanUp(t *testing.T) { defer restoreEnv() os.Setenv("LINODE_API_KEY", "testing") @@ -299,10 +347,10 @@ func TestDNSProvider_CleanUp(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - mockSrv := newMockServer(t, test.mockResponses) - defer mockSrv.Close() + server := newMockServer(test.mockResponses) + defer server.Close() - p.client.ToLinode().SetEndpoint(mockSrv.URL) + p.client.ToLinode().SetEndpoint(server.URL) err = p.CleanUp(domain, "", keyAuth) if len(test.expectedError) == 0 { @@ -313,3 +361,17 @@ func TestDNSProvider_CleanUp(t *testing.T) { }) } } + +func TestLivePresent(t *testing.T) { + if !liveTest { + t.Skip("Skipping live test") + } + // TODO implement this test +} + +func TestLiveCleanUp(t *testing.T) { + if !liveTest { + t.Skip("Skipping live test") + } + // TODO implement this test +} diff --git a/providers/dns/linodev4/linodev4_test.go b/providers/dns/linodev4/linodev4_test.go index 4f0bd16e..ab88de64 100644 --- a/providers/dns/linodev4/linodev4_test.go +++ b/providers/dns/linodev4/linodev4_test.go @@ -19,32 +19,34 @@ type ( ) var ( - apiToken string - isTestLive bool + liveTest bool + envTestAPIToken string ) func init() { - apiToken = os.Getenv("LINODE_TOKEN") - isTestLive = len(apiToken) != 0 + envTestAPIToken = os.Getenv("LINODE_TOKEN") + + liveTest = len(envTestAPIToken) != 0 } func restoreEnv() { - os.Setenv("LINODE_TOKEN", apiToken) + os.Setenv("LINODE_TOKEN", envTestAPIToken) } -func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server { +func newMockServer(responses MockResponseMap) *httptest.Server { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Ensure that we support the requested action. action := r.Method + ":" + r.URL.Path resp, ok := responses[action] if !ok { - require.FailNowf(t, "Unsupported mock", "action: %s", action) + http.Error(w, fmt.Sprintf("Unsupported mock action: %q", action), http.StatusInternalServerError) + return } rawResponse, err := json.Marshal(resp) if err != nil { - msg := fmt.Sprintf("Failed to JSON encode response: %v", err) - require.FailNow(t, msg) + http.Error(w, fmt.Sprintf("Failed to JSON encode response: %v", err), http.StatusInternalServerError) + return } // Send the response. @@ -69,36 +71,88 @@ func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server { return srv } -func TestNewDNSProviderWithEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("LINODE_TOKEN", "testing") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "LINODE_TOKEN": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "LINODE_TOKEN": "", + }, + expected: "linodev4: some credentials information are missing: LINODE_TOKEN", + }, + } - _, err := NewDNSProvider() - assert.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderWithoutEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("LINODE_TOKEN", "") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + }, + { + desc: "missing credentials", + expected: "linodev4: Linode Access Token missing", + }, + } - _, err := NewDNSProvider() - assert.EqualError(t, err, "linodev4: some credentials information are missing: LINODE_TOKEN") -} + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("LINODE_TOKEN") -func TestNewDNSProviderWithKey(t *testing.T) { - config := NewDefaultConfig() - config.Token = "testing" + config := NewDefaultConfig() + config.Token = test.apiKey - _, err := NewDNSProviderConfig(config) - assert.NoError(t, err) -} + p, err := NewDNSProviderConfig(config) -func TestNewDNSProviderWithoutKey(t *testing.T) { - config := NewDefaultConfig() - config.Token = "" - - _, err := NewDNSProviderConfig(config) - assert.EqualError(t, err, "linodev4: Linode Access Token missing") + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func TestDNSProvider_Present(t *testing.T) { @@ -175,11 +229,11 @@ func TestDNSProvider_Present(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - mockSrv := newMockServer(t, test.mockResponses) - defer mockSrv.Close() + server := newMockServer(test.mockResponses) + defer server.Close() assert.NotNil(t, p.client) - p.client.SetBaseURL(mockSrv.URL) + p.client.SetBaseURL(server.URL) err = p.Present(domain, "", keyAuth) if len(test.expectedError) == 0 { @@ -191,13 +245,6 @@ func TestDNSProvider_Present(t *testing.T) { } } -func TestDNSProvider_PresentLive(t *testing.T) { - if !isTestLive { - t.Skip("Skipping live test") - } - // TODO implement this test -} - func TestDNSProvider_CleanUp(t *testing.T) { defer restoreEnv() os.Setenv("LINODE_TOKEN", "testing") @@ -298,10 +345,10 @@ func TestDNSProvider_CleanUp(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - mockSrv := newMockServer(t, test.mockResponses) - defer mockSrv.Close() + server := newMockServer(test.mockResponses) + defer server.Close() - p.client.SetBaseURL(mockSrv.URL) + p.client.SetBaseURL(server.URL) err = p.CleanUp(domain, "", keyAuth) if len(test.expectedError) == 0 { @@ -312,3 +359,17 @@ func TestDNSProvider_CleanUp(t *testing.T) { }) } } + +func TestLivePresent(t *testing.T) { + if !liveTest { + t.Skip("Skipping live test") + } + // TODO implement this test +} + +func TestLiveCleanUp(t *testing.T) { + if !liveTest { + t.Skip("Skipping live test") + } + // TODO implement this test +} diff --git a/providers/dns/namecheap/namecheap_test.go b/providers/dns/namecheap/namecheap_test.go index f5f00134..f3fd0705 100644 --- a/providers/dns/namecheap/namecheap_test.go +++ b/providers/dns/namecheap/namecheap_test.go @@ -13,9 +13,9 @@ import ( ) var ( - fakeUser = "foo" - fakeKey = "bar" - fakeClientIP = "10.0.0.1" + envTestUser = "foo" + envTestKey = "bar" + envTestClientIP = "10.0.0.1" tlds = map[string]string{ "com.au": "com.au", @@ -28,24 +28,13 @@ var ( } ) -func TestGetHosts(t *testing.T) { +func TestDNSProvider_getHosts(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - mock := httptest.NewServer(http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - mockServer(&test, t, w, r) - })) + mock := httptest.NewServer(mockServer(&test, t)) defer mock.Close() - config := NewDefaultConfig() - config.BaseURL = mock.URL - config.APIUser = fakeUser - config.APIKey = fakeKey - config.ClientIP = fakeClientIP - config.HTTPClient = &http.Client{Timeout: 60 * time.Second} - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) + provider := mockDNSProvider(mock.URL) ch, err := newChallenge(test.domain, "", tlds) require.NoError(t, err) @@ -80,13 +69,10 @@ func TestGetHosts(t *testing.T) { } } -func TestSetHosts(t *testing.T) { +func TestDNSProvider_setHosts(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - mock := httptest.NewServer(http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - mockServer(&test, t, w, r) - })) + mock := httptest.NewServer(mockServer(&test, t)) defer mock.Close() prov := mockDNSProvider(mock.URL) @@ -110,13 +96,10 @@ func TestSetHosts(t *testing.T) { } } -func TestPresent(t *testing.T) { +func TestDNSProvider_Present(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - mock := httptest.NewServer(http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - mockServer(&test, t, w, r) - })) + mock := httptest.NewServer(mockServer(&test, t)) defer mock.Close() prov := mockDNSProvider(mock.URL) @@ -130,13 +113,10 @@ func TestPresent(t *testing.T) { } } -func TestCleanUp(t *testing.T) { +func TestDNSProvider_CleanUp(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - mock := httptest.NewServer(http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - mockServer(&test, t, w, r) - })) + mock := httptest.NewServer(mockServer(&test, t)) defer mock.Close() prov := mockDNSProvider(mock.URL) @@ -210,60 +190,61 @@ func assertEq(t *testing.T, variable, got, want string) { func assertHdr(tc *testCase, t *testing.T, values *url.Values) { ch, _ := newChallenge(tc.domain, "", tlds) - assertEq(t, "ApiUser", values.Get("ApiUser"), fakeUser) - assertEq(t, "ApiKey", values.Get("ApiKey"), fakeKey) - assertEq(t, "UserName", values.Get("UserName"), fakeUser) - assertEq(t, "ClientIp", values.Get("ClientIp"), fakeClientIP) + assertEq(t, "ApiUser", values.Get("ApiUser"), envTestUser) + assertEq(t, "ApiKey", values.Get("ApiKey"), envTestKey) + assertEq(t, "UserName", values.Get("UserName"), envTestUser) + assertEq(t, "ClientIp", values.Get("ClientIp"), envTestClientIP) assertEq(t, "SLD", values.Get("SLD"), ch.sld) assertEq(t, "TLD", values.Get("TLD"), ch.tld) } -func mockServer(tc *testCase, t *testing.T, w http.ResponseWriter, r *http.Request) { - switch r.Method { +func mockServer(tc *testCase, t *testing.T) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + values := r.URL.Query() + cmd := values.Get("Command") + switch cmd { + case "namecheap.domains.dns.getHosts": + assertHdr(tc, t, &values) + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, tc.getHostsResponse) + case "namecheap.domains.getTldList": + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, responseGetTlds) + default: + t.Errorf("Unexpected GET command: %s", cmd) + } + + case http.MethodPost: + err := r.ParseForm() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + values := r.Form + cmd := values.Get("Command") + switch cmd { + case "namecheap.domains.dns.setHosts": + assertHdr(tc, t, &values) + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, tc.setHostsResponse) + default: + t.Errorf("Unexpected POST command: %s", cmd) + } - case http.MethodGet: - values := r.URL.Query() - cmd := values.Get("Command") - switch cmd { - case "namecheap.domains.dns.getHosts": - assertHdr(tc, t, &values) - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, tc.getHostsResponse) - case "namecheap.domains.getTldList": - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, responseGetTlds) default: - t.Errorf("Unexpected GET command: %s", cmd) + t.Errorf("Unexpected http method: %s", r.Method) } - - case http.MethodPost: - err := r.ParseForm() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - values := r.Form - cmd := values.Get("Command") - switch cmd { - case "namecheap.domains.dns.setHosts": - assertHdr(tc, t, &values) - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, tc.setHostsResponse) - default: - t.Errorf("Unexpected POST command: %s", cmd) - } - - default: - t.Errorf("Unexpected http method: %s", r.Method) - } + }) } func mockDNSProvider(url string) *DNSProvider { config := NewDefaultConfig() config.BaseURL = url - config.APIUser = fakeUser - config.APIKey = fakeKey - config.ClientIP = fakeClientIP + config.APIUser = envTestUser + config.APIKey = envTestKey + config.ClientIP = envTestClientIP config.HTTPClient = &http.Client{Timeout: 60 * time.Second} provider, err := NewDNSProviderConfig(config) diff --git a/providers/dns/namedotcom/namedotcom_test.go b/providers/dns/namedotcom/namedotcom_test.go index 85a0d117..144aa2ed 100644 --- a/providers/dns/namedotcom/namedotcom_test.go +++ b/providers/dns/namedotcom/namedotcom_test.go @@ -9,60 +9,169 @@ import ( ) var ( - namedotcomLiveTest bool - namedotcomUsername string - namedotcomAPIToken string - namedotcomDomain string - namedotcomServer string + liveTest bool + envTestUsername string + envTestAPIToken string + envTestDomain string ) func init() { - namedotcomUsername = os.Getenv("NAMEDOTCOM_USERNAME") - namedotcomAPIToken = os.Getenv("NAMEDOTCOM_API_TOKEN") - namedotcomDomain = os.Getenv("NAMEDOTCOM_DOMAIN") - namedotcomServer = os.Getenv("NAMEDOTCOM_SERVER") + envTestUsername = os.Getenv("NAMECOM_USERNAME") + envTestAPIToken = os.Getenv("NAMECOM_API_TOKEN") + envTestDomain = os.Getenv("NAMEDOTCOM_DOMAIN") - if len(namedotcomAPIToken) > 0 && len(namedotcomUsername) > 0 && len(namedotcomDomain) > 0 { - namedotcomLiveTest = true + if len(envTestAPIToken) > 0 && len(envTestUsername) > 0 && len(envTestDomain) > 0 { + liveTest = true } } -func TestLiveNamedotcomPresent(t *testing.T) { - if !namedotcomLiveTest { +func restoreEnv() { + os.Setenv("NAMECOM_USERNAME", envTestUsername) + os.Setenv("NAMECOM_API_TOKEN", envTestAPIToken) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "NAMECOM_USERNAME": "A", + "NAMECOM_API_TOKEN": "B", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "NAMECOM_USERNAME": "", + "NAMECOM_API_TOKEN": "", + }, + expected: "namedotcom: some credentials information are missing: NAMECOM_USERNAME,NAMECOM_API_TOKEN", + }, + { + desc: "missing username", + envVars: map[string]string{ + "NAMECOM_USERNAME": "", + "NAMECOM_API_TOKEN": "B", + }, + expected: "namedotcom: some credentials information are missing: NAMECOM_USERNAME", + }, + { + desc: "missing api token", + envVars: map[string]string{ + "NAMECOM_USERNAME": "A", + "NAMECOM_API_TOKEN": "", + }, + expected: "namedotcom: some credentials information are missing: NAMECOM_API_TOKEN", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiToken string + username string + expected string + }{ + { + desc: "success", + apiToken: "A", + username: "B", + }, + { + desc: "missing credentials", + expected: "namedotcom: username is required", + }, + { + desc: "missing API token", + apiToken: "", + username: "B", + expected: "namedotcom: API token is required", + }, + { + desc: "missing username", + apiToken: "A", + username: "", + expected: "namedotcom: username is required", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("NAMECOM_USERNAME") + os.Unsetenv("NAMECOM_API_TOKEN") + + config := NewDefaultConfig() + config.Username = test.username + config.APIToken = test.apiToken + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.Username = namedotcomUsername - config.APIToken = namedotcomAPIToken - config.Server = namedotcomServer - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(namedotcomDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -// -// Cleanup -// - -func TestLiveNamedotcomCleanUp(t *testing.T) { - if !namedotcomLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - - config := NewDefaultConfig() - config.Username = namedotcomUsername - config.APIToken = namedotcomAPIToken - config.Server = namedotcomServer - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(namedotcomDomain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/netcup/client_test.go b/providers/dns/netcup/client_test.go index cba491b0..8b6cdc4f 100644 --- a/providers/dns/netcup/client_test.go +++ b/providers/dns/netcup/client_test.go @@ -6,16 +6,17 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/xenolf/lego/acme" ) -func TestClientAuth(t *testing.T) { - if !testLive { +func TestLiveClientAuth(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } // Setup - client := NewClient(testCustomerNumber, testAPIKey, testAPIPassword) + client := NewClient(envTestCustomerNumber, envTestAPIKey, envTestAPIPassword) for i := 1; i < 4; i++ { i := i @@ -23,57 +24,57 @@ func TestClientAuth(t *testing.T) { t.Parallel() sessionID, err := client.Login() - assert.NoError(t, err) + require.NoError(t, err) err = client.Logout(sessionID) - assert.NoError(t, err) + require.NoError(t, err) }) } } -func TestClientGetDnsRecords(t *testing.T) { - if !testLive { +func TestLiveClientGetDnsRecords(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - client := NewClient(testCustomerNumber, testAPIKey, testAPIPassword) + client := NewClient(envTestCustomerNumber, envTestAPIKey, envTestAPIPassword) // Setup sessionID, err := client.Login() - assert.NoError(t, err) + require.NoError(t, err) - fqdn, _, _ := acme.DNS01Record(testDomain, "123d==") + fqdn, _, _ := acme.DNS01Record(envTestDomain, "123d==") zone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers) - assert.NoError(t, err, "error finding DNSZone") + require.NoError(t, err, "error finding DNSZone") zone = acme.UnFqdn(zone) // TestMethod _, err = client.GetDNSRecords(zone, sessionID) - assert.NoError(t, err) + require.NoError(t, err) // Tear down err = client.Logout(sessionID) - assert.NoError(t, err) + require.NoError(t, err) } -func TestClientUpdateDnsRecord(t *testing.T) { - if !testLive { +func TestLiveClientUpdateDnsRecord(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } // Setup - client := NewClient(testCustomerNumber, testAPIKey, testAPIPassword) + client := NewClient(envTestCustomerNumber, envTestAPIKey, envTestAPIPassword) sessionID, err := client.Login() - assert.NoError(t, err) + require.NoError(t, err) - fqdn, _, _ := acme.DNS01Record(testDomain, "123d==") + fqdn, _, _ := acme.DNS01Record(envTestDomain, "123d==") zone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers) - assert.NoError(t, err, fmt.Errorf("error finding DNSZone, %v", err)) + require.NoError(t, err, fmt.Errorf("error finding DNSZone, %v", err)) hostname := strings.Replace(fqdn, "."+zone, "", 1) @@ -83,13 +84,13 @@ func TestClientUpdateDnsRecord(t *testing.T) { zone = acme.UnFqdn(zone) err = client.UpdateDNSRecord(sessionID, zone, record) - assert.NoError(t, err) + require.NoError(t, err) records, err := client.GetDNSRecords(zone, sessionID) - assert.NoError(t, err) + require.NoError(t, err) recordIdx, err := GetDNSRecordIdx(records, record) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, record.Hostname, records[recordIdx].Hostname) assert.Equal(t, record.RecordType, records[recordIdx].RecordType) @@ -99,11 +100,11 @@ func TestClientUpdateDnsRecord(t *testing.T) { records[recordIdx].DeleteRecord = true // Tear down - err = client.UpdateDNSRecord(sessionID, testDomain, records[recordIdx]) - assert.NoError(t, err, "Did not remove record! Please do so yourself.") + err = client.UpdateDNSRecord(sessionID, envTestDomain, records[recordIdx]) + require.NoError(t, err, "Did not remove record! Please do so yourself.") err = client.Logout(sessionID) - assert.NoError(t, err) + require.NoError(t, err) } func TestClientGetDnsRecordIdx(t *testing.T) { diff --git a/providers/dns/netcup/netcup_test.go b/providers/dns/netcup/netcup_test.go index 1c8c1b8a..4460e0ca 100644 --- a/providers/dns/netcup/netcup_test.go +++ b/providers/dns/netcup/netcup_test.go @@ -5,41 +5,192 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/xenolf/lego/acme" ) var ( - testLive bool - testCustomerNumber string - testAPIKey string - testAPIPassword string - testDomain string + liveTest bool + envTestCustomerNumber string + envTestAPIKey string + envTestAPIPassword string + envTestDomain string ) func init() { - testCustomerNumber = os.Getenv("NETCUP_CUSTOMER_NUMBER") - testAPIKey = os.Getenv("NETCUP_API_KEY") - testAPIPassword = os.Getenv("NETCUP_API_PASSWORD") - testDomain = os.Getenv("NETCUP_DOMAIN") + envTestCustomerNumber = os.Getenv("NETCUP_CUSTOMER_NUMBER") + envTestAPIKey = os.Getenv("NETCUP_API_KEY") + envTestAPIPassword = os.Getenv("NETCUP_API_PASSWORD") + envTestDomain = os.Getenv("NETCUP_DOMAIN") - if len(testCustomerNumber) > 0 && len(testAPIKey) > 0 && len(testAPIPassword) > 0 && len(testDomain) > 0 { - testLive = true + if len(envTestCustomerNumber) > 0 && len(envTestAPIKey) > 0 && len(envTestAPIPassword) > 0 && len(envTestDomain) > 0 { + liveTest = true } } -func TestDNSProviderPresentAndCleanup(t *testing.T) { - if !testLive { +func restoreEnv() { + os.Setenv("NETCUP_CUSTOMER_NUMBER", envTestCustomerNumber) + os.Setenv("NETCUP_API_KEY", envTestAPIKey) + os.Setenv("NETCUP_API_PASSWORD", envTestAPIPassword) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "NETCUP_CUSTOMER_NUMBER": "A", + "NETCUP_API_KEY": "B", + "NETCUP_API_PASSWORD": "C", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "NETCUP_CUSTOMER_NUMBER": "", + "NETCUP_API_KEY": "", + "NETCUP_API_PASSWORD": "", + }, + expected: "netcup: some credentials information are missing: NETCUP_CUSTOMER_NUMBER,NETCUP_API_KEY,NETCUP_API_PASSWORD", + }, + { + desc: "missing customer number", + envVars: map[string]string{ + "NETCUP_CUSTOMER_NUMBER": "", + "NETCUP_API_KEY": "B", + "NETCUP_API_PASSWORD": "C", + }, + expected: "netcup: some credentials information are missing: NETCUP_CUSTOMER_NUMBER", + }, + { + desc: "missing API key", + envVars: map[string]string{ + "NETCUP_CUSTOMER_NUMBER": "A", + "NETCUP_API_KEY": "", + "NETCUP_API_PASSWORD": "C", + }, + expected: "netcup: some credentials information are missing: NETCUP_API_KEY", + }, + { + desc: "missing api password", + envVars: map[string]string{ + "NETCUP_CUSTOMER_NUMBER": "A", + "NETCUP_API_KEY": "B", + "NETCUP_API_PASSWORD": "", + }, + expected: "netcup: some credentials information are missing: NETCUP_API_PASSWORD", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + customer string + key string + password string + expected string + }{ + { + desc: "success", + customer: "A", + key: "B", + password: "C", + }, + { + desc: "missing credentials", + expected: "netcup: netcup credentials missing", + }, + { + desc: "missing customer", + customer: "", + key: "B", + password: "C", + expected: "netcup: netcup credentials missing", + }, + { + desc: "missing key", + customer: "A", + key: "", + password: "C", + expected: "netcup: netcup credentials missing", + }, + { + desc: "missing password", + customer: "A", + key: "B", + password: "", + expected: "netcup: netcup credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("NETCUP_CUSTOMER_NUMBER") + os.Unsetenv("NETCUP_API_KEY") + os.Unsetenv("NETCUP_API_PASSWORD") + + config := NewDefaultConfig() + config.Customer = test.customer + config.Key = test.key + config.Password = test.password + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresentAndCleanup(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() p, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) - fqdn, _, _ := acme.DNS01Record(testDomain, "123d==") + fqdn, _, _ := acme.DNS01Record(envTestDomain, "123d==") zone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers) - assert.NoError(t, err, "error finding DNSZone") + require.NoError(t, err, "error finding DNSZone") zone = acme.UnFqdn(zone) @@ -53,10 +204,10 @@ func TestDNSProviderPresentAndCleanup(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("domain(%s)", tc), func(t *testing.T) { err = p.Present(tc, "987d", "123d==") - assert.NoError(t, err) + require.NoError(t, err) err = p.CleanUp(tc, "987d", "123d==") - assert.NoError(t, err, "Did not clean up! Please remove record yourself.") + require.NoError(t, err, "Did not clean up! Please remove record yourself.") }) } } diff --git a/providers/dns/nifcloud/client.go b/providers/dns/nifcloud/client.go index dc10cbc2..24a8f52b 100644 --- a/providers/dns/nifcloud/client.go +++ b/providers/dns/nifcloud/client.go @@ -89,13 +89,17 @@ type ChangeInfo struct { } // NewClient Creates a new client of NIFCLOUD DNS -func NewClient(accessKey string, secretKey string) *Client { +func NewClient(accessKey string, secretKey string) (*Client, error) { + if len(accessKey) == 0 || len(secretKey) == 0 { + return nil, errors.New("credentials missing") + } + return &Client{ accessKey: accessKey, secretKey: secretKey, BaseURL: defaultBaseURL, HTTPClient: &http.Client{}, - } + }, nil } // Client client of NIFCLOUD DNS diff --git a/providers/dns/nifcloud/client_test.go b/providers/dns/nifcloud/client_test.go index e56ccd37..f940c4ee 100644 --- a/providers/dns/nifcloud/client_test.go +++ b/providers/dns/nifcloud/client_test.go @@ -31,7 +31,9 @@ func TestChangeResourceRecordSets(t *testing.T) { server := runTestServer(responseBody, http.StatusOK) defer server.Close() - client := NewClient("", "") + client, err := NewClient("A", "B") + require.NoError(t, err) + client.BaseURL = server.URL res, err := client.ChangeResourceRecordSets("example.com", ChangeResourceRecordSetsRequest{}) @@ -83,7 +85,9 @@ func TestChangeResourceRecordSetsErrors(t *testing.T) { server := runTestServer(test.responseBody, test.statusCode) defer server.Close() - client := NewClient("", "") + client, err := NewClient("A", "B") + require.NoError(t, err) + client.BaseURL = server.URL res, err := client.ChangeResourceRecordSets("example.com", ChangeResourceRecordSetsRequest{}) @@ -107,7 +111,9 @@ func TestGetChange(t *testing.T) { server := runTestServer(responseBody, http.StatusOK) defer server.Close() - client := NewClient("", "") + client, err := NewClient("A", "B") + require.NoError(t, err) + client.BaseURL = server.URL res, err := client.GetChange("12345") @@ -159,7 +165,9 @@ func TestGetChangeErrors(t *testing.T) { server := runTestServer(test.responseBody, test.statusCode) defer server.Close() - client := NewClient("", "") + client, err := NewClient("A", "B") + require.NoError(t, err) + client.BaseURL = server.URL res, err := client.GetChange("12345") diff --git a/providers/dns/nifcloud/nifcloud.go b/providers/dns/nifcloud/nifcloud.go index 6021cd51..c8cf0484 100644 --- a/providers/dns/nifcloud/nifcloud.go +++ b/providers/dns/nifcloud/nifcloud.go @@ -77,7 +77,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("nifcloud: the configuration of the DNS provider is nil") } - client := NewClient(config.AccessKey, config.SecretKey) + client, err := NewClient(config.AccessKey, config.SecretKey) + if err != nil { + return nil, fmt.Errorf("nifcloud: %v", err) + } if config.HTTPClient != nil { client.HTTPClient = config.HTTPClient diff --git a/providers/dns/nifcloud/nifcloud_test.go b/providers/dns/nifcloud/nifcloud_test.go index f82b5bd6..d6602b88 100644 --- a/providers/dns/nifcloud/nifcloud_test.go +++ b/providers/dns/nifcloud/nifcloud_test.go @@ -9,44 +9,167 @@ import ( ) var ( - nifcloudLiveTest bool - nifcloudAccessKey string - nifcloudSecretKey string - nifcloudDomain string + liveTest bool + envTestAccessKey string + envTestSecretKey string + envTestDomain string ) func init() { - nifcloudAccessKey = os.Getenv("NIFCLOUD_ACCESS_KEY_ID") - nifcloudSecretKey = os.Getenv("NIFCLOUD_SECRET_ACCESS_KEY") - nifcloudDomain = os.Getenv("NIFCLOUD_DOMAIN") + envTestAccessKey = os.Getenv("NIFCLOUD_ACCESS_KEY_ID") + envTestSecretKey = os.Getenv("NIFCLOUD_SECRET_ACCESS_KEY") + envTestDomain = os.Getenv("NIFCLOUD_DOMAIN") - if len(nifcloudAccessKey) > 0 && len(nifcloudSecretKey) > 0 && len(nifcloudDomain) > 0 { - nifcloudLiveTest = true + if len(envTestAccessKey) > 0 && len(envTestSecretKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } -func TestLivenifcloudPresent(t *testing.T) { - if !nifcloudLiveTest { +func restoreEnv() { + os.Setenv("NIFCLOUD_ACCESS_KEY_ID", envTestAccessKey) + os.Setenv("NIFCLOUD_SECRET_ACCESS_KEY", envTestSecretKey) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "NIFCLOUD_ACCESS_KEY_ID": "123", + "NIFCLOUD_SECRET_ACCESS_KEY": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "NIFCLOUD_ACCESS_KEY_ID": "", + "NIFCLOUD_SECRET_ACCESS_KEY": "", + }, + expected: "nifcloud: some credentials information are missing: NIFCLOUD_ACCESS_KEY_ID,NIFCLOUD_SECRET_ACCESS_KEY", + }, + { + desc: "missing access key", + envVars: map[string]string{ + "NIFCLOUD_ACCESS_KEY_ID": "", + "NIFCLOUD_SECRET_ACCESS_KEY": "456", + }, + expected: "nifcloud: some credentials information are missing: NIFCLOUD_ACCESS_KEY_ID", + }, + { + desc: "missing secret key", + envVars: map[string]string{ + "NIFCLOUD_ACCESS_KEY_ID": "123", + "NIFCLOUD_SECRET_ACCESS_KEY": "", + }, + expected: "nifcloud: some credentials information are missing: NIFCLOUD_SECRET_ACCESS_KEY", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + accessKey string + secretKey string + expected string + }{ + { + desc: "success", + accessKey: "123", + secretKey: "456", + }, + { + desc: "missing credentials", + expected: "nifcloud: credentials missing", + }, + { + desc: "missing api key", + secretKey: "456", + expected: "nifcloud: credentials missing", + }, + { + desc: "missing secret key", + accessKey: "123", + expected: "nifcloud: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("NIFCLOUD_ACCESS_KEY_ID") + os.Unsetenv("NIFCLOUD_SECRET_ACCESS_KEY") + + config := NewDefaultConfig() + config.AccessKey = test.accessKey + config.SecretKey = test.secretKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(nifcloudDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -func TestLivenifcloudCleanUp(t *testing.T) { - if !nifcloudLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(nifcloudDomain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/ns1/ns1_test.go b/providers/dns/ns1/ns1_test.go index c40cc736..f1889ae5 100644 --- a/providers/dns/ns1/ns1_test.go +++ b/providers/dns/ns1/ns1_test.go @@ -10,21 +10,105 @@ import ( ) var ( - liveTest bool - apiKey string - domain string + liveTest bool + envTestAPIKey string + envTestDomain string ) func init() { - apiKey = os.Getenv("NS1_API_KEY") - domain = os.Getenv("NS1_DOMAIN") - if len(apiKey) > 0 && len(domain) > 0 { + envTestAPIKey = os.Getenv("NS1_API_KEY") + envTestDomain = os.Getenv("NS1_DOMAIN") + if len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { liveTest = true } } func restoreEnv() { - os.Setenv("NS1_API_KEY", apiKey) + os.Setenv("NS1_API_KEY", envTestAPIKey) +} + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "NS1_API_KEY": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "NS1_API_KEY": "", + }, + expected: "ns1: some credentials information are missing: NS1_API_KEY", + }, + } + + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + }, + { + desc: "missing credentials", + expected: "ns1: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("NS1_API_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func Test_getAuthZone(t *testing.T) { @@ -78,37 +162,16 @@ func Test_getAuthZone(t *testing.T) { } } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("NS1_API_KEY", "") - - config := NewDefaultConfig() - config.APIKey = "123" - - _, err := NewDNSProviderConfig(config) - require.NoError(t, err) -} - -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("NS1_API_KEY", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "ns1: some credentials information are missing: NS1_API_KEY") -} - func TestLivePresent(t *testing.T) { if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.APIKey = apiKey - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(domain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } @@ -117,14 +180,12 @@ func TestLiveCleanUp(t *testing.T) { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - - config := NewDefaultConfig() - config.APIKey = apiKey - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(domain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/otc/mock.go b/providers/dns/otc/mock_test.go similarity index 100% rename from providers/dns/otc/mock.go rename to providers/dns/otc/mock_test.go diff --git a/providers/dns/otc/otc_test.go b/providers/dns/otc/otc_test.go index 37a2983b..a83694c0 100644 --- a/providers/dns/otc/otc_test.go +++ b/providers/dns/otc/otc_test.go @@ -6,30 +6,30 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) -type OTCDNSTestSuite struct { +type TestSuite struct { suite.Suite Mock *DNSMock } -func (s *OTCDNSTestSuite) TearDownSuite() { +func (s *TestSuite) TearDownSuite() { s.Mock.ShutdownServer() } -func (s *OTCDNSTestSuite) SetupTest() { +func (s *TestSuite) SetupTest() { s.Mock = NewDNSMock(s.T()) s.Mock.Setup() s.Mock.HandleAuthSuccessfully() - } -func TestOTCDNSTestSuite(t *testing.T) { - suite.Run(t, new(OTCDNSTestSuite)) +func TestTestSuite(t *testing.T) { + suite.Run(t, new(TestSuite)) } -func (s *OTCDNSTestSuite) createDNSProvider() (*DNSProvider, error) { +func (s *TestSuite) createDNSProvider() (*DNSProvider, error) { url := fmt.Sprintf("%s/v3/auth/token", s.Mock.Server.URL) config := NewDefaultConfig() @@ -42,7 +42,17 @@ func (s *OTCDNSTestSuite) createDNSProvider() (*DNSProvider, error) { return NewDNSProviderConfig(config) } -func (s *OTCDNSTestSuite) TestOTCDNSLoginEnv() { +func (s *TestSuite) TestLogin() { + provider, err := s.createDNSProvider() + require.NoError(s.T(), err) + + err = provider.loginRequest() + require.NoError(s.T(), err) + assert.Equal(s.T(), provider.baseURL, fmt.Sprintf("%s/v2", s.Mock.Server.URL)) + assert.Equal(s.T(), fakeOTCToken, provider.token) +} + +func (s *TestSuite) TestLoginEnv() { defer os.Clearenv() os.Setenv("OTC_DOMAIN_NAME", "unittest1") @@ -52,7 +62,7 @@ func (s *OTCDNSTestSuite) TestOTCDNSLoginEnv() { os.Setenv("OTC_IDENTITY_ENDPOINT", "unittest5") provider, err := NewDNSProvider() - assert.Nil(s.T(), err) + require.NoError(s.T(), err) assert.Equal(s.T(), provider.config.DomainName, "unittest1") assert.Equal(s.T(), provider.config.UserName, "unittest2") assert.Equal(s.T(), provider.config.Password, "unittest3") @@ -62,60 +72,58 @@ func (s *OTCDNSTestSuite) TestOTCDNSLoginEnv() { os.Setenv("OTC_IDENTITY_ENDPOINT", "") provider, err = NewDNSProvider() - assert.Nil(s.T(), err) + require.NoError(s.T(), err) assert.Equal(s.T(), provider.config.IdentityEndpoint, "https://iam.eu-de.otc.t-systems.com:443/v3/auth/tokens") } -func (s *OTCDNSTestSuite) TestOTCDNSLoginEnvEmpty() { +func (s *TestSuite) TestLoginEnvEmpty() { defer os.Clearenv() _, err := NewDNSProvider() assert.EqualError(s.T(), err, "otc: some credentials information are missing: OTC_DOMAIN_NAME,OTC_USER_NAME,OTC_PASSWORD,OTC_PROJECT_NAME") } -func (s *OTCDNSTestSuite) TestOTCDNSLogin() { - otcProvider, err := s.createDNSProvider() +func (s *TestSuite) TestDNSProvider_Present() { + s.Mock.HandleListZonesSuccessfully() + s.Mock.HandleListRecordsetsSuccessfully() - assert.Nil(s.T(), err) - err = otcProvider.loginRequest() - assert.Nil(s.T(), err) - assert.Equal(s.T(), otcProvider.baseURL, fmt.Sprintf("%s/v2", s.Mock.Server.URL)) - assert.Equal(s.T(), fakeOTCToken, otcProvider.token) + provider, err := s.createDNSProvider() + require.NoError(s.T(), err) + + err = provider.Present("example.com", "", "foobar") + require.NoError(s.T(), err) } -func (s *OTCDNSTestSuite) TestOTCDNSEmptyZone() { +func (s *TestSuite) TestDNSProvider_Present_EmptyZone() { s.Mock.HandleListZonesEmpty() s.Mock.HandleListRecordsetsSuccessfully() - otcProvider, _ := s.createDNSProvider() - err := otcProvider.Present("example.com", "", "foobar") + provider, err := s.createDNSProvider() + require.NoError(s.T(), err) + + err = provider.Present("example.com", "", "foobar") assert.NotNil(s.T(), err) } -func (s *OTCDNSTestSuite) TestOTCDNSEmptyRecordset() { - s.Mock.HandleListZonesSuccessfully() - s.Mock.HandleListRecordsetsEmpty() - - otcProvider, _ := s.createDNSProvider() - err := otcProvider.CleanUp("example.com", "", "foobar") - assert.NotNil(s.T(), err) -} - -func (s *OTCDNSTestSuite) TestOTCDNSPresent() { - s.Mock.HandleListZonesSuccessfully() - s.Mock.HandleListRecordsetsSuccessfully() - - otcProvider, _ := s.createDNSProvider() - err := otcProvider.Present("example.com", "", "foobar") - assert.Nil(s.T(), err) -} - -func (s *OTCDNSTestSuite) TestOTCDNSCleanup() { +func (s *TestSuite) TestDNSProvider_CleanUp() { s.Mock.HandleListZonesSuccessfully() s.Mock.HandleListRecordsetsSuccessfully() s.Mock.HandleDeleteRecordsetsSuccessfully() - otcProvider, _ := s.createDNSProvider() - err := otcProvider.CleanUp("example.com", "", "foobar") - assert.Nil(s.T(), err) + provider, err := s.createDNSProvider() + require.NoError(s.T(), err) + + err = provider.CleanUp("example.com", "", "foobar") + require.NoError(s.T(), err) +} + +func (s *TestSuite) TestDNSProvider_CleanUp_EmptyRecordset() { + s.Mock.HandleListZonesSuccessfully() + s.Mock.HandleListRecordsetsEmpty() + + provider, err := s.createDNSProvider() + require.NoError(s.T(), err) + + err = provider.CleanUp("example.com", "", "foobar") + require.Error(s.T(), err) } diff --git a/providers/dns/ovh/ovh_test.go b/providers/dns/ovh/ovh_test.go index 2e6a3c8a..c6af2fe6 100644 --- a/providers/dns/ovh/ovh_test.go +++ b/providers/dns/ovh/ovh_test.go @@ -5,95 +5,52 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - liveTest bool - apiEndpoint string - applicationKey string - applicationSecret string - consumerKey string - domain string + liveTest bool + envTestAPIEndpoint string + envTestApplicationKey string + envTestApplicationSecret string + envTestConsumerKey string + envTestDomain string ) func init() { - apiEndpoint = os.Getenv("OVH_ENDPOINT") - applicationKey = os.Getenv("OVH_APPLICATION_KEY") - applicationSecret = os.Getenv("OVH_APPLICATION_SECRET") - consumerKey = os.Getenv("OVH_CONSUMER_KEY") - liveTest = len(apiEndpoint) > 0 && len(applicationKey) > 0 && len(applicationSecret) > 0 && len(consumerKey) > 0 + envTestAPIEndpoint = os.Getenv("OVH_ENDPOINT") + envTestApplicationKey = os.Getenv("OVH_APPLICATION_KEY") + envTestApplicationSecret = os.Getenv("OVH_APPLICATION_SECRET") + envTestConsumerKey = os.Getenv("OVH_CONSUMER_KEY") + envTestDomain = os.Getenv("OVH_DOMAIN") + + liveTest = len(envTestAPIEndpoint) > 0 && len(envTestApplicationKey) > 0 && len(envTestApplicationSecret) > 0 && len(envTestConsumerKey) > 0 } func restoreEnv() { - os.Setenv("OVH_ENDPOINT", apiEndpoint) - os.Setenv("OVH_APPLICATION_KEY", applicationKey) - os.Setenv("OVH_APPLICATION_SECRET", applicationSecret) - os.Setenv("OVH_CONSUMER_KEY", consumerKey) + os.Setenv("OVH_ENDPOINT", envTestAPIEndpoint) + os.Setenv("OVH_APPLICATION_KEY", envTestApplicationKey) + os.Setenv("OVH_APPLICATION_SECRET", envTestApplicationSecret) + os.Setenv("OVH_CONSUMER_KEY", envTestConsumerKey) } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("OVH_ENDPOINT", "ovh-eu") - os.Setenv("OVH_APPLICATION_KEY", "1234") - os.Setenv("OVH_APPLICATION_SECRET", "5678") - os.Setenv("OVH_CONSUMER_KEY", "abcde") - - _, err := NewDNSProvider() - require.NoError(t, err) -} - -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - +func TestNewDNSProvider(t *testing.T) { testCases := []struct { desc string envVars map[string]string expected string }{ { - desc: "missing OVH_ENDPOINT", - envVars: map[string]string{ - "OVH_ENDPOINT": "", - "OVH_APPLICATION_KEY": "1234", - "OVH_APPLICATION_SECRET": "5678", - "OVH_CONSUMER_KEY": "abcde", - }, - expected: "ovh: some credentials information are missing: OVH_ENDPOINT", - }, - { - desc: "missing OVH_APPLICATION_KEY", + desc: "success", envVars: map[string]string{ "OVH_ENDPOINT": "ovh-eu", - "OVH_APPLICATION_KEY": "", - "OVH_APPLICATION_SECRET": "5678", - "OVH_CONSUMER_KEY": "abcde", + "OVH_APPLICATION_KEY": "B", + "OVH_APPLICATION_SECRET": "C", + "OVH_CONSUMER_KEY": "D", }, - expected: "ovh: some credentials information are missing: OVH_APPLICATION_KEY", }, { - desc: "missing OVH_APPLICATION_SECRET", - envVars: map[string]string{ - "OVH_ENDPOINT": "ovh-eu", - "OVH_APPLICATION_KEY": "1234", - "OVH_APPLICATION_SECRET": "", - "OVH_CONSUMER_KEY": "abcde", - }, - expected: "ovh: some credentials information are missing: OVH_APPLICATION_SECRET", - }, - { - desc: "missing OVH_CONSUMER_KEY", - envVars: map[string]string{ - "OVH_ENDPOINT": "ovh-eu", - "OVH_APPLICATION_KEY": "1234", - "OVH_APPLICATION_SECRET": "5678", - "OVH_CONSUMER_KEY": "", - }, - expected: "ovh: some credentials information are missing: OVH_CONSUMER_KEY", - }, - { - desc: "all missing", + desc: "missing credentials", envVars: map[string]string{ "OVH_ENDPOINT": "", "OVH_APPLICATION_KEY": "", @@ -102,18 +59,171 @@ func TestNewDNSProviderMissingCredErr(t *testing.T) { }, expected: "ovh: some credentials information are missing: OVH_ENDPOINT,OVH_APPLICATION_KEY,OVH_APPLICATION_SECRET,OVH_CONSUMER_KEY", }, + { + desc: "missing endpoint", + envVars: map[string]string{ + "OVH_ENDPOINT": "", + "OVH_APPLICATION_KEY": "B", + "OVH_APPLICATION_SECRET": "C", + "OVH_CONSUMER_KEY": "D", + }, + expected: "ovh: some credentials information are missing: OVH_ENDPOINT", + }, + { + desc: "missing invalid endpoint", + envVars: map[string]string{ + "OVH_ENDPOINT": "foobar", + "OVH_APPLICATION_KEY": "B", + "OVH_APPLICATION_SECRET": "C", + "OVH_CONSUMER_KEY": "D", + }, + expected: "ovh: unknown endpoint 'foobar', consider checking 'Endpoints' list of using an URL", + }, + { + desc: "missing application key", + envVars: map[string]string{ + "OVH_ENDPOINT": "ovh-eu", + "OVH_APPLICATION_KEY": "", + "OVH_APPLICATION_SECRET": "C", + "OVH_CONSUMER_KEY": "D", + }, + expected: "ovh: some credentials information are missing: OVH_APPLICATION_KEY", + }, + { + desc: "missing application secret", + envVars: map[string]string{ + "OVH_ENDPOINT": "ovh-eu", + "OVH_APPLICATION_KEY": "B", + "OVH_APPLICATION_SECRET": "", + "OVH_CONSUMER_KEY": "D", + }, + expected: "ovh: some credentials information are missing: OVH_APPLICATION_SECRET", + }, + { + desc: "missing consumer key", + envVars: map[string]string{ + "OVH_ENDPOINT": "ovh-eu", + "OVH_APPLICATION_KEY": "B", + "OVH_APPLICATION_SECRET": "C", + "OVH_CONSUMER_KEY": "", + }, + expected: "ovh: some credentials information are missing: OVH_CONSUMER_KEY", + }, } for _, test := range testCases { - test := test t.Run(test.desc, func(t *testing.T) { - + defer restoreEnv() for key, value := range test.envVars { - os.Setenv(key, value) + if len(value) == 0 { + os.Unsetenv(key) + } else { + os.Setenv(key, value) + } } - _, err := NewDNSProvider() - assert.EqualError(t, err, test.expected) + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + require.NotNil(t, p.recordIDs) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiEndpoint string + applicationKey string + applicationSecret string + consumerKey string + expected string + }{ + { + desc: "success", + apiEndpoint: "ovh-eu", + applicationKey: "B", + applicationSecret: "C", + consumerKey: "D", + }, + { + desc: "missing credentials", + expected: "ovh: credentials missing", + }, + { + desc: "missing api endpoint", + apiEndpoint: "", + applicationKey: "B", + applicationSecret: "C", + consumerKey: "D", + expected: "ovh: credentials missing", + }, + { + desc: "missing invalid api endpoint", + apiEndpoint: "foobar", + applicationKey: "B", + applicationSecret: "C", + consumerKey: "D", + expected: "ovh: unknown endpoint 'foobar', consider checking 'Endpoints' list of using an URL", + }, + { + desc: "missing application key", + apiEndpoint: "ovh-eu", + applicationKey: "", + applicationSecret: "C", + consumerKey: "D", + expected: "ovh: credentials missing", + }, + { + desc: "missing application secret", + apiEndpoint: "ovh-eu", + applicationKey: "B", + applicationSecret: "", + consumerKey: "D", + expected: "ovh: credentials missing", + }, + { + desc: "missing consumer key", + apiEndpoint: "ovh-eu", + applicationKey: "B", + applicationSecret: "C", + consumerKey: "", + expected: "ovh: credentials missing", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("OVH_ENDPOINT") + os.Unsetenv("OVH_APPLICATION_KEY") + os.Unsetenv("OVH_APPLICATION_SECRET") + os.Unsetenv("OVH_CONSUMER_KEY") + + config := NewDefaultConfig() + config.APIEndpoint = test.apiEndpoint + config.ApplicationKey = test.applicationKey + config.ApplicationSecret = test.applicationSecret + config.ConsumerKey = test.consumerKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + require.NotNil(t, p.recordIDs) + } else { + require.EqualError(t, err, test.expected) + } }) } } @@ -123,10 +233,11 @@ func TestLivePresent(t *testing.T) { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(domain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } @@ -135,11 +246,12 @@ func TestLiveCleanUp(t *testing.T) { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(domain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/pdns/pdns_test.go b/providers/dns/pdns/pdns_test.go index 68d204d9..392b7099 100644 --- a/providers/dns/pdns/pdns_test.go +++ b/providers/dns/pdns/pdns_test.go @@ -5,90 +5,164 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - pdnsLiveTest bool - pdnsURL *url.URL - pdnsURLStr string - pdnsAPIKey string - pdnsDomain string + liveTest bool + envTestAPIURL *url.URL + envTestAPIKey string + envTestDomain string ) func init() { - pdnsURLStr = os.Getenv("PDNS_API_URL") - pdnsURL, _ = url.Parse(pdnsURLStr) - pdnsAPIKey = os.Getenv("PDNS_API_KEY") - pdnsDomain = os.Getenv("PDNS_DOMAIN") - if len(pdnsURLStr) > 0 && len(pdnsAPIKey) > 0 && len(pdnsDomain) > 0 { - pdnsLiveTest = true + envTestAPIURL, _ = url.Parse(os.Getenv("PDNS_API_URL")) + envTestAPIKey = os.Getenv("PDNS_API_KEY") + envTestDomain = os.Getenv("PDNS_DOMAIN") + + if len(envTestAPIURL.String()) > 0 && len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("PDNS_API_URL", pdnsURLStr) - os.Setenv("PDNS_API_KEY", pdnsAPIKey) + os.Setenv("PDNS_API_URL", envTestAPIURL.String()) + os.Setenv("PDNS_API_KEY", envTestAPIKey) } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() - os.Setenv("PDNS_API_URL", "") - os.Setenv("PDNS_API_KEY", "") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "PDNS_API_KEY": "123", + "PDNS_API_URL": "http://example.com", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "PDNS_API_KEY": "", + "PDNS_API_URL": "", + }, + expected: "pdns: some credentials information are missing: PDNS_API_KEY,PDNS_API_URL", + }, + { + desc: "missing api key", + envVars: map[string]string{ + "PDNS_API_KEY": "", + "PDNS_API_URL": "http://example.com", + }, + expected: "pdns: some credentials information are missing: PDNS_API_KEY", + }, + { + desc: "missing API URL", + envVars: map[string]string{ + "PDNS_API_KEY": "123", + "PDNS_API_URL": "", + }, + expected: "pdns: some credentials information are missing: PDNS_API_URL", + }, + } - tmpURL, _ := url.Parse("http://localhost:8081") + 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) + } + } - config := NewDefaultConfig() - config.Host = tmpURL - config.APIKey = "123" + p, err := NewDNSProvider() - _, err := NewDNSProviderConfig(config) - require.NoError(t, err) + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("PDNS_API_URL", "http://localhost:8081") - os.Setenv("PDNS_API_KEY", "123") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + host *url.URL + expected string + }{ + { + desc: "success", + apiKey: "123", + host: func() *url.URL { + u, _ := url.Parse("http://example.com") + return u + }(), + }, + { + desc: "missing credentials", + expected: "pdns: API key missing", + }, + { + desc: "missing API key", + apiKey: "", + host: func() *url.URL { + u, _ := url.Parse("http://example.com") + return u + }(), + expected: "pdns: API key missing", + }, + { + desc: "missing host", + apiKey: "123", + expected: "pdns: API URL missing", + }, + } - _, err := NewDNSProvider() - require.NoError(t, err) + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("PDNS_API_KEY") + os.Unsetenv("PDNS_API_URL") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + config.Host = test.host + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingHostErr(t *testing.T) { - defer restoreEnv() - os.Setenv("PDNS_API_URL", "") - os.Setenv("PDNS_API_KEY", "123") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "pdns: some credentials information are missing: PDNS_API_URL") -} - -func TestNewDNSProviderMissingKeyErr(t *testing.T) { - defer restoreEnv() - os.Setenv("PDNS_API_URL", pdnsURLStr) - os.Setenv("PDNS_API_KEY", "") - - _, err := NewDNSProvider() - assert.EqualError(t, err, "pdns: some credentials information are missing: PDNS_API_KEY,PDNS_API_URL") -} - -func TestPdnsPresentAndCleanup(t *testing.T) { - if !pdnsLiveTest { +func TestLivePresentAndCleanup(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.Host = pdnsURL - config.APIKey = pdnsAPIKey - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(pdnsDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) - err = provider.CleanUp(pdnsDomain, "", "123d==") + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/rackspace/client.go b/providers/dns/rackspace/client.go index ce203276..54b05c9d 100644 --- a/providers/dns/rackspace/client.go +++ b/providers/dns/rackspace/client.go @@ -16,20 +16,44 @@ type AuthData struct { Auth `json:"auth"` } -// Identity Identity +// Identity Identity type Identity struct { - Access struct { - ServiceCatalog []struct { - Endpoints []struct { - PublicURL string `json:"publicURL"` - TenantID string `json:"tenantId"` - } `json:"endpoints"` - Name string `json:"name"` - } `json:"serviceCatalog"` - Token struct { - ID string `json:"id"` - } `json:"token"` - } `json:"access"` + Access Access `json:"access"` +} + +// Access Access +type Access struct { + ServiceCatalog []ServiceCatalog `json:"serviceCatalog"` + Token Token `json:"token"` +} + +// Token Token +type Token struct { + ID string `json:"id"` +} + +// ServiceCatalog ServiceCatalog +type ServiceCatalog struct { + Endpoints []Endpoint `json:"endpoints"` + Name string `json:"name"` +} + +// Endpoint Endpoint +type Endpoint struct { + PublicURL string `json:"publicURL"` + TenantID string `json:"tenantId"` +} + +// ZoneSearchResponse represents the response when querying Rackspace DNS zones +type ZoneSearchResponse struct { + TotalEntries int `json:"totalEntries"` + HostedZones []HostedZone `json:"domains"` +} + +// HostedZone HostedZone +type HostedZone struct { + ID int `json:"id"` + Name string `json:"name"` } // Records is the list of records sent/received from the DNS API diff --git a/providers/dns/rackspace/rackspace.go b/providers/dns/rackspace/rackspace.go index 2a35c907..7b5e73d4 100644 --- a/providers/dns/rackspace/rackspace.go +++ b/providers/dns/rackspace/rackspace.go @@ -89,39 +89,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, fmt.Errorf("rackspace: credentials missing") } - authData := AuthData{ - Auth: Auth{ - APIKeyCredentials: APIKeyCredentials{ - Username: config.APIUser, - APIKey: config.APIKey, - }, - }, - } - - body, err := json.Marshal(authData) - if err != nil { - return nil, err - } - - req, err := http.NewRequest(http.MethodPost, config.BaseURL, bytes.NewReader(body)) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", "application/json") - - // client := &http.Client{Timeout: 30 * time.Second} - resp, err := config.HTTPClient.Do(req) - if err != nil { - return nil, fmt.Errorf("rackspace: error querying Identity API: %v", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("rackspace: authentication failed: response code: %d", resp.StatusCode) - } - - var identity Identity - err = json.NewDecoder(resp.Body).Decode(&identity) + identity, err := login(config) if err != nil { return nil, fmt.Errorf("rackspace: %v", err) } @@ -134,6 +102,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { break } } + if dnsEndpoint == "" { return nil, fmt.Errorf("rackspace: failed to populate DNS endpoint, check Rackspace API for changes") } @@ -149,6 +118,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { // Present creates a TXT record to fulfill the dns-01 challenge func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value, _ := acme.DNS01Record(domain, keyAuth) + zoneID, err := d.getHostedZoneID(fqdn) if err != nil { return fmt.Errorf("rackspace: %v", err) @@ -178,6 +148,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { // CleanUp removes the TXT record matching the specified parameters func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { fqdn, _, _ := acme.DNS01Record(domain, keyAuth) + zoneID, err := d.getHostedZoneID(fqdn) if err != nil { return fmt.Errorf("rackspace: %v", err) @@ -204,15 +175,6 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { // getHostedZoneID performs a lookup to get the DNS zone which needs // modifying for a given FQDN func (d *DNSProvider) getHostedZoneID(fqdn string) (int, error) { - // HostedZones represents the response when querying Rackspace DNS zones - type ZoneSearchResponse struct { - TotalEntries int `json:"totalEntries"` - HostedZones []struct { - ID int `json:"id"` - Name string `json:"name"` - } `json:"domains"` - } - authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers) if err != nil { return 0, err @@ -250,8 +212,7 @@ func (d *DNSProvider) findTxtRecord(fqdn string, zoneID int) (*Record, error) { return nil, err } - recordsLength := len(records.Record) - switch recordsLength { + switch len(records.Record) { case 1: case 0: return nil, fmt.Errorf("no TXT record found for %s", fqdn) @@ -265,6 +226,7 @@ func (d *DNSProvider) findTxtRecord(fqdn string, zoneID int) (*Record, error) { // makeRequest is a wrapper function used for making DNS API requests func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) { url := d.cloudDNSEndpoint + uri + req, err := http.NewRequest(method, url, body) if err != nil { return nil, err @@ -292,3 +254,44 @@ func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawM return r, nil } + +func login(config *Config) (*Identity, error) { + authData := AuthData{ + Auth: Auth{ + APIKeyCredentials: APIKeyCredentials{ + Username: config.APIUser, + APIKey: config.APIKey, + }, + }, + } + + body, err := json.Marshal(authData) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, config.BaseURL, bytes.NewReader(body)) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + resp, err := config.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("error querying Identity API: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("authentication failed: response code: %d", resp.StatusCode) + } + + var identity Identity + err = json.NewDecoder(resp.Body).Decode(&identity) + if err != nil { + return nil, err + } + + return &identity, nil +} diff --git a/providers/dns/rackspace/rackspace_test.go b/providers/dns/rackspace/rackspace_test.go index ab214ab6..f4fa288f 100644 --- a/providers/dns/rackspace/rackspace_test.go +++ b/providers/dns/rackspace/rackspace_test.go @@ -15,45 +15,117 @@ import ( ) var ( - rackspaceLiveTest bool - rackspaceUser string - rackspaceAPIKey string - rackspaceDomain string - testAPIURL string + liveTest bool + envTestUser string + envTestAPIKey string + envTestDomain string ) func init() { - rackspaceUser = os.Getenv("RACKSPACE_USER") - rackspaceAPIKey = os.Getenv("RACKSPACE_API_KEY") - rackspaceDomain = os.Getenv("RACKSPACE_DOMAIN") - if len(rackspaceUser) > 0 && len(rackspaceAPIKey) > 0 && len(rackspaceDomain) > 0 { - rackspaceLiveTest = true + envTestUser = os.Getenv("RACKSPACE_USER") + envTestAPIKey = os.Getenv("RACKSPACE_API_KEY") + envTestDomain = os.Getenv("RACKSPACE_DOMAIN") + + if len(envTestUser) > 0 && len(envTestAPIKey) > 0 && len(envTestDomain) > 0 { + liveTest = true } } -func testRackspaceEnv() { - os.Setenv("RACKSPACE_USER", "testUser") - os.Setenv("RACKSPACE_API_KEY", "testKey") +func TestNewDNSProviderConfig(t *testing.T) { + config, tearDown := setupTest() + defer tearDown() + + provider, err := NewDNSProviderConfig(config) + require.NoError(t, err) + assert.NotNil(t, provider.config) + + assert.Equal(t, provider.token, "testToken", "The token should match") } -func liveRackspaceEnv() { - os.Setenv("RACKSPACE_USER", rackspaceUser) - os.Setenv("RACKSPACE_API_KEY", rackspaceAPIKey) +func TestNewDNSProviderConfig_MissingCredErr(t *testing.T) { + _, err := NewDNSProviderConfig(NewDefaultConfig()) + assert.EqualError(t, err, "rackspace: credentials missing") } -func startTestServers() (*httptest.Server, *httptest.Server) { - dnsAPI := httptest.NewServer(dnsMux()) - dnsEndpoint := dnsAPI.URL + "/123456" +func TestDNSProvider_Present(t *testing.T) { + config, tearDown := setupTest() + defer tearDown() - identityAPI := httptest.NewServer(identityHandler(dnsEndpoint)) - testAPIURL = identityAPI.URL + "/" + provider, err := NewDNSProviderConfig(config) - return identityAPI, dnsAPI + if assert.NoError(t, err) { + err = provider.Present("example.com", "token", "keyAuth") + require.NoError(t, err) + } } -func closeTestServers(identityAPI, dnsAPI *httptest.Server) { - identityAPI.Close() - dnsAPI.Close() +func TestDNSProvider_CleanUp(t *testing.T) { + config, tearDown := setupTest() + defer tearDown() + + provider, err := NewDNSProviderConfig(config) + + if assert.NoError(t, err) { + err = provider.CleanUp("example.com", "token", "keyAuth") + require.NoError(t, err) + } +} + +func TestLiveNewDNSProvider_ValidEnv(t *testing.T) { + if !liveTest { + t.Skip("skipping live test") + } + + provider, err := NewDNSProvider() + require.NoError(t, err) + assert.Contains(t, provider.cloudDNSEndpoint, "https://dns.api.rackspacecloud.com/v1.0/", "The endpoint URL should contain the base") +} + +func TestLivePresent(t *testing.T) { + if !liveTest { + t.Skip("skipping live test") + } + + provider, err := NewDNSProvider() + require.NoError(t, err) + + err = provider.Present(envTestDomain, "", "112233445566==") + require.NoError(t, err) +} + +func TestLiveCleanUp(t *testing.T) { + if !liveTest { + t.Skip("skipping live test") + } + + time.Sleep(time.Second * 15) + + provider, err := NewDNSProvider() + require.NoError(t, err) + + err = provider.CleanUp(envTestDomain, "", "112233445566==") + require.NoError(t, err) +} + +func setupTest() (*Config, func()) { + apiURL, tearDown := startTestServers() + + config := NewDefaultConfig() + config.APIUser = "testUser" + config.APIKey = "testKey" + config.BaseURL = apiURL + + return config, tearDown +} + +func startTestServers() (string, func()) { + dnsAPI := httptest.NewServer(dnsHandler()) + identityAPI := httptest.NewServer(identityHandler(dnsAPI.URL + "/123456")) + + return identityAPI.URL + "/", func() { + identityAPI.Close() + dnsAPI.Close() + } } func identityHandler(dnsEndpoint string) http.Handler { @@ -63,18 +135,20 @@ func identityHandler(dnsEndpoint string) http.Handler { w.WriteHeader(http.StatusInternalServerError) return } + resp, found := jsonMap[string(reqBody)] if !found { w.WriteHeader(http.StatusBadRequest) return } + resp = strings.Replace(resp, "https://dns.api.rackspacecloud.com/v1.0/123456", dnsEndpoint, 1) w.WriteHeader(http.StatusOK) fmt.Fprintf(w, resp) }) } -func dnsMux() *http.ServeMux { +func dnsHandler() *http.ServeMux { mux := http.NewServeMux() // Used by `getHostedZoneID()` finding `zoneID` "?name=example.com" @@ -93,7 +167,7 @@ func dnsMux() *http.ServeMux { case http.MethodPost: reqBody, err := ioutil.ReadAll(r.Body) if err != nil { - w.WriteHeader(http.StatusInternalServerError) + http.Error(w, err.Error(), http.StatusInternalServerError) return } resp, found := jsonMap[string(reqBody)] @@ -103,7 +177,7 @@ func dnsMux() *http.ServeMux { } w.WriteHeader(http.StatusAccepted) fmt.Fprintf(w, resp) - // Used by `findTxtRecord()` finding `record.ID` "?type=TXT&name=_acme-challenge.example.com" + // Used by `findTxtRecord()` finding `record.ID` "?type=TXT&name=_acme-challenge.example.com" case http.MethodGet: if r.URL.Query().Get("type") == "TXT" && r.URL.Query().Get("name") == "_acme-challenge.example.com" { w.WriteHeader(http.StatusOK) @@ -112,7 +186,7 @@ func dnsMux() *http.ServeMux { } w.WriteHeader(http.StatusBadRequest) return - // Used by `CleanUp()` deleting the TXT record "?id=445566" + // Used by `CleanUp()` deleting the TXT record "?id=445566" case http.MethodDelete: if r.URL.Query().Get("id") == "TXT-654321" { w.WriteHeader(http.StatusOK) @@ -131,104 +205,6 @@ func dnsMux() *http.ServeMux { return mux } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - testRackspaceEnv() - - _, err := NewDNSProviderConfig(&Config{}) - assert.EqualError(t, err, "rackspace: credentials missing") -} - -func TestOfflineRackspaceValid(t *testing.T) { - testRackspaceEnv() - - config := NewDefaultConfig() - config.BaseURL = testAPIURL - config.APIKey = os.Getenv("RACKSPACE_API_KEY") - config.APIUser = os.Getenv("RACKSPACE_USER") - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - - assert.Equal(t, provider.token, "testToken", "The token should match") -} - -func TestOfflineRackspacePresent(t *testing.T) { - testRackspaceEnv() - - config := NewDefaultConfig() - config.APIUser = os.Getenv("RACKSPACE_USER") - config.APIKey = os.Getenv("RACKSPACE_API_KEY") - config.BaseURL = testAPIURL - - provider, err := NewDNSProviderConfig(config) - - if assert.NoError(t, err) { - err = provider.Present("example.com", "token", "keyAuth") - require.NoError(t, err) - } -} - -func TestOfflineRackspaceCleanUp(t *testing.T) { - testRackspaceEnv() - - config := NewDefaultConfig() - config.APIUser = os.Getenv("RACKSPACE_USER") - config.APIKey = os.Getenv("RACKSPACE_API_KEY") - config.BaseURL = testAPIURL - - provider, err := NewDNSProviderConfig(config) - - if assert.NoError(t, err) { - err = provider.CleanUp("example.com", "token", "keyAuth") - require.NoError(t, err) - } -} - -func TestNewDNSProviderValidEnv(t *testing.T) { - if !rackspaceLiveTest { - t.Skip("skipping live test") - } - - liveRackspaceEnv() - provider, err := NewDNSProvider() - require.NoError(t, err) - assert.Contains(t, provider.cloudDNSEndpoint, "https://dns.api.rackspacecloud.com/v1.0/", "The endpoint URL should contain the base") -} - -func TestRackspacePresent(t *testing.T) { - if !rackspaceLiveTest { - t.Skip("skipping live test") - } - - liveRackspaceEnv() - provider, err := NewDNSProvider() - require.NoError(t, err) - - err = provider.Present(rackspaceDomain, "", "112233445566==") - require.NoError(t, err) -} - -func TestRackspaceCleanUp(t *testing.T) { - if !rackspaceLiveTest { - t.Skip("skipping live test") - } - - time.Sleep(time.Second * 15) - - liveRackspaceEnv() - provider, err := NewDNSProvider() - require.NoError(t, err) - - err = provider.CleanUp(rackspaceDomain, "", "112233445566==") - require.NoError(t, err) -} - -func TestMain(m *testing.M) { - identityAPI, dnsAPI := startTestServers() - defer closeTestServers(identityAPI, dnsAPI) - os.Exit(m.Run()) -} - var jsonMap = map[string]string{ `{"auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"testUser","apiKey":"testKey"}}}`: `{"access":{"token":{"id":"testToken","expires":"1970-01-01T00:00:00.000Z","tenant":{"id":"123456","name":"123456"},"RAX-AUTH:authenticatedBy":["APIKEY"]},"serviceCatalog":[{"type":"rax:dns","endpoints":[{"publicURL":"https://dns.api.rackspacecloud.com/v1.0/123456","tenantId":"123456"}],"name":"cloudDNS"}],"user":{"id":"fakeUseID","name":"testUser"}}}`, "zoneDetails": `{"domains":[{"name":"example.com","id":112233,"emailAddress":"hostmaster@example.com","updated":"1970-01-01T00:00:00.000+0000","created":"1970-01-01T00:00:00.000+0000"}],"totalEntries":1}`, diff --git a/providers/dns/rfc2136/rfc2136_test.go b/providers/dns/rfc2136/rfc2136_test.go index fc1ce7ce..a3625fe1 100644 --- a/providers/dns/rfc2136/rfc2136_test.go +++ b/providers/dns/rfc2136/rfc2136_test.go @@ -16,38 +16,33 @@ import ( ) var ( - rfc2136TestDomain = "123456789.www.example.com" - rfc2136TestKeyAuth = "123d==" - rfc2136TestValue = "Now36o-3BmlB623-0c1qCIUmgWVVmDJb88KGl24pqpo" - rfc2136TestFqdn = "_acme-challenge.123456789.www.example.com." - rfc2136TestZone = "example.com." - rfc2136TestTTL = 120 - rfc2136TestTsigKey = "example.com." - rfc2136TestTsigSecret = "IwBTJx9wrDp4Y1RyC3H0gA==" + envTestDomain = "123456789.www.example.com" + envTestKeyAuth = "123d==" + envTestValue = "Now36o-3BmlB623-0c1qCIUmgWVVmDJb88KGl24pqpo" + envTestFqdn = "_acme-challenge.123456789.www.example.com." + envTestZone = "example.com." + envTestTTL = 120 + envTestTsigKey = "example.com." + envTestTsigSecret = "IwBTJx9wrDp4Y1RyC3H0gA==" ) var reqChan = make(chan *dns.Msg, 10) -func TestRFC2136CanaryLocalTestServer(t *testing.T) { +func TestCanaryLocalTestServer(t *testing.T) { acme.ClearFqdnCache() dns.HandleFunc("example.com.", serverHandlerHello) defer dns.HandleRemove("example.com.") - server, addrstr, err := runLocalDNSTestServer(false) + server, addr, err := runLocalDNSTestServer(false) require.NoError(t, err, "Failed to start test server") - defer func() { - errS := server.Shutdown() - if errS != nil { - t.Log(errS) - } - }() + defer func() { _ = server.Shutdown() }() c := new(dns.Client) m := new(dns.Msg) m.SetQuestion("example.com.", dns.TypeTXT) - r, _, err := c.Exchange(m, addrstr) + r, _, err := c.Exchange(m, addr) require.NoError(t, err, "Failed to communicate with test server") assert.Len(t, r.Extra, 1, "Failed to communicate with test server") @@ -55,115 +50,95 @@ func TestRFC2136CanaryLocalTestServer(t *testing.T) { assert.Equal(t, "Hello world", txt) } -func TestRFC2136ServerSuccess(t *testing.T) { +func TestServerSuccess(t *testing.T) { acme.ClearFqdnCache() - dns.HandleFunc(rfc2136TestZone, serverHandlerReturnSuccess) - defer dns.HandleRemove(rfc2136TestZone) + dns.HandleFunc(envTestZone, serverHandlerReturnSuccess) + defer dns.HandleRemove(envTestZone) - server, addrstr, err := runLocalDNSTestServer(false) + server, addr, err := runLocalDNSTestServer(false) require.NoError(t, err, "Failed to start test server") - defer func() { - errS := server.Shutdown() - if errS != nil { - t.Log(errS) - } - }() + defer func() { _ = server.Shutdown() }() config := NewDefaultConfig() - config.Nameserver = addrstr + config.Nameserver = addr provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth) + err = provider.Present(envTestDomain, "", envTestKeyAuth) require.NoError(t, err) } -func TestRFC2136ServerError(t *testing.T) { +func TestServerError(t *testing.T) { acme.ClearFqdnCache() - dns.HandleFunc(rfc2136TestZone, serverHandlerReturnErr) - defer dns.HandleRemove(rfc2136TestZone) + dns.HandleFunc(envTestZone, serverHandlerReturnErr) + defer dns.HandleRemove(envTestZone) - server, addrstr, err := runLocalDNSTestServer(false) + server, addr, err := runLocalDNSTestServer(false) require.NoError(t, err, "Failed to start test server") - defer func() { - errS := server.Shutdown() - if errS != nil { - t.Log(errS) - } - }() + defer func() { _ = server.Shutdown() }() config := NewDefaultConfig() - config.Nameserver = addrstr + config.Nameserver = addr provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth) + err = provider.Present(envTestDomain, "", envTestKeyAuth) require.Error(t, err) if !strings.Contains(err.Error(), "NOTZONE") { t.Errorf("Expected Present() to return an error with the 'NOTZONE' rcode string but it did not: %v", err) } } -func TestRFC2136TsigClient(t *testing.T) { +func TestTsigClient(t *testing.T) { acme.ClearFqdnCache() - dns.HandleFunc(rfc2136TestZone, serverHandlerReturnSuccess) - defer dns.HandleRemove(rfc2136TestZone) + dns.HandleFunc(envTestZone, serverHandlerReturnSuccess) + defer dns.HandleRemove(envTestZone) - server, addrstr, err := runLocalDNSTestServer(true) + server, addr, err := runLocalDNSTestServer(true) require.NoError(t, err, "Failed to start test server") - defer func() { - errS := server.Shutdown() - if errS != nil { - t.Log(errS) - } - }() + defer func() { _ = server.Shutdown() }() config := NewDefaultConfig() - config.Nameserver = addrstr - config.TSIGKey = rfc2136TestTsigKey - config.TSIGSecret = rfc2136TestTsigSecret + config.Nameserver = addr + config.TSIGKey = envTestTsigKey + config.TSIGSecret = envTestTsigSecret provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth) + err = provider.Present(envTestDomain, "", envTestKeyAuth) require.NoError(t, err) } -func TestRFC2136ValidUpdatePacket(t *testing.T) { +func TestValidUpdatePacket(t *testing.T) { acme.ClearFqdnCache() - dns.HandleFunc(rfc2136TestZone, serverHandlerPassBackRequest) - defer dns.HandleRemove(rfc2136TestZone) + dns.HandleFunc(envTestZone, serverHandlerPassBackRequest) + defer dns.HandleRemove(envTestZone) - server, addrstr, err := runLocalDNSTestServer(false) + server, addr, err := runLocalDNSTestServer(false) require.NoError(t, err, "Failed to start test server") - defer func() { - errS := server.Shutdown() - if errS != nil { - t.Log(errS) - } - }() + defer func() { _ = server.Shutdown() }() - txtRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN TXT %s", rfc2136TestFqdn, rfc2136TestTTL, rfc2136TestValue)) + txtRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN TXT %s", envTestFqdn, envTestTTL, envTestValue)) rrs := []dns.RR{txtRR} m := new(dns.Msg) - m.SetUpdate(rfc2136TestZone) + m.SetUpdate(envTestZone) m.RemoveRRset(rrs) m.Insert(rrs) - expectstr := m.String() + expectStr := m.String() expect, err := m.Pack() require.NoError(t, err, "error packing") config := NewDefaultConfig() - config.Nameserver = addrstr + config.Nameserver = addr provider, err := NewDNSProviderConfig(config) require.NoError(t, err) - err = provider.Present(rfc2136TestDomain, "", "1234d==") + err = provider.Present(envTestDomain, "", "1234d==") require.NoError(t, err) rcvMsg := <-reqChan @@ -177,7 +152,7 @@ func TestRFC2136ValidUpdatePacket(t *testing.T) { if err := tmp.Unpack(actual); err != nil { t.Fatalf("Error unpacking actual msg: %v", err) } - t.Errorf("Expected msg:\n%s", expectstr) + t.Errorf("Expected msg:\n%s", expectStr) t.Errorf("Actual msg:\n%v", tmp) } } @@ -187,9 +162,10 @@ func runLocalDNSTestServer(tsig bool) (*dns.Server, string, error) { if err != nil { return nil, "", err } + server := &dns.Server{PacketConn: pc, ReadTimeout: time.Hour, WriteTimeout: time.Hour} if tsig { - server.TsigSecret = map[string]string{rfc2136TestTsigKey: rfc2136TestTsigSecret} + server.TsigSecret = map[string]string{envTestTsigKey: envTestTsigSecret} } waitLock := sync.Mutex{} @@ -221,14 +197,14 @@ func serverHandlerReturnSuccess(w dns.ResponseWriter, req *dns.Msg) { m.SetReply(req) if req.Opcode == dns.OpcodeQuery && req.Question[0].Qtype == dns.TypeSOA && req.Question[0].Qclass == dns.ClassINET { // Return SOA to appease findZoneByFqdn() - soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", rfc2136TestZone, rfc2136TestTTL, rfc2136TestZone, rfc2136TestZone)) + soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", envTestZone, envTestTTL, envTestZone, envTestZone)) m.Answer = []dns.RR{soaRR} } if t := req.IsTsig(); t != nil { if w.TsigStatus() == nil { // Validated - m.SetTsig(rfc2136TestZone, dns.HmacMD5, 300, time.Now().Unix()) + m.SetTsig(envTestZone, dns.HmacMD5, 300, time.Now().Unix()) } } @@ -246,14 +222,14 @@ func serverHandlerPassBackRequest(w dns.ResponseWriter, req *dns.Msg) { m.SetReply(req) if req.Opcode == dns.OpcodeQuery && req.Question[0].Qtype == dns.TypeSOA && req.Question[0].Qclass == dns.ClassINET { // Return SOA to appease findZoneByFqdn() - soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", rfc2136TestZone, rfc2136TestTTL, rfc2136TestZone, rfc2136TestZone)) + soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", envTestZone, envTestTTL, envTestZone, envTestZone)) m.Answer = []dns.RR{soaRR} } if t := req.IsTsig(); t != nil { if w.TsigStatus() == nil { // Validated - m.SetTsig(rfc2136TestZone, dns.HmacMD5, 300, time.Now().Unix()) + m.SetTsig(envTestZone, dns.HmacMD5, 300, time.Now().Unix()) } } diff --git a/providers/dns/route53/route53_integration_test.go b/providers/dns/route53/route53_integration_test.go index 68c076fb..eede6e6c 100644 --- a/providers/dns/route53/route53_integration_test.go +++ b/providers/dns/route53/route53_integration_test.go @@ -10,7 +10,7 @@ import ( "github.com/xenolf/lego/platform/config/env" ) -func TestRoute53TTL(t *testing.T) { +func TestLiveTTL(t *testing.T) { config, err := env.Get("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION", "R53_DOMAIN") if err != nil { t.Skip(err.Error()) @@ -19,19 +19,19 @@ func TestRoute53TTL(t *testing.T) { provider, err := NewDNSProvider() require.NoError(t, err) - r53Domain := config["R53_DOMAIN"] + domain := config["R53_DOMAIN"] - err = provider.Present(r53Domain, "foo", "bar") + err = provider.Present(domain, "foo", "bar") require.NoError(t, err) // we need a separate R53 client here as the one in the DNS provider is unexported. - fqdn := "_acme-challenge." + r53Domain + "." + fqdn := "_acme-challenge." + domain + "." sess, err := session.NewSession() require.NoError(t, err) svc := route53.New(sess) defer func() { - errC := provider.CleanUp(r53Domain, "foo", "bar") + errC := provider.CleanUp(domain, "foo", "bar") if errC != nil { t.Log(errC) } @@ -52,5 +52,5 @@ func TestRoute53TTL(t *testing.T) { } } - t.Fatalf("Could not find a TXT record for _acme-challenge.%s with a TTL of 10", r53Domain) + t.Fatalf("Could not find a TXT record for _acme-challenge.%s with a TTL of 10", domain) } diff --git a/providers/dns/route53/route53_test.go b/providers/dns/route53/route53_test.go index 4f2a0410..cc840685 100644 --- a/providers/dns/route53/route53_test.go +++ b/providers/dns/route53/route53_test.go @@ -15,39 +15,39 @@ import ( ) var ( - r53AwsSecretAccessKey string - r53AwsAccessKeyID string - r53AwsRegion string - r53AwsHostedZoneID string + envTestAwsSecretAccessKey string + envTestAwsAccessKeyID string + envTestAwsRegion string + envTestAwsHostedZoneID string - r53AwsMaxRetries string - r53AwsTTL string - r53AwsPropagationTimeout string - r53AwsPollingInterval string + envTestAwsMaxRetries string + envTestAwsTTL string + envTestAwsPropagationTimeout string + envTestAwsPollingInterval string ) func init() { - r53AwsAccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") - r53AwsSecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") - r53AwsRegion = os.Getenv("AWS_REGION") - r53AwsHostedZoneID = os.Getenv("AWS_HOSTED_ZONE_ID") + envTestAwsAccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") + envTestAwsSecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") + envTestAwsRegion = os.Getenv("AWS_REGION") + envTestAwsHostedZoneID = os.Getenv("AWS_HOSTED_ZONE_ID") - r53AwsMaxRetries = os.Getenv("AWS_MAX_RETRIES") - r53AwsTTL = os.Getenv("AWS_TTL") - r53AwsPropagationTimeout = os.Getenv("AWS_PROPAGATION_TIMEOUT") - r53AwsPollingInterval = os.Getenv("AWS_POLLING_INTERVAL") + envTestAwsMaxRetries = os.Getenv("AWS_MAX_RETRIES") + envTestAwsTTL = os.Getenv("AWS_TTL") + envTestAwsPropagationTimeout = os.Getenv("AWS_PROPAGATION_TIMEOUT") + envTestAwsPollingInterval = os.Getenv("AWS_POLLING_INTERVAL") } func restoreEnv() { - os.Setenv("AWS_ACCESS_KEY_ID", r53AwsAccessKeyID) - os.Setenv("AWS_SECRET_ACCESS_KEY", r53AwsSecretAccessKey) - os.Setenv("AWS_REGION", r53AwsRegion) - os.Setenv("AWS_HOSTED_ZONE_ID", r53AwsHostedZoneID) + os.Setenv("AWS_ACCESS_KEY_ID", envTestAwsAccessKeyID) + os.Setenv("AWS_SECRET_ACCESS_KEY", envTestAwsSecretAccessKey) + os.Setenv("AWS_REGION", envTestAwsRegion) + os.Setenv("AWS_HOSTED_ZONE_ID", envTestAwsHostedZoneID) - os.Setenv("AWS_MAX_RETRIES", r53AwsMaxRetries) - os.Setenv("AWS_TTL", r53AwsTTL) - os.Setenv("AWS_PROPAGATION_TIMEOUT", r53AwsPropagationTimeout) - os.Setenv("AWS_POLLING_INTERVAL", r53AwsPollingInterval) + os.Setenv("AWS_MAX_RETRIES", envTestAwsMaxRetries) + os.Setenv("AWS_TTL", envTestAwsTTL) + os.Setenv("AWS_PROPAGATION_TIMEOUT", envTestAwsPropagationTimeout) + os.Setenv("AWS_POLLING_INTERVAL", envTestAwsPollingInterval) } func cleanEnv() { @@ -62,7 +62,7 @@ func cleanEnv() { os.Unsetenv("AWS_POLLING_INTERVAL") } -func makeRoute53Provider(ts *httptest.Server) *DNSProvider { +func makeTestProvider(ts *httptest.Server) *DNSProvider { config := &aws.Config{ Credentials: credentials.NewStaticCredentials("abc", "123", " "), Endpoint: aws.String(ts.URL), @@ -93,7 +93,7 @@ func Test_loadCredentials_FromEnv(t *testing.T) { require.NoError(t, err) value, err := sess.Config.Credentials.Get() - assert.NoError(t, err, "Expected credentials to be set from environment") + require.NoError(t, err, "Expected credentials to be set from environment") expected := credentials.Value{ AccessKeyID: "123", @@ -123,10 +123,10 @@ func Test_getHostedZoneID_FromEnv(t *testing.T) { os.Setenv("AWS_HOSTED_ZONE_ID", expectedZoneID) provider, err := NewDNSProvider() - assert.NoError(t, err) + require.NoError(t, err) hostedZoneID, err := provider.getHostedZoneID("whatever") - assert.NoError(t, err, "HostedZoneID") + require.NoError(t, err, "HostedZoneID") assert.Equal(t, expectedZoneID, hostedZoneID) } @@ -181,7 +181,7 @@ func TestNewDefaultConfig(t *testing.T) { } } -func TestRoute53Present(t *testing.T) { +func TestDNSProvider_Present(t *testing.T) { mockResponses := MockResponseMap{ "/2013-04-01/hostedzonesbyname": {StatusCode: 200, Body: ListHostedZonesByNameResponse}, "/2013-04-01/hostedzone/ABCDEFG/rrset/": {StatusCode: 200, Body: ChangeResourceRecordSetsResponse}, @@ -195,11 +195,11 @@ func TestRoute53Present(t *testing.T) { ts := newMockServer(t, mockResponses) defer ts.Close() - provider := makeRoute53Provider(ts) + provider := makeTestProvider(ts) domain := "example.com" keyAuth := "123456d==" err := provider.Present(domain, "", keyAuth) - assert.NoError(t, err, "Expected Present to return no error") + require.NoError(t, err, "Expected Present to return no error") } diff --git a/providers/dns/sakuracloud/sakuracloud_test.go b/providers/dns/sakuracloud/sakuracloud_test.go index d8713a54..5de74b0c 100644 --- a/providers/dns/sakuracloud/sakuracloud_test.go +++ b/providers/dns/sakuracloud/sakuracloud_test.go @@ -5,121 +5,171 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/xenolf/lego/acme" ) var ( - sakuracloudLiveTest bool - sakuracloudAccessToken string - sakuracloudAccessSecret string - sakuracloudDomain string + liveTest bool + envTestAccessToken string + envTestAccessSecret string + envTestDomain string ) func init() { - sakuracloudAccessToken = os.Getenv("SAKURACLOUD_ACCESS_TOKEN") - sakuracloudAccessSecret = os.Getenv("SAKURACLOUD_ACCESS_TOKEN_SECRET") - sakuracloudDomain = os.Getenv("SAKURACLOUD_DOMAIN") + envTestAccessToken = os.Getenv("SAKURACLOUD_ACCESS_TOKEN") + envTestAccessSecret = os.Getenv("SAKURACLOUD_ACCESS_TOKEN_SECRET") + envTestDomain = os.Getenv("SAKURACLOUD_DOMAIN") - if len(sakuracloudAccessToken) > 0 && len(sakuracloudAccessSecret) > 0 && len(sakuracloudDomain) > 0 { - sakuracloudLiveTest = true + if len(envTestAccessToken) > 0 && len(envTestAccessSecret) > 0 && len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("SAKURACLOUD_ACCESS_TOKEN", sakuracloudAccessToken) - os.Setenv("SAKURACLOUD_ACCESS_TOKEN_SECRET", sakuracloudAccessSecret) + os.Setenv("SAKURACLOUD_ACCESS_TOKEN", envTestAccessToken) + os.Setenv("SAKURACLOUD_ACCESS_TOKEN_SECRET", envTestAccessSecret) } -// -// NewDNSProvider -// +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "SAKURACLOUD_ACCESS_TOKEN": "123", + "SAKURACLOUD_ACCESS_TOKEN_SECRET": "456", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + "SAKURACLOUD_ACCESS_TOKEN": "", + "SAKURACLOUD_ACCESS_TOKEN_SECRET": "", + }, + expected: "sakuracloud: some credentials information are missing: SAKURACLOUD_ACCESS_TOKEN,SAKURACLOUD_ACCESS_TOKEN_SECRET", + }, + { + desc: "missing access token", + envVars: map[string]string{ + "SAKURACLOUD_ACCESS_TOKEN": "", + "SAKURACLOUD_ACCESS_TOKEN_SECRET": "456", + }, + expected: "sakuracloud: some credentials information are missing: SAKURACLOUD_ACCESS_TOKEN", + }, + { + desc: "missing token secret", + envVars: map[string]string{ + "SAKURACLOUD_ACCESS_TOKEN": "123", + "SAKURACLOUD_ACCESS_TOKEN_SECRET": "", + }, + expected: "sakuracloud: some credentials information are missing: SAKURACLOUD_ACCESS_TOKEN_SECRET", + }, + } -func TestNewDNSProviderValid(t *testing.T) { - defer restoreEnv() + 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) + } + } - os.Setenv("SAKURACLOUD_ACCESS_TOKEN", "123") - os.Setenv("SAKURACLOUD_ACCESS_TOKEN_SECRET", "456") - provider, err := NewDNSProvider() + p, err := NewDNSProvider() - assert.NotNil(t, provider) - assert.Equal(t, acme.UserAgent, provider.client.UserAgent) - require.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) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderInvalidWithMissingAccessToken(t *testing.T) { - defer restoreEnv() +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + token string + secret string + expected string + }{ + { + desc: "success", + token: "123", + secret: "456", + }, + { + desc: "missing credentials", + expected: "sakuracloud: AccessToken is missing", + }, + { + desc: "missing token", + secret: "456", + expected: "sakuracloud: AccessToken is missing", + }, + { + desc: "missing secret", + token: "123", + expected: "sakuracloud: AccessSecret is missing", + }, + } - os.Setenv("SAKURACLOUD_ACCESS_TOKEN", "") - provider, err := NewDNSProvider() + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("SAKURACLOUD_ACCESS_TOKEN") + os.Unsetenv("SAKURACLOUD_ACCESS_TOKEN_SECRET") - assert.Nil(t, provider) - assert.EqualError(t, err, "sakuracloud: some credentials information are missing: SAKURACLOUD_ACCESS_TOKEN,SAKURACLOUD_ACCESS_TOKEN_SECRET") + config := NewDefaultConfig() + config.Token = test.token + config.Secret = test.secret + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -// -// NewDNSProviderCredentials -// - -func TestNewDNSProviderCredentialsValid(t *testing.T) { - config := NewDefaultConfig() - config.Token = "123" - config.Secret = "456" - - provider, err := NewDNSProviderConfig(config) - require.NoError(t, err) - - assert.NotNil(t, provider) - assert.Equal(t, acme.UserAgent, provider.client.UserAgent) -} - -func TestNewDNSProviderCredentialsInvalidWithMissingAccessToken(t *testing.T) { - config := NewDefaultConfig() - - provider, err := NewDNSProviderConfig(config) - assert.Nil(t, provider) - assert.EqualError(t, err, "sakuracloud: AccessToken is missing") -} - -// -// Present -// - -func TestLiveSakuraCloudPresent(t *testing.T) { - if !sakuracloudLiveTest { +func TestLivePresent(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - config := NewDefaultConfig() - config.Token = sakuracloudAccessToken - config.Secret = sakuracloudAccessSecret - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(sakuracloudDomain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } -// -// Cleanup -// - -func TestLiveSakuraCloudCleanUp(t *testing.T) { - if !sakuracloudLiveTest { +func TestLiveCleanUp(t *testing.T) { + if !liveTest { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - - config := NewDefaultConfig() - config.Token = sakuracloudAccessToken - config.Secret = sakuracloudAccessSecret - - provider, err := NewDNSProviderConfig(config) + restoreEnv() + provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(sakuracloudDomain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) } diff --git a/providers/dns/stackpath/stackpath_test.go b/providers/dns/stackpath/stackpath_test.go index 9ee42dc2..54ecd47d 100644 --- a/providers/dns/stackpath/stackpath_test.go +++ b/providers/dns/stackpath/stackpath_test.go @@ -13,58 +13,32 @@ import ( ) var ( - stackpathLiveTest bool - stackpathClientID string - stackpathClientSecret string - stackpathStackID string - stackpathDomain string + liveTest bool + envTestClientID string + envTestClientSecret string + envTestStackID string + envTestDomain string ) func init() { - stackpathClientID = os.Getenv("STACKPATH_CLIENT_ID") - stackpathClientSecret = os.Getenv("STACKPATH_CLIENT_SECRET") - stackpathStackID = os.Getenv("STACKPATH_STACK_ID") - stackpathDomain = os.Getenv("STACKPATH_DOMAIN") + envTestClientID = os.Getenv("STACKPATH_CLIENT_ID") + envTestClientSecret = os.Getenv("STACKPATH_CLIENT_SECRET") + envTestStackID = os.Getenv("STACKPATH_STACK_ID") + envTestDomain = os.Getenv("STACKPATH_DOMAIN") - if len(stackpathClientID) > 0 && - len(stackpathClientSecret) > 0 && - len(stackpathStackID) > 0 && - len(stackpathDomain) > 0 { - stackpathLiveTest = true + if len(envTestClientID) > 0 && + len(envTestClientSecret) > 0 && + len(envTestStackID) > 0 && + len(envTestDomain) > 0 { + liveTest = true } } func restoreEnv() { - os.Setenv("STACKPATH_CLIENT_ID", stackpathClientID) - os.Setenv("STACKPATH_CLIENT_SECRET", stackpathClientSecret) - os.Setenv("STACKPATH_STACK_ID", stackpathStackID) - os.Setenv("STACKPATH_DOMAIN", stackpathDomain) -} - -func TestLivePresent(t *testing.T) { - if !stackpathLiveTest { - t.Skip("skipping live test") - } - - provider, err := NewDNSProvider() - require.NoError(t, err) - - err = provider.Present(stackpathDomain, "", "123d==") - require.NoError(t, err) -} - -func TestLiveCleanUp(t *testing.T) { - if !stackpathLiveTest { - t.Skip("skipping live test") - } - - time.Sleep(time.Second * 1) - - provider, err := NewDNSProvider() - require.NoError(t, err) - - err = provider.CleanUp(stackpathDomain, "", "123d==") - require.NoError(t, err) + os.Setenv("STACKPATH_CLIENT_ID", envTestClientID) + os.Setenv("STACKPATH_CLIENT_SECRET", envTestClientSecret) + os.Setenv("STACKPATH_STACK_ID", envTestStackID) + os.Setenv("STACKPATH_DOMAIN", envTestDomain) } func TestNewDNSProvider(t *testing.T) { @@ -133,7 +107,7 @@ func TestNewDNSProvider(t *testing.T) { p, err := NewDNSProvider() if len(test.expected) == 0 { - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, p) } else { require.EqualError(t, err, test.expected) @@ -313,3 +287,31 @@ func TestDNSProvider_getZones(t *testing.T) { assert.Equal(t, expected, zone) } + +func TestLivePresent(t *testing.T) { + if !liveTest { + t.Skip("skipping live test") + } + + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) + + err = provider.Present(envTestDomain, "", "123d==") + require.NoError(t, err) +} + +func TestLiveCleanUp(t *testing.T) { + if !liveTest { + t.Skip("skipping live test") + } + + restoreEnv() + provider, err := NewDNSProvider() + require.NoError(t, err) + + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") + require.NoError(t, err) +} diff --git a/providers/dns/vegadns/vegadns_test.go b/providers/dns/vegadns/vegadns_test.go index 257f2dda..50af3172 100644 --- a/providers/dns/vegadns/vegadns_test.go +++ b/providers/dns/vegadns/vegadns_test.go @@ -103,14 +103,14 @@ var jsonMap = map[string]string{ type muxCallback func() *http.ServeMux -func TestVegaDNSNewDNSProviderFail(t *testing.T) { +func TestNewDNSProvider_Fail(t *testing.T) { os.Setenv("VEGADNS_URL", "") _, err := NewDNSProvider() assert.Error(t, err, "VEGADNS_URL env missing") } -func TestVegaDNSTimeoutSuccess(t *testing.T) { - ts, err := startTestServer(vegaDNSMuxSuccess) +func TestDNSProvider_TimeoutSuccess(t *testing.T) { + ts, err := startTestServer(muxSuccess) require.NoError(t, err) defer ts.Close() @@ -132,16 +132,16 @@ func TestDNSProvider_Present(t *testing.T) { }{ { desc: "Success", - callback: vegaDNSMuxSuccess, + callback: muxSuccess, }, { desc: "FailToFindZone", - callback: vegaDNSMuxFailToFindZone, + callback: muxFailToFindZone, expectedError: "vegadns: can't find Authoritative Zone for _acme-challenge.example.com. in Present: Unable to find auth zone for fqdn _acme-challenge.example.com", }, { desc: "FailToCreateTXT", - callback: vegaDNSMuxFailToCreateTXT, + callback: muxFailToCreateTXT, expectedError: "vegadns: Got bad answer from VegaDNS on CreateTXT. Code: 400. Message: ", }, } @@ -175,16 +175,16 @@ func TestDNSProvider_CleanUp(t *testing.T) { }{ { desc: "Success", - callback: vegaDNSMuxSuccess, + callback: muxSuccess, }, { desc: "FailToFindZone", - callback: vegaDNSMuxFailToFindZone, + callback: muxFailToFindZone, expectedError: "vegadns: can't find Authoritative Zone for _acme-challenge.example.com. in CleanUp: Unable to find auth zone for fqdn _acme-challenge.example.com", }, { desc: "FailToGetRecordID", - callback: vegaDNSMuxFailToGetRecordID, + callback: muxFailToGetRecordID, expectedError: "vegadns: couldn't get Record ID in CleanUp: Got bad answer from VegaDNS on GetRecordID. Code: 404. Message: ", }, } @@ -210,7 +210,7 @@ func TestDNSProvider_CleanUp(t *testing.T) { } } -func vegaDNSMuxSuccess() *http.ServeMux { +func muxSuccess() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/1.0/token", func(w http.ResponseWriter, r *http.Request) { @@ -268,7 +268,7 @@ func vegaDNSMuxSuccess() *http.ServeMux { return mux } -func vegaDNSMuxFailToFindZone() *http.ServeMux { +func muxFailToFindZone() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/1.0/token", func(w http.ResponseWriter, r *http.Request) { @@ -288,7 +288,7 @@ func vegaDNSMuxFailToFindZone() *http.ServeMux { return mux } -func vegaDNSMuxFailToCreateTXT() *http.ServeMux { +func muxFailToCreateTXT() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/1.0/token", func(w http.ResponseWriter, r *http.Request) { @@ -330,7 +330,7 @@ func vegaDNSMuxFailToCreateTXT() *http.ServeMux { return mux } -func vegaDNSMuxFailToGetRecordID() *http.ServeMux { +func muxFailToGetRecordID() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/1.0/token", func(w http.ResponseWriter, r *http.Request) { diff --git a/providers/dns/vultr/vultr_test.go b/providers/dns/vultr/vultr_test.go index 0f045c01..2d7fe58c 100644 --- a/providers/dns/vultr/vultr_test.go +++ b/providers/dns/vultr/vultr_test.go @@ -5,40 +5,108 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - liveTest bool - apiKey string - domain string + liveTest bool + envTestAPIKey string + envTestDomain string ) func init() { - apiKey = os.Getenv("VULTR_API_KEY") - domain = os.Getenv("VULTR_TEST_DOMAIN") - liveTest = len(apiKey) > 0 && len(domain) > 0 + envTestAPIKey = os.Getenv("VULTR_API_KEY") + envTestDomain = os.Getenv("VULTR_TEST_DOMAIN") + + liveTest = len(envTestAPIKey) > 0 && len(envTestDomain) > 0 } func restoreEnv() { - os.Setenv("VULTR_API_KEY", apiKey) + os.Setenv("VULTR_API_KEY", envTestAPIKey) } -func TestNewDNSProviderValidEnv(t *testing.T) { - defer restoreEnv() - os.Setenv("VULTR_API_KEY", "123") +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + "VULTR_API_KEY": "123", + }, + }, + { + desc: "missing api key", + envVars: map[string]string{ + "VULTR_API_KEY": "", + }, + expected: "vultr: some credentials information are missing: VULTR_API_KEY", + }, + } - _, err := NewDNSProvider() - require.NoError(t, err) + 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) + } + } + + p, err := NewDNSProvider() + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } -func TestNewDNSProviderMissingCredErr(t *testing.T) { - defer restoreEnv() - os.Setenv("VULTR_API_KEY", "") +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiKey string + expected string + }{ + { + desc: "success", + apiKey: "123", + }, + { + desc: "missing credentials", + expected: "vultr: credentials missing", + }, + } - _, err := NewDNSProvider() - assert.EqualError(t, err, "vultr: some credentials information are missing: VULTR_API_KEY") + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer restoreEnv() + os.Unsetenv("VULTR_API_KEY") + + config := NewDefaultConfig() + config.APIKey = test.apiKey + + p, err := NewDNSProviderConfig(config) + + if len(test.expected) == 0 { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } } func TestLivePresent(t *testing.T) { @@ -46,10 +114,11 @@ func TestLivePresent(t *testing.T) { t.Skip("skipping live test") } + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.Present(domain, "", "123d==") + err = provider.Present(envTestDomain, "", "123d==") require.NoError(t, err) } @@ -58,11 +127,12 @@ func TestLiveCleanUp(t *testing.T) { t.Skip("skipping live test") } - time.Sleep(time.Second * 1) - + restoreEnv() provider, err := NewDNSProvider() require.NoError(t, err) - err = provider.CleanUp(domain, "", "123d==") + time.Sleep(1 * time.Second) + + err = provider.CleanUp(envTestDomain, "", "123d==") require.NoError(t, err) }