Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions azure/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const (
ChinaCloudName = "AzureChinaCloud"
// USGovernmentCloudName is the name of the Azure US Government cloud.
USGovernmentCloudName = "AzureUSGovernmentCloud"
// GermanCloudName is the name of the Azure German cloud.
GermanCloudName = "AzureGermanCloud"
)

const (
Expand Down
107 changes: 64 additions & 43 deletions azure/scope/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,47 +25,53 @@ import (
"strings"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
azureautorest "github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"

infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/azure"
)

// AzureClients contains all the Azure clients used by the scopes.
type AzureClients struct {
auth.EnvironmentSettings

TokenCredential azcore.TokenCredential
ResourceManagerEndpoint string
ResourceManagerVMDNSSuffix string
activeDirectoryEndpoint string
tokenAudience string

authType infrav1.IdentityType

cloudEnvironment string
tenantID string
clientID string
clientSecret string
subscriptionID string
}

// CloudEnvironment returns the Azure environment the controller runs in.
func (c *AzureClients) CloudEnvironment() string {
return c.Environment.Name
return c.cloudEnvironment
}

// TenantID returns the Azure tenant id the controller runs in.
func (c *AzureClients) TenantID() string {
return c.Values["AZURE_TENANT_ID"]
return c.tenantID
}

// ClientID returns the Azure client id from the controller environment.
func (c *AzureClients) ClientID() string {
return c.Values["AZURE_CLIENT_ID"]
return c.clientID
}

// ClientSecret returns the Azure client secret from the controller environment.
func (c *AzureClients) ClientSecret() string {
return c.Values["AZURE_CLIENT_SECRET"]
return c.clientSecret
}

// SubscriptionID returns the Azure subscription id of the cluster,
// either specified or from the environment.
func (c *AzureClients) SubscriptionID() string {
return c.Values["AZURE_SUBSCRIPTION_ID"]
return c.subscriptionID
}

// Token returns the Azure token credential of the cluster used for SDKv2 services.
Expand All @@ -86,70 +92,85 @@ func (c *AzureClients) setCredentialsWithProvider(ctx context.Context, subscript
return fmt.Errorf("credentials provider cannot have an empty value")
}

settings, err := c.getSettingsFromEnvironment(environmentName)
err := c.getSettingsFromEnvironment(environmentName)
if err != nil {
return err
}

if subscriptionID == "" {
subscriptionID = settings.GetSubscriptionID()
subscriptionID = c.SubscriptionID()
if subscriptionID == "" {
return fmt.Errorf("error creating azure services. subscriptionID is not set in cluster or AZURE_SUBSCRIPTION_ID env var")
}
}

c.EnvironmentSettings = settings
c.ResourceManagerEndpoint = settings.Environment.ResourceManagerEndpoint
c.ResourceManagerVMDNSSuffix = settings.Environment.ResourceManagerVMDNSSuffix
c.Values["AZURE_SUBSCRIPTION_ID"] = strings.TrimSuffix(subscriptionID, "\n")
c.Values["AZURE_TENANT_ID"] = strings.TrimSuffix(credentialsProvider.GetTenantID(), "\n")
c.Values["AZURE_CLIENT_ID"] = strings.TrimSuffix(credentialsProvider.GetClientID(), "\n")
c.subscriptionID = strings.TrimSuffix(subscriptionID, "\n")
c.tenantID = strings.TrimSuffix(credentialsProvider.GetTenantID(), "\n")
c.clientID = strings.TrimSuffix(credentialsProvider.GetClientID(), "\n")

clientSecret, err := credentialsProvider.GetClientSecret(ctx)
if err != nil {
return err
}
c.Values["AZURE_CLIENT_SECRET"] = strings.TrimSuffix(clientSecret, "\n")
c.clientSecret = strings.TrimSuffix(clientSecret, "\n")

c.authType = credentialsProvider.Type()

tokenCredential, err := credentialsProvider.GetTokenCredential(ctx, c.ResourceManagerEndpoint, c.Environment.ActiveDirectoryEndpoint, c.Environment.TokenAudience)
tokenCredential, err := credentialsProvider.GetTokenCredential(ctx, c.ResourceManagerEndpoint, c.activeDirectoryEndpoint, c.tokenAudience)
if err != nil {
return err
}
c.TokenCredential = tokenCredential
return err
}

func (c *AzureClients) getSettingsFromEnvironment(environmentName string) (s auth.EnvironmentSettings, err error) {
s = auth.EnvironmentSettings{
Values: map[string]string{},
}
s.Values["AZURE_ENVIRONMENT"] = environmentName
setValue(s, "AZURE_SUBSCRIPTION_ID")
setValue(s, "AZURE_TENANT_ID")
setValue(s, "AZURE_AUXILIARY_TENANT_IDS")
setValue(s, "AZURE_CLIENT_ID")
setValue(s, "AZURE_CLIENT_SECRET")
setValue(s, "AZURE_CERTIFICATE_PATH")
setValue(s, "AZURE_CERTIFICATE_PASSWORD")
setValue(s, "AZURE_USERNAME")
setValue(s, "AZURE_PASSWORD")
setValue(s, "AZURE_AD_RESOURCE")
Comment on lines -130 to -138
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT none of these environment variables mean anything to the SDKv2 clients that we use.

if v := s.Values["AZURE_ENVIRONMENT"]; v == "" {
s.Environment = azureautorest.PublicCloud
} else {
s.Environment, err = azureautorest.EnvironmentFromName(v)
func (c *AzureClients) getSettingsFromEnvironment(environmentName string) error {
if environmentName == "" {
environmentName = azure.PublicCloudName
}
if s.Values["AZURE_AD_RESOURCE"] == "" {
s.Values["AZURE_AD_RESOURCE"] = s.Environment.ResourceManagerEndpoint
setValue(&c.subscriptionID, "AZURE_SUBSCRIPTION_ID")

// These strings were well-known by go-autorest which we don't use anymore.
// This translates those strings into the corresponding SDKv2 configuration.
var cloudConfig cloud.Configuration
switch environmentName {
case azure.ChinaCloudName:
cloudConfig = cloud.AzureChina
c.ResourceManagerVMDNSSuffix = "cloudapp.chinacloudapi.cn"
case azure.GermanCloudName:
// Not built in to SDKv2.
// https://github.com/Azure/go-autorest/blob/33e12ab7683c1c236a863ccfbfdd78c626f7fe28/autorest/azure/environments.go#L243
cloudConfig = cloud.Configuration{
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.de/",
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
cloud.ResourceManager: {
Audience: "https://management.microsoftazure.de/",
Endpoint: "https://management.microsoftazure.de/",
},
},
}
c.ResourceManagerVMDNSSuffix = "cloudapp.microsoftazure.de"
case azure.PublicCloudName:
cloudConfig = cloud.AzurePublic
c.ResourceManagerVMDNSSuffix = "cloudapp.azure.com"
case azure.USGovernmentCloudName:
cloudConfig = cloud.AzureGovernment
c.ResourceManagerVMDNSSuffix = "cloudapp.usgovcloudapi.net"
default:
return fmt.Errorf("invalid cloud environment name %q", c.CloudEnvironment())
}
return

c.cloudEnvironment = environmentName
c.activeDirectoryEndpoint = cloudConfig.ActiveDirectoryAuthorityHost
c.ResourceManagerEndpoint = cloudConfig.Services[cloud.ResourceManager].Endpoint
c.tokenAudience = cloudConfig.Services[cloud.ResourceManager].Audience

return nil
}

// setValue adds the specified environment variable value to the Values map if it exists.
func setValue(settings auth.EnvironmentSettings, key string) {
func setValue(value *string, key string) {
if v := os.Getenv(key); v != "" {
settings.Values[key] = v
*value = v
}
}
49 changes: 8 additions & 41 deletions azure/scope/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
asonetworkv1api20201101 "github.com/Azure/azure-service-operator/v2/api/network/v1api20201101"
asonetworkv1api20220701 "github.com/Azure/azure-service-operator/v2/api/network/v1api20220701"
asoresourcesv1 "github.com/Azure/azure-service-operator/v2/api/resources/v1api20200601"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/google/go-cmp/cmp"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -1044,11 +1043,7 @@ func TestNatGatewaySpecs(t *testing.T) {
},
},
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: "123",
},
},
subscriptionID: "123",
},
AzureCluster: &infrav1.AzureCluster{
Spec: infrav1.AzureClusterSpec{
Expand Down Expand Up @@ -1118,11 +1113,7 @@ func TestNatGatewaySpecs(t *testing.T) {
},
},
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: "123",
},
},
subscriptionID: "123",
},
AzureCluster: &infrav1.AzureCluster{
Spec: infrav1.AzureClusterSpec{
Expand Down Expand Up @@ -1210,11 +1201,7 @@ func TestNatGatewaySpecs(t *testing.T) {
},
},
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: "123",
},
},
subscriptionID: "123",
},
AzureCluster: &infrav1.AzureCluster{
Spec: infrav1.AzureClusterSpec{
Expand Down Expand Up @@ -1510,11 +1497,7 @@ func TestSubnetSpecs(t *testing.T) {
},
},
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: "123",
},
},
subscriptionID: "123",
},
AzureCluster: &infrav1.AzureCluster{
Spec: infrav1.AzureClusterSpec{
Expand Down Expand Up @@ -1591,11 +1574,7 @@ func TestSubnetSpecs(t *testing.T) {
},
},
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: "123",
},
},
subscriptionID: "123",
},
AzureCluster: &infrav1.AzureCluster{
Spec: infrav1.AzureClusterSpec{
Expand Down Expand Up @@ -1887,11 +1866,7 @@ func TestAzureBastionSpec(t *testing.T) {
},
},
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: "123",
},
},
subscriptionID: "123",
},
AzureCluster: &infrav1.AzureCluster{
Spec: infrav1.AzureClusterSpec{
Expand Down Expand Up @@ -3346,11 +3321,7 @@ func TestClusterScope_LBSpecs(t *testing.T) {
Cluster: cluster,
AzureCluster: tc.azureCluster,
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: tc.azureCluster.Spec.SubscriptionID,
},
},
subscriptionID: tc.azureCluster.Spec.SubscriptionID,
},
}
if got := clusterScope.LBSpecs(); !reflect.DeepEqual(got, tc.want) {
Expand Down Expand Up @@ -3668,11 +3639,7 @@ func TestVNetPeerings(t *testing.T) {
Cluster: cluster,
AzureCluster: azureCluster,
AzureClients: AzureClients{
EnvironmentSettings: auth.EnvironmentSettings{
Values: map[string]string{
auth.SubscriptionID: tc.subscriptionID,
},
},
subscriptionID: tc.subscriptionID,
},
}
got := clusterScope.VnetPeeringSpecs()
Expand Down
Loading