diff --git a/docs/generated/reference/output/reference/api-docs/index.html b/docs/generated/reference/output/reference/api-docs/index.html
index efb0fad45..f19a28781 100755
--- a/docs/generated/reference/output/reference/api-docs/index.html
+++ b/docs/generated/reference/output/reference/api-docs/index.html
@@ -1133,6 +1133,10 @@ Appears In:
|
+environment string |
+ |
+
+
hostedZoneName string |
|
diff --git a/docs/tasks/issuers/setup-acme/dns01/azuredns.rst b/docs/tasks/issuers/setup-acme/dns01/azuredns.rst
index c02c25e2e..22698bf87 100644
--- a/docs/tasks/issuers/setup-acme/dns01/azuredns.rst
+++ b/docs/tasks/issuers/setup-acme/dns01/azuredns.rst
@@ -64,3 +64,5 @@ You can configure the issuer like so:
# ResourceGroup name where dns zone is provisioned
resourceGroupName: AZURE_RESOURCE_GROUP
hostedZoneName: AZURE_DNS_ZONE_NAME
+ # Azure Cloud Environment, default to AzurePublicCloud
+ environment: AZURE_ENVIRONMENT
diff --git a/pkg/apis/certmanager/v1alpha1/types_issuer.go b/pkg/apis/certmanager/v1alpha1/types_issuer.go
index 7ee8d6f97..b49338e91 100644
--- a/pkg/apis/certmanager/v1alpha1/types_issuer.go
+++ b/pkg/apis/certmanager/v1alpha1/types_issuer.go
@@ -479,6 +479,10 @@ type ACMEIssuerDNS01ProviderAzureDNS struct {
// +optional
HostedZoneName string `json:"hostedZoneName,omitempty"`
+
+ // +kubebuilder:validation:Enum=,AzurePublicCloud,AzureChinaCloud,AzureGermanCloud,AzureUSGovernmentCloud
+ // +optional
+ Environment string `json:"environment,omitempty"`
}
// ACMEIssuerDNS01ProviderAcmeDNS is a structure containing the
diff --git a/pkg/apis/certmanager/validation/issuer.go b/pkg/apis/certmanager/validation/issuer.go
index d58131b74..1d3041547 100644
--- a/pkg/apis/certmanager/validation/issuer.go
+++ b/pkg/apis/certmanager/validation/issuer.go
@@ -268,6 +268,12 @@ func ValidateACMEIssuerDNS01Config(iss *v1alpha1.ACMEIssuerDNS01Config, fldPath
if len(p.AzureDNS.ResourceGroupName) == 0 {
el = append(el, field.Required(fldPath.Child("azuredns", "resourceGroupName"), ""))
}
+ switch p.AzureDNS.Environment {
+ case "", "AzurePublicCloud", "AzureChinaCloud", "AzureGermanCloud", "AzureUSGovernmentCloud":
+ default:
+ el = append(el, field.Invalid(fldPath.Child("azuredns", "environment"), p.AzureDNS.Environment,
+ "must be either empty or one of AzurePublicCloud, AzureChinaCloud, AzureGermanCloud or AzureUSGovernmentCloud"))
+ }
}
}
if p.CloudDNS != nil {
diff --git a/pkg/apis/certmanager/validation/issuer_test.go b/pkg/apis/certmanager/validation/issuer_test.go
index 28163798e..e3aacca3b 100644
--- a/pkg/apis/certmanager/validation/issuer_test.go
+++ b/pkg/apis/certmanager/validation/issuer_test.go
@@ -513,6 +513,26 @@ func TestValidateACMEIssuerDNS01Config(t *testing.T) {
field.Required(providersPath.Index(0).Child("azuredns", "resourceGroupName"), ""),
},
},
+ "invalid azuredns environment": {
+ cfg: &v1alpha1.ACMEIssuerDNS01Config{
+ Providers: []v1alpha1.ACMEIssuerDNS01Provider{
+ {
+ Name: "a name",
+ AzureDNS: &v1alpha1.ACMEIssuerDNS01ProviderAzureDNS{Environment: "an env"},
+ },
+ },
+ },
+ errs: []*field.Error{
+ field.Required(providersPath.Index(0).Child("azuredns", "clientSecretSecretRef", "name"), "secret name is required"),
+ field.Required(providersPath.Index(0).Child("azuredns", "clientSecretSecretRef", "key"), "secret key is required"),
+ field.Required(providersPath.Index(0).Child("azuredns", "clientID"), ""),
+ field.Required(providersPath.Index(0).Child("azuredns", "subscriptionID"), ""),
+ field.Required(providersPath.Index(0).Child("azuredns", "tenantID"), ""),
+ field.Required(providersPath.Index(0).Child("azuredns", "resourceGroupName"), ""),
+ field.Invalid(providersPath.Index(0).Child("azuredns", "environment"), "an env",
+ "must be either empty or one of AzurePublicCloud, AzureChinaCloud, AzureGermanCloud or AzureUSGovernmentCloud"),
+ },
+ },
"missing akamai config": {
cfg: &v1alpha1.ACMEIssuerDNS01Config{
Providers: []v1alpha1.ACMEIssuerDNS01Provider{
diff --git a/pkg/issuer/acme/dns/azuredns/azuredns.go b/pkg/issuer/acme/dns/azuredns/azuredns.go
index 4f00a63f2..da781879a 100644
--- a/pkg/issuer/acme/dns/azuredns/azuredns.go
+++ b/pkg/issuer/acme/dns/azuredns/azuredns.go
@@ -46,27 +46,37 @@ func NewDNSProvider(dns01Nameservers []string) (*DNSProvider, error) {
tenantID := os.Getenv("AZURE_TENANT_ID")
resourceGroupName := ("AZURE_RESOURCE_GROUP")
zoneName := ("AZURE_ZONE_NAME")
+ environment := ("AZURE_ENVIRONMENT")
- return NewDNSProviderCredentials(clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, zoneName, dns01Nameservers)
+ return NewDNSProviderCredentials(environment, 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, dns01Nameservers []string) (*DNSProvider, error) {
- oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, tenantID)
+func NewDNSProviderCredentials(environment, clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, zoneName string, dns01Nameservers []string) (*DNSProvider, error) {
+ env := azure.PublicCloud
+ if environment != "" {
+ var err error
+ env, err = azure.EnvironmentFromName(environment)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, tenantID)
if err != nil {
return nil, err
}
- spt, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, clientSecret, azure.PublicCloud.ResourceManagerEndpoint)
+ spt, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, clientSecret, env.ResourceManagerEndpoint)
if err != nil {
return nil, err
}
- rc := dns.NewRecordSetsClient(subscriptionID)
+ rc := dns.NewRecordSetsClientWithBaseURI(env.ResourceManagerEndpoint, subscriptionID)
rc.Authorizer = autorest.NewBearerAuthorizer(spt)
- zc := dns.NewZonesClient(subscriptionID)
+ zc := dns.NewZonesClientWithBaseURI(env.ResourceManagerEndpoint, subscriptionID)
zc.Authorizer = autorest.NewBearerAuthorizer(spt)
return &DNSProvider{
diff --git a/pkg/issuer/acme/dns/azuredns/azuredns_test.go b/pkg/issuer/acme/dns/azuredns/azuredns_test.go
index 32275a882..122a637f2 100644
--- a/pkg/issuer/acme/dns/azuredns/azuredns_test.go
+++ b/pkg/issuer/acme/dns/azuredns/azuredns_test.go
@@ -45,7 +45,7 @@ func TestLiveAzureDnsPresent(t *testing.T) {
if !azureLiveTest {
t.Skip("skipping live test")
}
- provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName, util.RecursiveNameservers)
+ provider, err := NewDNSProviderCredentials("", azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName, util.RecursiveNameservers)
assert.NoError(t, err)
err = provider.Present(azureDomain, "_acme-challenge."+azureDomain+".", "123d==")
@@ -59,9 +59,20 @@ func TestLiveAzureDnsCleanUp(t *testing.T) {
time.Sleep(time.Second * 5)
- provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName, util.RecursiveNameservers)
+ provider, err := NewDNSProviderCredentials("", azureClientID, azureClientSecret, azuresubscriptionID, azureTenantID, azureResourceGroupName, azureHostedZoneName, util.RecursiveNameservers)
assert.NoError(t, err)
err = provider.CleanUp(azureDomain, "_acme-challenge."+azureDomain+".", "123d==")
assert.NoError(t, err)
}
+
+func TestInvalidAzureDns(t *testing.T) {
+ validEnv := []string{"", "AzurePublicCloud", "AzureChinaCloud", "AzureGermanCloud", "AzureUSGovernmentCloud"}
+ for _, env := range validEnv {
+ _, err := NewDNSProviderCredentials(env, "cid", "secret", "", "", "", "", util.RecursiveNameservers)
+ assert.NoError(t, err)
+ }
+
+ _, err := NewDNSProviderCredentials("invalid env", "cid", "secret", "", "", "", "", util.RecursiveNameservers)
+ assert.Error(t, err)
+}
diff --git a/pkg/issuer/acme/dns/dns.go b/pkg/issuer/acme/dns/dns.go
index ea8d8391e..724a0b08f 100644
--- a/pkg/issuer/acme/dns/dns.go
+++ b/pkg/issuer/acme/dns/dns.go
@@ -62,7 +62,7 @@ type dnsProviderConstructors struct {
cloudDNS func(project string, serviceAccount []byte, dns01Nameservers []string, ambient bool) (*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, tenantID, resourceGroupName, hostedZoneName string, dns01Nameservers []string) (*azuredns.DNSProvider, error)
+ azureDNS func(environment, clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, hostedZoneName string, dns01Nameservers []string) (*azuredns.DNSProvider, error)
acmeDNS func(host string, accountJson []byte, dns01Nameservers []string) (*acmedns.DNSProvider, error)
digitalOcean func(token string, dns01Nameservers []string) (*digitalocean.DNSProvider, error)
}
@@ -345,6 +345,7 @@ func (s *Solver) solverForChallenge(ctx context.Context, issuer v1alpha1.Generic
}
impl, err = s.dnsProviderConstructors.azureDNS(
+ providerConfig.AzureDNS.Environment,
providerConfig.AzureDNS.ClientID,
string(clientSecretBytes),
providerConfig.AzureDNS.SubscriptionID,
diff --git a/pkg/issuer/acme/dns/util_test.go b/pkg/issuer/acme/dns/util_test.go
index fde1837ee..f841b1440 100644
--- a/pkg/issuer/acme/dns/util_test.go
+++ b/pkg/issuer/acme/dns/util_test.go
@@ -154,7 +154,7 @@ func newFakeDNSProviders() *fakeDNSProviders {
f.call("route53", accessKey, secretKey, hostedZoneID, region, ambient, util.RecursiveNameservers)
return nil, nil
},
- azureDNS: func(clientID, clientSecret, subscriptionID, tenentID, resourceGroupName, hostedZoneName string, dns01Nameservers []string) (*azuredns.DNSProvider, error) {
+ azureDNS: func(environment, 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
},