Skip to content

Commit

Permalink
Merge pull request #4295 from pohly/azure-cli-credentials
Browse files Browse the repository at this point in the history
azure: support CLI credentials instead of service principal
  • Loading branch information
k8s-ci-robot authored Sep 22, 2021
2 parents b434c57 + 9d51239 commit 7e6e0f9
Show file tree
Hide file tree
Showing 31 changed files with 2,402 additions and 27 deletions.
26 changes: 21 additions & 5 deletions cluster-autoscaler/cloudprovider/azure/azure_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/adal"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth"

klog "k8s.io/klog/v2"
"k8s.io/legacy-cloud-providers/azure/clients/containerserviceclient"
Expand All @@ -52,10 +53,10 @@ type azDeploymentsClient struct {
client resources.DeploymentsClient
}

func newAzDeploymentsClient(subscriptionID, endpoint string, servicePrincipalToken *adal.ServicePrincipalToken) *azDeploymentsClient {
func newAzDeploymentsClient(subscriptionID, endpoint string, authorizer autorest.Authorizer) *azDeploymentsClient {
deploymentsClient := resources.NewDeploymentsClient(subscriptionID)
deploymentsClient.BaseURI = endpoint
deploymentsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken)
deploymentsClient.Authorizer = authorizer
deploymentsClient.PollingDelay = 5 * time.Second
configureUserAgent(&deploymentsClient.Client)

Expand Down Expand Up @@ -206,13 +207,28 @@ func newServicePrincipalTokenFromCredentials(config *Config, env *azure.Environm
return nil, fmt.Errorf("no credentials provided for AAD application %s", config.AADClientID)
}

func newAuthorizer(config *Config, env *azure.Environment) (autorest.Authorizer, error) {
switch config.AuthMethod {
case authMethodCLI:
return auth.NewAuthorizerFromCLI()
case "", authMethodPrincipal:
token, err := newServicePrincipalTokenFromCredentials(config, env)
if err != nil {
return nil, fmt.Errorf("retrieve service principal token: %v", err)
}
return autorest.NewBearerAuthorizer(token), nil
default:
return nil, fmt.Errorf("unsupported authorization method: %s", config.AuthMethod)
}
}

func newAzClient(cfg *Config, env *azure.Environment) (*azClient, error) {
spt, err := newServicePrincipalTokenFromCredentials(cfg, env)
authorizer, err := newAuthorizer(cfg, env)
if err != nil {
return nil, err
}

azClientConfig := cfg.getAzureClientConfig(spt, env)
azClientConfig := cfg.getAzureClientConfig(authorizer, env)
azClientConfig.UserAgent = getUserAgentExtension()

vmssClientConfig := azClientConfig.WithRateLimiter(cfg.VirtualMachineScaleSetRateLimit)
Expand All @@ -227,7 +243,7 @@ func newAzClient(cfg *Config, env *azure.Environment) (*azClient, error) {
virtualMachinesClient := vmclient.New(vmClientConfig)
klog.V(5).Infof("Created vm client with authorizer: %v", virtualMachinesClient)

deploymentsClient := newAzDeploymentsClient(cfg.SubscriptionID, env.ResourceManagerEndpoint, spt)
deploymentsClient := newAzDeploymentsClient(cfg.SubscriptionID, env.ResourceManagerEndpoint, authorizer)
klog.V(5).Infof("Created deployments client with authorizer: %v", deploymentsClient)

interfaceClientConfig := azClientConfig.WithRateLimiter(cfg.InterfaceRateLimit)
Expand Down
42 changes: 31 additions & 11 deletions cluster-autoscaler/cloudprovider/azure/azure_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,21 @@ package azure

import (
"encoding/json"
"errors"
"fmt"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/adal"
"github.com/Azure/go-autorest/autorest/azure"
"io"
"io/ioutil"
"k8s.io/klog/v2"
providerazure "k8s.io/legacy-cloud-providers/azure"
azclients "k8s.io/legacy-cloud-providers/azure/clients"
"k8s.io/legacy-cloud-providers/azure/retry"
"os"
"strconv"
"strings"
"time"

"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"k8s.io/klog/v2"
providerazure "k8s.io/legacy-cloud-providers/azure"
azclients "k8s.io/legacy-cloud-providers/azure/clients"
"k8s.io/legacy-cloud-providers/azure/retry"
)

const (
Expand All @@ -53,6 +54,10 @@ const (
rateLimitReadBucketsEnvVar = "RATE_LIMIT_READ_BUCKETS"
rateLimitWriteQPSEnvVar = "RATE_LIMIT_WRITE_QPS"
rateLimitWriteBucketsEnvVar = "RATE_LIMIT_WRITE_BUCKETS"

// auth methods
authMethodPrincipal = "principal"
authMethodCLI = "cli"
)

// CloudProviderRateLimitConfig indicates the rate limit config for each clients.
Expand Down Expand Up @@ -80,6 +85,14 @@ type Config struct {
ResourceGroup string `json:"resourceGroup" yaml:"resourceGroup"`
VMType string `json:"vmType" yaml:"vmType"`

// AuthMethod determines how to authorize requests for the Azure
// cloud. Valid options are "principal" (= the traditional
// service principle approach) and "cli" (= load az command line
// config file). The default is "principal".
AuthMethod string `json:"authMethod" yaml:"authMethod"`

// Settings for a service principal.

AADClientID string `json:"aadClientId" yaml:"aadClientId"`
AADClientSecret string `json:"aadClientSecret" yaml:"aadClientSecret"`
AADClientCertPath string `json:"aadClientCertPath" yaml:"aadClientCertPath"`
Expand Down Expand Up @@ -373,12 +386,12 @@ func overrideDefaultRateLimitConfig(defaults, config *azclients.RateLimitConfig)
return config
}

func (cfg *Config) getAzureClientConfig(servicePrincipalToken *adal.ServicePrincipalToken, env *azure.Environment) *azclients.ClientConfig {
func (cfg *Config) getAzureClientConfig(authorizer autorest.Authorizer, env *azure.Environment) *azclients.ClientConfig {
azClientConfig := &azclients.ClientConfig{
Location: cfg.Location,
SubscriptionID: cfg.SubscriptionID,
ResourceManagerEndpoint: env.ResourceManagerEndpoint,
Authorizer: autorest.NewBearerAuthorizer(servicePrincipalToken),
Authorizer: authorizer,
Backoff: &retry.Backoff{Steps: 1},
}

Expand Down Expand Up @@ -445,8 +458,15 @@ func (cfg *Config) validate() error {
return fmt.Errorf("tenant ID not set")
}

if cfg.AADClientID == "" {
return fmt.Errorf("ARM Client ID not set")
switch cfg.AuthMethod {
case "", authMethodPrincipal:
if cfg.AADClientID == "" {
return errors.New("ARM Client ID not set")
}
case authMethodCLI:
// Nothing to check at the moment.
default:
return fmt.Errorf("unsupported authorization method: %s", cfg.AuthMethod)
}

if cfg.CloudProviderBackoff && cfg.CloudProviderBackoffRetries == 0 {
Expand Down
3 changes: 2 additions & 1 deletion cluster-autoscaler/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/Azure/azure-sdk-for-go v55.0.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.18
github.com/Azure/go-autorest/autorest/adal v0.9.13
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8
github.com/Azure/go-autorest/autorest/date v0.3.0
github.com/Azure/go-autorest/autorest/to v0.4.0
github.com/aws/aws-sdk-go v1.38.49
Expand All @@ -21,7 +22,7 @@ require (
github.com/satori/go.uuid v1.2.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
google.golang.org/api v0.46.0
gopkg.in/gcfg.v1 v1.2.0
Expand Down
14 changes: 14 additions & 0 deletions cluster-autoscaler/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,17 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM=
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk=
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8 h1:TzPg6B6fTZ0G1zBf3T54aI7p3cAT6u//TOXGPmFMOXg=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
Expand All @@ -60,6 +67,7 @@ github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+X
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
github.com/Azure/go-autorest/autorest/validation v0.1.0 h1:ISSNzGUh+ZSzizJWOWzs8bwpXIePbGLW4z/AmUFGH5A=
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
Expand Down Expand Up @@ -197,6 +205,9 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/digitalocean/godo v1.27.0 h1:78iE9oVvTnAEqhMip2UHFvL01b8LJcydbNUpr0cAmN4=
github.com/digitalocean/godo v1.27.0/go.mod h1:iJnN9rVu6K5LioLxLimlq0uRI+y/eAQjROUmeU/r0hY=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
Expand Down Expand Up @@ -482,6 +493,7 @@ github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
Expand Down Expand Up @@ -751,6 +763,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down
Loading

0 comments on commit 7e6e0f9

Please sign in to comment.