azure: refactor azure.go to make auth reusable

This commit is contained in:
Cole Mickens 2017-07-13 03:15:08 -07:00
parent 4521c2312c
commit 8f55afd0cb

View File

@ -148,69 +148,62 @@ func decodePkcs12(pkcs []byte, password string) (*x509.Certificate, *rsa.Private
return certificate, rsaPrivateKey, nil return certificate, rsaPrivateKey, nil
} }
// newServicePrincipalToken creates a new service principal token based on the configuration // GetServicePrincipalToken creates a new service principal token based on the configuration
func newServicePrincipalToken(az *Cloud) (*adal.ServicePrincipalToken, error) { func GetServicePrincipalToken(config *Config, env *azure.Environment) (*adal.ServicePrincipalToken, error) {
oauthConfig, err := adal.NewOAuthConfig(az.Environment.ActiveDirectoryEndpoint, az.TenantID) oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, config.TenantID)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating the OAuth config: %v", err) return nil, fmt.Errorf("creating the OAuth config: %v", err)
} }
if az.UseManagedIdentityExtension { if config.UseManagedIdentityExtension {
glog.V(2).Infoln("azure: using managed identity extension to retrieve access token") glog.V(2).Infoln("azure: using managed identity extension to retrieve access token")
return adal.NewServicePrincipalTokenFromMSI( return adal.NewServicePrincipalTokenFromMSI(
*oauthConfig, *oauthConfig,
az.Environment.ServiceManagementEndpoint) env.ServiceManagementEndpoint)
} else if len(az.AADClientSecret) > 0 { }
if len(config.AADClientSecret) > 0 {
glog.V(2).Infoln("azure: using client_id+client_secret to retrieve access token") glog.V(2).Infoln("azure: using client_id+client_secret to retrieve access token")
return adal.NewServicePrincipalToken( return adal.NewServicePrincipalToken(
*oauthConfig, *oauthConfig,
az.AADClientID, config.AADClientID,
az.AADClientSecret, config.AADClientSecret,
az.Environment.ServiceManagementEndpoint) env.ServiceManagementEndpoint)
} else if len(az.AADClientCertPath) > 0 && len(az.AADClientCertPassword) > 0 { }
if len(config.AADClientCertPath) > 0 && len(config.AADClientCertPassword) > 0 {
glog.V(2).Infoln("azure: using jwt client_assertion (client_cert+client_private_key) to retrieve access token") glog.V(2).Infoln("azure: using jwt client_assertion (client_cert+client_private_key) to retrieve access token")
certData, err := ioutil.ReadFile(az.AADClientCertPath) certData, err := ioutil.ReadFile(config.AADClientCertPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("reading the client certificate from file %s: %v", az.AADClientCertPath, err) return nil, fmt.Errorf("reading the client certificate from file %s: %v", config.AADClientCertPath, err)
} }
certificate, privateKey, err := decodePkcs12(certData, az.AADClientCertPassword) certificate, privateKey, err := decodePkcs12(certData, config.AADClientCertPassword)
if err != nil { if err != nil {
return nil, fmt.Errorf("decoding the client certificate: %v", err) return nil, fmt.Errorf("decoding the client certificate: %v", err)
} }
return adal.NewServicePrincipalTokenFromCertificate( return adal.NewServicePrincipalTokenFromCertificate(
*oauthConfig, *oauthConfig,
az.AADClientID, config.AADClientID,
certificate, certificate,
privateKey, privateKey,
az.Environment.ServiceManagementEndpoint) env.ServiceManagementEndpoint)
} }
return nil, fmt.Errorf("No credentials provided for AAD application %s", az.AADClientID) return nil, fmt.Errorf("No credentials provided for AAD application %s", config.AADClientID)
} }
// NewCloud returns a Cloud with initialized clients // NewCloud returns a Cloud with initialized clients
func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) { func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
var az Cloud config, env, err := ParseConfig(configReader)
configContents, err := ioutil.ReadAll(configReader)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = yaml.Unmarshal(configContents, &az) az := Cloud{
if err != nil { Config: *config,
return nil, err Environment: *env,
} }
if az.Cloud == "" { servicePrincipalToken, err := GetServicePrincipalToken(config, env)
az.Environment = azure.PublicCloud
} else {
az.Environment, err = azure.EnvironmentFromName(az.Cloud)
if err != nil {
return nil, err
}
}
servicePrincipalToken, err := newServicePrincipalToken(&az)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -317,6 +310,31 @@ func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
return &az, nil return &az, nil
} }
// ParseConfig returns a parsed configuration and azure.Environment for an Azure cloudprovider config file
func ParseConfig(configReader io.Reader) (*Config, *azure.Environment, error) {
var config Config
configContents, err := ioutil.ReadAll(configReader)
if err != nil {
return nil, nil, err
}
err = yaml.Unmarshal(configContents, &config)
if err != nil {
return nil, nil, err
}
var env azure.Environment
if config.Cloud == "" {
env = azure.PublicCloud
} else {
env, err = azure.EnvironmentFromName(config.Cloud)
if err != nil {
return nil, nil, err
}
}
return &config, &env, nil
}
// Initialize passes a Kubernetes clientBuilder interface to the cloud provider // Initialize passes a Kubernetes clientBuilder interface to the cloud provider
func (az *Cloud) Initialize(clientBuilder controller.ControllerClientBuilder) {} func (az *Cloud) Initialize(clientBuilder controller.ControllerClientBuilder) {}