diff --git a/pkg/issuer/acme/dns/akamai/akamai.go b/pkg/issuer/acme/dns/akamai/akamai.go index 166d67f26..724560d4f 100644 --- a/pkg/issuer/acme/dns/akamai/akamai.go +++ b/pkg/issuer/acme/dns/akamai/akamai.go @@ -37,6 +37,7 @@ import ( // DNSProvider is an implementation of the acme.ChallengeProvider interface type DNSProvider struct { + dns01Nameservers []string // serviceConsumerDomain as issued by Akamai Luna Control Center. // The ServiceConsumerDomain is the base URL. serviceConsumerDomain string @@ -48,8 +49,9 @@ type DNSProvider struct { } // NewDNSProvider returns a DNSProvider instance configured for Akamai. -func NewDNSProvider(serviceConsumerDomain, clientToken, clientSecret, accessToken string) (*DNSProvider, error) { +func NewDNSProvider(serviceConsumerDomain, clientToken, clientSecret, accessToken string, dns01Nameservers []string) (*DNSProvider, error) { return &DNSProvider{ + dns01Nameservers, serviceConsumerDomain, NewEdgeGridAuth(clientToken, clientSecret, accessToken), http.DefaultTransport, @@ -74,7 +76,7 @@ func (a *DNSProvider) Timeout() (timeout, interval time.Duration) { // Present creates a TXT record to fulfil the dns-01 challenge func (a *DNSProvider) Present(domain, token, keyAuth string) error { - fqdn, value, ttl, err := util.DNS01Record(domain, keyAuth) + fqdn, value, ttl, err := util.DNS01Record(domain, keyAuth, a.dns01Nameservers) if err != nil { return err } @@ -84,7 +86,7 @@ func (a *DNSProvider) Present(domain, token, keyAuth string) error { // CleanUp removes the TXT record matching the specified parameters func (a *DNSProvider) CleanUp(domain, token, keyAuth string) error { - fqdn, _, _, err := util.DNS01Record(domain, keyAuth) + fqdn, _, _, err := util.DNS01Record(domain, keyAuth, a.dns01Nameservers) if err != nil { return err } diff --git a/pkg/issuer/acme/dns/akamai/akamai_test.go b/pkg/issuer/acme/dns/akamai/akamai_test.go index 444f61431..afb81e4e6 100644 --- a/pkg/issuer/acme/dns/akamai/akamai_test.go +++ b/pkg/issuer/acme/dns/akamai/akamai_test.go @@ -24,6 +24,7 @@ import ( "strings" "testing" + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" "github.com/stretchr/testify/assert" ) @@ -104,7 +105,7 @@ func (r httpResponder) RoundTrip(req *http.Request) (*http.Response, error) { } func TestPresent(t *testing.T) { - akamai, err := NewDNSProvider("akamai.example.com", "token", "secret", "access-token") + akamai, err := NewDNSProvider("akamai.example.com", "token", "secret", "access-token", util.RecursiveNameservers) assert.NoError(t, err) var response []byte @@ -119,7 +120,7 @@ func TestPresent(t *testing.T) { } func TestCleanUp(t *testing.T) { - akamai, err := NewDNSProvider("akamai.example.com", "token", "secret", "access-token") + akamai, err := NewDNSProvider("akamai.example.com", "token", "secret", "access-token", util.RecursiveNameservers) assert.NoError(t, err) var response []byte diff --git a/pkg/issuer/acme/dns/azuredns/azuredns.go b/pkg/issuer/acme/dns/azuredns/azuredns.go index b4b2e3ccd..885a882bd 100644 --- a/pkg/issuer/acme/dns/azuredns/azuredns.go +++ b/pkg/issuer/acme/dns/azuredns/azuredns.go @@ -27,6 +27,7 @@ import ( // DNSProvider implements the util.ChallengeProvider interface type DNSProvider struct { + dns01Nameservers []string recordClient dns.RecordSetsClient zoneClient dns.ZonesClient resourceGroupName string @@ -36,7 +37,7 @@ type DNSProvider struct { // NewDNSProvider returns a DNSProvider instance configured for the Azure // DNS service. // Credentials are automatically detected from environment variables -func NewDNSProvider() (*DNSProvider, error) { +func NewDNSProvider(dns01Nameservers []string) (*DNSProvider, error) { clientID := os.Getenv("AZURE_CLIENT_ID") clientSecret := os.Getenv("AZURE_CLIENT_SECRET") @@ -45,12 +46,12 @@ func NewDNSProvider() (*DNSProvider, error) { resourceGroupName := ("AZURE_RESOURCE_GROUP") zoneName := ("AZURE_ZONE_NAME") - return NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, zoneName) + return NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, zoneName, dns01Nameservers) } // NewDNSProviderCredentials returns a DNSProvider instance configured for the Azure // DNS service using static credentials from its parameters -func NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, zoneName string) (*DNSProvider, error) { +func NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, zoneName string, dns01Nameservers []string) (*DNSProvider, error) { oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, tenantID) if err != nil { return nil, err @@ -68,6 +69,7 @@ func NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, zc.Authorizer = autorest.NewBearerAuthorizer(spt) return &DNSProvider{ + dns01Nameservers: dns01Nameservers, recordClient: rc, zoneClient: zc, resourceGroupName: resourceGroupName, @@ -77,7 +79,7 @@ func NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, // Present creates a TXT record using the specified parameters func (c *DNSProvider) Present(domain, token, keyAuth string) error { - fqdn, value, ttl, err := util.DNS01Record(domain, keyAuth) + fqdn, value, ttl, err := util.DNS01Record(domain, keyAuth, c.dns01Nameservers) if err != nil { return err } @@ -87,7 +89,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error { // CleanUp removes the TXT record matching the specified parameters func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error { - fqdn, _, _, err := util.DNS01Record(domain, keyAuth) + fqdn, _, _, err := util.DNS01Record(domain, keyAuth, c.dns01Nameservers) if err != nil { return err } diff --git a/pkg/issuer/acme/dns/azuredns/azuredns_test.go b/pkg/issuer/acme/dns/azuredns/azuredns_test.go index f5886297f..a2b414bad 100644 --- a/pkg/issuer/acme/dns/azuredns/azuredns_test.go +++ b/pkg/issuer/acme/dns/azuredns/azuredns_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" "github.com/stretchr/testify/assert" ) @@ -44,7 +45,7 @@ func TestLiveAzureDnsPresent(t *testing.T) { if !azureLiveTest { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName) + provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName, util.RecursiveNameservers) assert.NoError(t, err) err = provider.Present(azureDomain, "", "123d==") @@ -58,7 +59,7 @@ func TestLiveAzureDnsCleanUp(t *testing.T) { time.Sleep(time.Second * 5) - provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName) + provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName, util.RecursiveNameservers) assert.NoError(t, err) err = provider.CleanUp(azureDomain, "", "123d==") diff --git a/pkg/issuer/acme/dns/clouddns/clouddns.go b/pkg/issuer/acme/dns/clouddns/clouddns.go index 6d75dadd3..6d0a2927e 100644 --- a/pkg/issuer/acme/dns/clouddns/clouddns.go +++ b/pkg/issuer/acme/dns/clouddns/clouddns.go @@ -26,25 +26,26 @@ import ( // DNSProvider is an implementation of the DNSProvider interface. type DNSProvider struct { - project string - client *dns.Service + dns01Nameservers []string + project string + client *dns.Service } // NewDNSProvider returns a DNSProvider instance configured for Google Cloud // DNS. Project name must be passed in the environment variable: GCE_PROJECT. // A Service Account file can be passed in the environment variable: // GCE_SERVICE_ACCOUNT_FILE -func NewDNSProvider() (*DNSProvider, error) { +func NewDNSProvider(dns01Nameservers []string) (*DNSProvider, error) { project := os.Getenv("GCE_PROJECT") if saFile, ok := os.LookupEnv("GCE_SERVICE_ACCOUNT_FILE"); ok { - return NewDNSProviderServiceAccount(project, saFile) + return NewDNSProviderServiceAccount(project, saFile, dns01Nameservers) } - return NewDNSProviderCredentials(project) + return NewDNSProviderCredentials(project, dns01Nameservers) } // NewDNSProviderCredentials uses the supplied credentials to return a // DNSProvider instance configured for Google Cloud DNS. -func NewDNSProviderCredentials(project string) (*DNSProvider, error) { +func NewDNSProviderCredentials(project string, dns01Nameservers []string) (*DNSProvider, error) { if project == "" { return nil, fmt.Errorf("Google Cloud project name missing") } @@ -58,14 +59,15 @@ func NewDNSProviderCredentials(project string) (*DNSProvider, error) { return nil, fmt.Errorf("Unable to create Google Cloud DNS service: %v", err) } return &DNSProvider{ - project: project, - client: svc, + project: project, + client: svc, + dns01Nameservers: dns01Nameservers, }, nil } // NewDNSProviderServiceAccount uses the supplied service account JSON file to // return a DNSProvider instance configured for Google Cloud DNS. -func NewDNSProviderServiceAccount(project string, saFile string) (*DNSProvider, error) { +func NewDNSProviderServiceAccount(project string, saFile string, dns01Nameservers []string) (*DNSProvider, error) { if project == "" { return nil, fmt.Errorf("Google Cloud project name missing") } @@ -77,12 +79,12 @@ func NewDNSProviderServiceAccount(project string, saFile string) (*DNSProvider, if err != nil { return nil, fmt.Errorf("Unable to read Service Account file: %v", err) } - return NewDNSProviderServiceAccountBytes(project, dat) + return NewDNSProviderServiceAccountBytes(project, dat, dns01Nameservers) } // NewDNSProviderServiceAccountBytes uses the supplied service account JSON // file data to return a DNSProvider instance configured for Google Cloud DNS. -func NewDNSProviderServiceAccountBytes(project string, saBytes []byte) (*DNSProvider, error) { +func NewDNSProviderServiceAccountBytes(project string, saBytes []byte, dns01Nameservers []string) (*DNSProvider, error) { if project == "" { return nil, fmt.Errorf("Google Cloud project name missing") } @@ -101,14 +103,15 @@ func NewDNSProviderServiceAccountBytes(project string, saBytes []byte) (*DNSProv return nil, fmt.Errorf("Unable to create Google Cloud DNS service: %v", err) } return &DNSProvider{ - project: project, - client: svc, + project: project, + client: svc, + dns01Nameservers: dns01Nameservers, }, nil } // Present creates a TXT record to fulfil the dns-01 challenge. func (c *DNSProvider) Present(domain, token, key string) error { - fqdn, value, ttl, err := util.DNS01Record(domain, key) + fqdn, value, ttl, err := util.DNS01Record(domain, key, c.dns01Nameservers) if err != nil { return err } @@ -158,7 +161,7 @@ func (c *DNSProvider) Present(domain, token, key string) error { // CleanUp removes the TXT record matching the specified parameters. func (c *DNSProvider) CleanUp(domain, token, key string) error { - fqdn, _, _, err := util.DNS01Record(domain, key) + fqdn, _, _, err := util.DNS01Record(domain, key, c.dns01Nameservers) if err != nil { return err } diff --git a/pkg/issuer/acme/dns/clouddns/clouddns_test.go b/pkg/issuer/acme/dns/clouddns/clouddns_test.go index 7358caa32..a936ae3f1 100644 --- a/pkg/issuer/acme/dns/clouddns/clouddns_test.go +++ b/pkg/issuer/acme/dns/clouddns/clouddns_test.go @@ -17,6 +17,7 @@ import ( "golang.org/x/oauth2/google" "google.golang.org/api/dns/v1" + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" "github.com/stretchr/testify/assert" ) @@ -44,7 +45,7 @@ func TestNewDNSProviderValid(t *testing.T) { t.Skip("skipping live test (requires credentials)") } os.Setenv("GCE_PROJECT", "") - _, err := NewDNSProviderCredentials("my-project") + _, err := NewDNSProviderCredentials("my-project", util.RecursiveNameservers) assert.NoError(t, err) restoreGCloudEnv() } @@ -54,14 +55,14 @@ func TestNewDNSProviderValidEnv(t *testing.T) { t.Skip("skipping live test (requires credentials)") } os.Setenv("GCE_PROJECT", "my-project") - _, err := NewDNSProvider() + _, err := NewDNSProvider(util.RecursiveNameservers) assert.NoError(t, err) restoreGCloudEnv() } func TestNewDNSProviderMissingCredErr(t *testing.T) { os.Setenv("GCE_PROJECT", "") - _, err := NewDNSProvider() + _, err := NewDNSProvider(util.RecursiveNameservers) assert.EqualError(t, err, "Google Cloud project name missing") restoreGCloudEnv() } @@ -71,7 +72,7 @@ func TestLiveGoogleCloudPresent(t *testing.T) { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(gcloudProject) + provider, err := NewDNSProviderCredentials(gcloudProject, util.RecursiveNameservers) assert.NoError(t, err) err = provider.Present(gcloudDomain, "", "123d==") @@ -83,7 +84,7 @@ func TestLiveGoogleCloudPresentMultiple(t *testing.T) { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(gcloudProject) + provider, err := NewDNSProviderCredentials(gcloudProject, util.RecursiveNameservers) assert.NoError(t, err) // Check that we're able to create multiple entries @@ -99,7 +100,7 @@ func TestLiveGoogleCloudCleanUp(t *testing.T) { time.Sleep(time.Second * 1) - provider, err := NewDNSProviderCredentials(gcloudProject) + provider, err := NewDNSProviderCredentials(gcloudProject, util.RecursiveNameservers) assert.NoError(t, err) err = provider.CleanUp(gcloudDomain, "", "123d==") diff --git a/pkg/issuer/acme/dns/cloudflare/cloudflare.go b/pkg/issuer/acme/dns/cloudflare/cloudflare.go index c06e621f9..41756d506 100644 --- a/pkg/issuer/acme/dns/cloudflare/cloudflare.go +++ b/pkg/issuer/acme/dns/cloudflare/cloudflare.go @@ -30,29 +30,31 @@ const CloudFlareAPIURL = "https://api.cloudflare.com/client/v4" // DNSProvider is an implementation of the acme.ChallengeProvider interface type DNSProvider struct { - authEmail string - authKey string + dns01Nameservers []string + authEmail string + authKey string } // NewDNSProvider returns a DNSProvider instance configured for cloudflare. // Credentials must be passed in the environment variables: CLOUDFLARE_EMAIL // and CLOUDFLARE_API_KEY. -func NewDNSProvider() (*DNSProvider, error) { +func NewDNSProvider(dns01Nameservers []string) (*DNSProvider, error) { email := os.Getenv("CLOUDFLARE_EMAIL") key := os.Getenv("CLOUDFLARE_API_KEY") - return NewDNSProviderCredentials(email, key) + return NewDNSProviderCredentials(email, key, dns01Nameservers) } // NewDNSProviderCredentials uses the supplied credentials to return a // DNSProvider instance configured for cloudflare. -func NewDNSProviderCredentials(email, key string) (*DNSProvider, error) { +func NewDNSProviderCredentials(email, key string, dns01Nameservers []string) (*DNSProvider, error) { if email == "" || key == "" { return nil, fmt.Errorf("CloudFlare credentials missing") } return &DNSProvider{ - authEmail: email, - authKey: key, + authEmail: email, + authKey: key, + dns01Nameservers: dns01Nameservers, }, nil } @@ -64,7 +66,7 @@ func (c *DNSProvider) Timeout() (timeout, interval time.Duration) { // Present creates a TXT record to fulfil the dns-01 challenge func (c *DNSProvider) Present(domain, token, keyAuth string) error { - fqdn, value, _, err := util.DNS01Record(domain, keyAuth) + fqdn, value, _, err := util.DNS01Record(domain, keyAuth, c.dns01Nameservers) if err != nil { return err } @@ -113,7 +115,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error { // CleanUp removes the TXT record matching the specified parameters func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error { - fqdn, _, _, err := util.DNS01Record(domain, keyAuth) + fqdn, _, _, err := util.DNS01Record(domain, keyAuth, c.dns01Nameservers) if err != nil { return err } diff --git a/pkg/issuer/acme/dns/cloudflare/cloudflare_test.go b/pkg/issuer/acme/dns/cloudflare/cloudflare_test.go index d528cc10f..26f6b8e60 100644 --- a/pkg/issuer/acme/dns/cloudflare/cloudflare_test.go +++ b/pkg/issuer/acme/dns/cloudflare/cloudflare_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" "github.com/stretchr/testify/assert" ) @@ -40,7 +41,7 @@ func restoreCloudFlareEnv() { func TestNewDNSProviderValid(t *testing.T) { os.Setenv("CLOUDFLARE_EMAIL", "") os.Setenv("CLOUDFLARE_API_KEY", "") - _, err := NewDNSProviderCredentials("123", "123") + _, err := NewDNSProviderCredentials("123", "123", util.RecursiveNameservers) assert.NoError(t, err) restoreCloudFlareEnv() } @@ -48,7 +49,7 @@ func TestNewDNSProviderValid(t *testing.T) { func TestNewDNSProviderValidEnv(t *testing.T) { os.Setenv("CLOUDFLARE_EMAIL", "test@example.com") os.Setenv("CLOUDFLARE_API_KEY", "123") - _, err := NewDNSProvider() + _, err := NewDNSProvider(util.RecursiveNameservers) assert.NoError(t, err) restoreCloudFlareEnv() } @@ -56,7 +57,7 @@ func TestNewDNSProviderValidEnv(t *testing.T) { func TestNewDNSProviderMissingCredErr(t *testing.T) { os.Setenv("CLOUDFLARE_EMAIL", "") os.Setenv("CLOUDFLARE_API_KEY", "") - _, err := NewDNSProvider() + _, err := NewDNSProvider(util.RecursiveNameservers) assert.EqualError(t, err, "CloudFlare credentials missing") restoreCloudFlareEnv() } @@ -66,7 +67,7 @@ func TestCloudFlarePresent(t *testing.T) { t.Skip("skipping live test") } - provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey) + provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey, util.RecursiveNameservers) assert.NoError(t, err) err = provider.Present(cflareDomain, "", "123d==") @@ -80,7 +81,7 @@ func TestCloudFlareCleanUp(t *testing.T) { time.Sleep(time.Second * 2) - provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey) + provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey, util.RecursiveNameservers) assert.NoError(t, err) err = provider.CleanUp(cflareDomain, "", "123d==") diff --git a/pkg/issuer/acme/dns/dns.go b/pkg/issuer/acme/dns/dns.go index 24b0dac3e..3e74179fc 100644 --- a/pkg/issuer/acme/dns/dns.go +++ b/pkg/issuer/acme/dns/dns.go @@ -50,10 +50,10 @@ type solver interface { // It is useful for mocking out a given provider since an alternate set of // constructors may be set. type dnsProviderConstructors struct { - cloudDNS func(project string, serviceAccount []byte) (*clouddns.DNSProvider, error) - cloudFlare func(email, apikey string) (*cloudflare.DNSProvider, error) - route53 func(accessKey, secretKey, hostedZoneID, region string, ambient bool) (*route53.DNSProvider, error) - azureDNS func(clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName string) (*azuredns.DNSProvider, error) + cloudDNS func(project string, serviceAccount []byte, dns01Nameservers []string) (*clouddns.DNSProvider, error) + cloudFlare func(email, apikey string, dns01Nameservers []string) (*cloudflare.DNSProvider, error) + route53 func(accessKey, secretKey, hostedZoneID, region string, ambient bool, dns01Nameservers []string) (*route53.DNSProvider, error) + azureDNS func(clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName string, dns01Nameservers []string) (*azuredns.DNSProvider, error) } // Solver is a solver for the acme dns01 challenge. @@ -85,7 +85,7 @@ func (s *Solver) Present(ctx context.Context, issuer v1alpha1.GenericIssuer, _ * } func (s *Solver) Check(ch v1alpha1.ACMEOrderChallenge) (bool, error) { - fqdn, value, ttl, err := util.DNS01Record(ch.Domain, ch.Key) + fqdn, value, ttl, err := util.DNS01Record(ch.Domain, ch.Key, s.DNS01Nameservers) if err != nil { return false, err } @@ -163,7 +163,8 @@ func (s *Solver) solverForIssuerProvider(issuer v1alpha1.GenericIssuer, provider providerConfig.Akamai.ServiceConsumerDomain, string(clientToken), string(clientSecret), - string(accessToken)) + string(accessToken), + s.DNS01Nameservers) if err != nil { return nil, errors.Wrap(err, "error instantiating akamai challenge solver") } @@ -180,7 +181,7 @@ func (s *Solver) solverForIssuerProvider(issuer v1alpha1.GenericIssuer, provider return nil, fmt.Errorf("specfied key %q not found in secret %s/%s", saKey, saSecret.Namespace, saSecret.Name) } - impl, err = s.dnsProviderConstructors.cloudDNS(providerConfig.CloudDNS.Project, saBytes) + impl, err = s.dnsProviderConstructors.cloudDNS(providerConfig.CloudDNS.Project, saBytes, s.DNS01Nameservers) if err != nil { return nil, fmt.Errorf("error instantiating google clouddns challenge solver: %s", err) } @@ -193,7 +194,7 @@ func (s *Solver) solverForIssuerProvider(issuer v1alpha1.GenericIssuer, provider email := providerConfig.Cloudflare.Email apiKey := string(apiKeySecret.Data[providerConfig.Cloudflare.APIKey.Key]) - impl, err = s.dnsProviderConstructors.cloudFlare(email, apiKey) + impl, err = s.dnsProviderConstructors.cloudFlare(email, apiKey, s.DNS01Nameservers) if err != nil { return nil, fmt.Errorf("error instantiating cloudflare challenge solver: %s", err) } @@ -218,6 +219,7 @@ func (s *Solver) solverForIssuerProvider(issuer v1alpha1.GenericIssuer, provider providerConfig.Route53.HostedZoneID, providerConfig.Route53.Region, s.CanUseAmbientCredentials(issuer), + s.DNS01Nameservers, ) if err != nil { return nil, fmt.Errorf("error instantiating route53 challenge solver: %s", err) @@ -240,6 +242,7 @@ func (s *Solver) solverForIssuerProvider(issuer v1alpha1.GenericIssuer, provider providerConfig.AzureDNS.TenantID, providerConfig.AzureDNS.ResourceGroupName, providerConfig.AzureDNS.HostedZoneName, + s.DNS01Nameservers, ) default: return nil, fmt.Errorf("no dns provider config specified for provider %q", providerName) diff --git a/pkg/issuer/acme/dns/dns_test.go b/pkg/issuer/acme/dns/dns_test.go index 042ffcc40..11661d6bf 100644 --- a/pkg/issuer/acme/dns/dns_test.go +++ b/pkg/issuer/acme/dns/dns_test.go @@ -28,6 +28,7 @@ import ( "github.com/jetstack/cert-manager/pkg/controller" "github.com/jetstack/cert-manager/pkg/controller/test" "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/cloudflare" + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" ) func newIssuer(name, namespace string, configs []v1alpha1.ACMEIssuerDNS01Provider) *v1alpha1.Issuer { @@ -276,7 +277,7 @@ func TestRoute53TrimCreds(t *testing.T) { expectedR53Call := []fakeDNSProviderCall{ { name: "route53", - args: []interface{}{"test_with_spaces", "AKIENDINNEWLINE", "", "us-west-2", false}, + args: []interface{}{"test_with_spaces", "AKIENDINNEWLINE", "", "us-west-2", false, util.RecursiveNameservers}, }, } @@ -324,7 +325,7 @@ func TestRoute53AmbientCreds(t *testing.T) { result{ expectedCall: &fakeDNSProviderCall{ name: "route53", - args: []interface{}{"", "", "", "us-west-2", true}, + args: []interface{}{"", "", "", "us-west-2", true, util.RecursiveNameservers}, }, }, }, @@ -357,7 +358,7 @@ func TestRoute53AmbientCreds(t *testing.T) { result{ expectedCall: &fakeDNSProviderCall{ name: "route53", - args: []interface{}{"", "", "", "us-west-2", false}, + args: []interface{}{"", "", "", "us-west-2", false, util.RecursiveNameservers}, }, }, }, diff --git a/pkg/issuer/acme/dns/route53/route53.go b/pkg/issuer/acme/dns/route53/route53.go index 30c554cd8..0e2350166 100644 --- a/pkg/issuer/acme/dns/route53/route53.go +++ b/pkg/issuer/acme/dns/route53/route53.go @@ -36,8 +36,9 @@ const ( // DNSProvider implements the util.ChallengeProvider interface type DNSProvider struct { - client *route53.Route53 - hostedZoneID string + dns01Nameservers []string + client *route53.Route53 + hostedZoneID string } // customRetryer implements the client.Retryer interface by composing the @@ -65,7 +66,7 @@ func (d customRetryer) RetryRules(r *request.Request) time.Duration { // NewDNSProvider returns a DNSProvider instance configured for the AWS // Route 53 service using static credentials from its parameters or, if they're // unset and the 'ambient' option is set, credentials from the environment. -func NewDNSProvider(accessKeyID, secretAccessKey, hostedZoneID, region string, ambient bool) (*DNSProvider, error) { +func NewDNSProvider(accessKeyID, secretAccessKey, hostedZoneID, region string, ambient bool, dns01Nameservers []string) (*DNSProvider, error) { if accessKeyID == "" && secretAccessKey == "" { if !ambient { return nil, fmt.Errorf("unable to construct route53 provider: empty credentials; perhaps you meant to enable ambient credentials?") @@ -107,8 +108,9 @@ func NewDNSProvider(accessKeyID, secretAccessKey, hostedZoneID, region string, a client := route53.New(sess, config) return &DNSProvider{ - client: client, - hostedZoneID: hostedZoneID, + client: client, + hostedZoneID: hostedZoneID, + dns01Nameservers: dns01Nameservers, }, nil } @@ -120,7 +122,7 @@ func (*DNSProvider) Timeout() (timeout, interval time.Duration) { // Present creates a TXT record using the specified parameters func (r *DNSProvider) Present(domain, token, keyAuth string) error { - fqdn, value, _, err := util.DNS01Record(domain, keyAuth) + fqdn, value, _, err := util.DNS01Record(domain, keyAuth, r.dns01Nameservers) if err != nil { return err } @@ -131,7 +133,7 @@ func (r *DNSProvider) Present(domain, token, keyAuth string) error { // CleanUp removes the TXT record matching the specified parameters func (r *DNSProvider) CleanUp(domain, token, keyAuth string) error { - fqdn, value, _, err := util.DNS01Record(domain, keyAuth) + fqdn, value, _, err := util.DNS01Record(domain, keyAuth, r.dns01Nameservers) if err != nil { return err } diff --git a/pkg/issuer/acme/dns/route53/route53_test.go b/pkg/issuer/acme/dns/route53/route53_test.go index 06a1b7dc7..db45dc78e 100644 --- a/pkg/issuer/acme/dns/route53/route53_test.go +++ b/pkg/issuer/acme/dns/route53/route53_test.go @@ -18,6 +18,8 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/route53" "github.com/stretchr/testify/assert" + + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" ) var ( @@ -48,7 +50,7 @@ func makeRoute53Provider(ts *httptest.Server) *DNSProvider { } client := route53.New(session.New(config)) - return &DNSProvider{client: client} + return &DNSProvider{client: client, dns01Nameservers: util.RecursiveNameservers} } func TestAmbientCredentialsFromEnv(t *testing.T) { @@ -57,7 +59,7 @@ func TestAmbientCredentialsFromEnv(t *testing.T) { os.Setenv("AWS_REGION", "us-east-1") defer restoreRoute53Env() - provider, err := NewDNSProvider("", "", "", "", true) + provider, err := NewDNSProvider("", "", "", "", true, util.RecursiveNameservers) assert.NoError(t, err, "Expected no error constructing DNSProvider") _, err = provider.client.Config.Credentials.Get() @@ -71,7 +73,7 @@ func TestNoCredentialsFromEnv(t *testing.T) { os.Setenv("AWS_REGION", "us-east-1") defer restoreRoute53Env() - _, err := NewDNSProvider("", "", "", "", false) + _, err := NewDNSProvider("", "", "", "", false, util.RecursiveNameservers) assert.Error(t, err, "Expected error constructing DNSProvider with no credentials and not ambient") } @@ -79,7 +81,7 @@ func TestAmbientRegionFromEnv(t *testing.T) { os.Setenv("AWS_REGION", "us-east-1") defer restoreRoute53Env() - provider, err := NewDNSProvider("", "", "", "", true) + provider, err := NewDNSProvider("", "", "", "", true, util.RecursiveNameservers) assert.NoError(t, err, "Expected no error constructing DNSProvider") assert.Equal(t, "us-east-1", *provider.client.Config.Region, "Expected Region to be set from environment") @@ -89,7 +91,7 @@ func TestNoRegionFromEnv(t *testing.T) { os.Setenv("AWS_REGION", "us-east-1") defer restoreRoute53Env() - provider, err := NewDNSProvider("marx", "swordfish", "", "", false) + provider, err := NewDNSProvider("marx", "swordfish", "", "", false, util.RecursiveNameservers) assert.NoError(t, err, "Expected no error constructing DNSProvider") assert.Equal(t, "", *provider.client.Config.Region, "Expected Region to not be set from environment") diff --git a/pkg/issuer/acme/dns/util/dns.go b/pkg/issuer/acme/dns/util/dns.go index ff00f3133..03ddadb1f 100644 --- a/pkg/issuer/acme/dns/util/dns.go +++ b/pkg/issuer/acme/dns/util/dns.go @@ -16,11 +16,11 @@ import ( // DNS01Record returns a DNS record which will fulfill the `dns-01` challenge // TODO: move this into a non-generic place by resolving import cycle in dns package -func DNS01Record(domain, value string) (string, string, int, error) { +func DNS01Record(domain, value string, nameservers []string) (string, string, int, error) { fqdn := fmt.Sprintf("_acme-challenge.%s.", domain) // Check if the domain has CNAME then return that - r, err := dnsQuery(fqdn, dns.TypeCNAME, RecursiveNameservers, true) + r, err := dnsQuery(fqdn, dns.TypeCNAME, nameservers, true) if err == nil && r.Rcode == dns.RcodeSuccess { fqdn = updateDomainWithCName(r, fqdn) } diff --git a/pkg/issuer/acme/dns/util/wait.go b/pkg/issuer/acme/dns/util/wait.go index 862522ae6..f36db6bf8 100644 --- a/pkg/issuer/acme/dns/util/wait.go +++ b/pkg/issuer/acme/dns/util/wait.go @@ -84,7 +84,7 @@ func checkDNSPropagation(fqdn, value string, nameservers []string) (bool, error) fqdn = updateDomainWithCName(r, fqdn) } - authoritativeNss, err := lookupNameservers(fqdn) + authoritativeNss, err := lookupNameservers(fqdn, nameservers) if err != nil { return false, err } @@ -155,15 +155,15 @@ func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive bool) ( } // lookupNameservers returns the authoritative nameservers for the given fqdn. -func lookupNameservers(fqdn string) ([]string, error) { +func lookupNameservers(fqdn string, nameservers []string) ([]string, error) { var authoritativeNss []string - zone, err := FindZoneByFqdn(fqdn, RecursiveNameservers) + zone, err := FindZoneByFqdn(fqdn, nameservers) if err != nil { return nil, fmt.Errorf("Could not determine the zone: %v", err) } - r, err := dnsQuery(zone, dns.TypeNS, RecursiveNameservers, true) + r, err := dnsQuery(zone, dns.TypeNS, nameservers, true) if err != nil { return nil, err } diff --git a/pkg/issuer/acme/dns/util/wait_test.go b/pkg/issuer/acme/dns/util/wait_test.go index f0d8387a5..14c7c7b68 100644 --- a/pkg/issuer/acme/dns/util/wait_test.go +++ b/pkg/issuer/acme/dns/util/wait_test.go @@ -99,7 +99,7 @@ func TestPreCheckDNS(t *testing.T) { func TestLookupNameserversOK(t *testing.T) { for _, tt := range lookupNameserversTestsOK { - nss, err := lookupNameservers(tt.fqdn) + nss, err := lookupNameservers(tt.fqdn, RecursiveNameservers) if err != nil { t.Fatalf("#%s: got %q; want nil", tt.fqdn, err) } @@ -115,7 +115,7 @@ func TestLookupNameserversOK(t *testing.T) { func TestLookupNameserversErr(t *testing.T) { for _, tt := range lookupNameserversTestsErr { - _, err := lookupNameservers(tt.fqdn) + _, err := lookupNameservers(tt.fqdn, RecursiveNameservers) if err == nil { t.Fatalf("#%s: expected %q (error); got ", tt.fqdn, tt.error) } diff --git a/pkg/issuer/acme/dns/util_test.go b/pkg/issuer/acme/dns/util_test.go index 9e6a10ca3..f90045168 100644 --- a/pkg/issuer/acme/dns/util_test.go +++ b/pkg/issuer/acme/dns/util_test.go @@ -28,6 +28,7 @@ import ( "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/clouddns" "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/cloudflare" "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/route53" + "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" ) const ( @@ -134,23 +135,23 @@ func newFakeDNSProviders() *fakeDNSProviders { calls: []fakeDNSProviderCall{}, } f.constructors = dnsProviderConstructors{ - cloudDNS: func(project string, serviceAccount []byte) (*clouddns.DNSProvider, error) { - f.call("clouddns", project, serviceAccount) + cloudDNS: func(project string, serviceAccount []byte, dns01Nameservers []string) (*clouddns.DNSProvider, error) { + f.call("clouddns", project, serviceAccount, util.RecursiveNameservers) return nil, nil }, - cloudFlare: func(email, apikey string) (*cloudflare.DNSProvider, error) { - f.call("cloudflare", email, apikey) + cloudFlare: func(email, apikey string, dns01Nameservers []string) (*cloudflare.DNSProvider, error) { + f.call("cloudflare", email, apikey, util.RecursiveNameservers) if email == "" || apikey == "" { return nil, errors.New("invalid email or apikey") } return nil, nil }, - route53: func(accessKey, secretKey, hostedZoneID, region string, ambient bool) (*route53.DNSProvider, error) { - f.call("route53", accessKey, secretKey, hostedZoneID, region, ambient) + route53: func(accessKey, secretKey, hostedZoneID, region string, ambient bool, dns01Nameservers []string) (*route53.DNSProvider, error) { + f.call("route53", accessKey, secretKey, hostedZoneID, region, ambient, util.RecursiveNameservers) return nil, nil }, - azureDNS: func(clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName string) (*azuredns.DNSProvider, error) { - f.call("azuredns", clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName) + azureDNS: func(clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName string, dns01Nameservers []string) (*azuredns.DNSProvider, error) { + f.call("azuredns", clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName, util.RecursiveNameservers) return nil, nil }, }