Skip to content

Commit ec57d8a

Browse files
committed
Support Azure Stack dynamic environments
1 parent 11dbf54 commit ec57d8a

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

pkg/credentialprovider/azure/azure_credentials.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (a *acrProvider) loadConfig(rdr io.Reader) error {
144144
klog.Errorf("Failed to load azure credential file: %v", err)
145145
}
146146

147-
a.environment, err = auth.ParseAzureEnvironment(a.config.Cloud)
147+
a.environment, err = auth.ParseAzureEnvironment(a.config.Cloud, a.config.cloudFQDN, a.config.IdentitySystem)
148148
if err != nil {
149149
return err
150150
}

staging/src/k8s.io/legacy-cloud-providers/azure/auth/azure_auth.go

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ import (
3030
"k8s.io/klog"
3131
)
3232

33+
const (
34+
// ADFSIdentitySystem is the override value for tenantID on Azure Stack clouds.
35+
ADFSIdentitySystem = "adfs"
36+
)
37+
3338
var (
3439
// ErrorNoAuth indicates that no credentials are provided.
3540
ErrorNoAuth = fmt.Errorf("no credentials provided for Azure cloud provider")
36-
// ADFSIdentitySystem indicates value of tenantId for ADFS on Azure Stack.
37-
ADFSIdentitySystem = "ADFS"
3841
)
3942

4043
// AzureAuthConfig holds auth related part of cloud config
@@ -59,15 +62,19 @@ type AzureAuthConfig struct {
5962
UserAssignedIdentityID string `json:"userAssignedIdentityID,omitempty" yaml:"userAssignedIdentityID,omitempty"`
6063
// The ID of the Azure Subscription that the cluster is deployed in
6164
SubscriptionID string `json:"subscriptionId,omitempty" yaml:"subscriptionId,omitempty"`
62-
// Identity system value for the deployment. This gets populate for Azure Stack case.
63-
IdentitySystem string `json:"identitySystem,omitempty" yaml:"identitySystem,omitempty"`
65+
// IdentitySystem indicates the identity provider. Relevant only to hybrid clouds (Azure Stack).
66+
// Allowed values are 'azure_ad' (default), 'adfs'.
67+
IdentitySystem string `json:"identitySystem" yaml:"identitySystem"`
68+
// CloudFQDN represents the hybrid cloud's fully qualified domain name: {location}.{domain}
69+
// If set, cloud provider will generate its autorest.Environment instead of using one of the pre-defined ones.
70+
CloudFQDN string `json:"cloudFQDN" yaml:"cloudFQDN"`
6471
}
6572

6673
// GetServicePrincipalToken creates a new service principal token based on the configuration
6774
func GetServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment) (*adal.ServicePrincipalToken, error) {
6875
var tenantID string
6976
if strings.EqualFold(config.IdentitySystem, ADFSIdentitySystem) {
70-
tenantID = "adfs"
77+
tenantID = ADFSIdentitySystem
7178
} else {
7279
tenantID = config.TenantID
7380
}
@@ -126,10 +133,18 @@ func GetServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment) (
126133
}
127134

128135
// ParseAzureEnvironment returns azure environment by name
129-
func ParseAzureEnvironment(cloudName string) (*azure.Environment, error) {
136+
func ParseAzureEnvironment(cloudName, cloudFQDN, identitySystem string) (*azure.Environment, error) {
130137
var env azure.Environment
131138
var err error
132-
if cloudName == "" {
139+
if cloudFQDN != "" {
140+
resourceManagerEndpoint := fmt.Sprintf("https://management.%s/", cloudFQDN)
141+
nameOverride := azure.OverrideProperty{Key: azure.EnvironmentName, Value: cloudName}
142+
klog.V(4).Infof("Loading environment from resource manager endpoint: %s", resourceManagerEndpoint)
143+
env, err = azure.EnvironmentFromURL(resourceManagerEndpoint, nameOverride)
144+
if err == nil && strings.EqualFold(cloudName, "AzureStackCloud") {
145+
azureStackOverrides(env, cloudFQDN, identitySystem)
146+
}
147+
} else if cloudName == "" {
133148
env = azure.PublicCloud
134149
} else {
135150
env, err = azure.EnvironmentFromName(cloudName)
@@ -151,3 +166,22 @@ func decodePkcs12(pkcs []byte, password string) (*x509.Certificate, *rsa.Private
151166

152167
return certificate, rsaPrivateKey, nil
153168
}
169+
170+
func azureStackOverrides(env azure.Environment, cloudFQDN, identitySystem string) azure.Environment {
171+
// if AzureStack, make sure the generated environment matches what AKSe currently generates
172+
env.ManagementPortalURL = fmt.Sprintf("https://portal.%s/", cloudFQDN)
173+
// TODO: figure out why AKSe does this
174+
// why is autorest not setting ServiceManagementEndpoint?
175+
env.ServiceManagementEndpoint = env.TokenAudience
176+
// TODO: figure out why AKSe does this
177+
// ResourceManagerVMDNSSuffix is not referenced in k/k
178+
split := strings.Split(cloudFQDN, ".")
179+
domain := strings.Join(split[1:], ".")
180+
env.ResourceManagerVMDNSSuffix = fmt.Sprintf("cloudapp.%s", domain)
181+
// NOTE: autorest sets KeyVaultEndpoint while AKSe does not
182+
if strings.EqualFold(identitySystem, ADFSIdentitySystem) {
183+
env.ActiveDirectoryEndpoint = strings.TrimSuffix(env.ActiveDirectoryEndpoint, "/")
184+
env.ActiveDirectoryEndpoint = strings.TrimSuffix(env.ActiveDirectoryEndpoint, "adfs")
185+
}
186+
return env
187+
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ func (az *Cloud) InitializeCloudFromConfig(config *Config, fromSecret bool) erro
325325
}
326326
}
327327

328-
env, err := auth.ParseAzureEnvironment(config.Cloud)
328+
env, err := auth.ParseAzureEnvironment(config.Cloud, config.CloudFQDN, config.IdentitySystem)
329329
if err != nil {
330330
return err
331331
}

0 commit comments

Comments
 (0)