Repository: kubernetes-sigs/cloud-provider-azure
Pull request #3024 (2023-01-04 10:48:41)

[release-1.26] Refactor: move auth config to config package
This is an automated cherry-pick of #3016

/assign MartinForReal

```release-note
NONE
```


Patch:
diff --git a/pkg/credentialprovider/azure_acr_helper.go b/pkg/credentialprovider/azure_acr_helper.go
index 4fdf3a70a..6a2221686 100644
--- a/pkg/credentialprovider/azure_acr_helper.go
+++ b/pkg/credentialprovider/azure_acr_helper.go
@@ -50,7 +50,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"strconv"
@@ -182,7 +181,7 @@ func performTokenExchange(
 
 	var content []byte
 	limitedReader := &io.LimitedReader{R: exchange.Body, N: maxReadLength}
-	if content, err = ioutil.ReadAll(limitedReader); err != nil {
+	if content, err = io.ReadAll(limitedReader); err != nil {
 		return "", fmt.Errorf("Www-Authenticate: error reading response from %s", authEndpoint)
 	}
 
diff --git a/pkg/credentialprovider/azure_credentials.go b/pkg/credentialprovider/azure_credentials.go
index 7e4b7475e..c051560fc 100644
--- a/pkg/credentialprovider/azure_credentials.go
+++ b/pkg/credentialprovider/azure_credentials.go
@@ -21,20 +21,18 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"regexp"
 	"strings"
 	"time"
 
+	providerconfig "sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
+
 	"github.com/Azure/go-autorest/autorest/adal"
 	"github.com/Azure/go-autorest/autorest/azure"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/klog/v2"
 	"k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1"
-	"sigs.k8s.io/yaml"
-
-	"sigs.k8s.io/cloud-provider-azure/pkg/auth"
 )
 
 // Refer: https://github.com/kubernetes/kubernetes/blob/master/pkg/credentialprovider/azure/azure_credentials.go
@@ -57,7 +55,7 @@ type CredentialProvider interface {
 
 // acrProvider implements the credential provider interface for Azure Container Registry.
 type acrProvider struct {
-	config                *auth.AzureAuthConfig
+	config                *providerconfig.AzureAuthConfig
 	environment           *azure.Environment
 	servicePrincipalToken *adal.ServicePrincipalToken
 }
@@ -78,12 +76,12 @@ func NewAcrProvider(configFile string) (CredentialProvider, error) {
 }
 
 func newAcrProviderFromConfigReader(configReader io.Reader) (*acrProvider, error) {
-	config, env, err := parseConfig(configReader)
+	config, env, err := providerconfig.ParseAzureAuthConfig(configReader)
 	if err != nil {
 		return nil, fmt.Errorf("failed to load config: %w", err)
 	}
 
-	servicePrincipalToken, err := auth.GetServicePrincipalToken(config, env, env.ServiceManagementEndpoint)
+	servicePrincipalToken, err := providerconfig.GetServicePrincipalToken(config, env, env.ServiceManagementEndpoint)
 	if err != nil {
 		return nil, fmt.Errorf("failed to create service principal token: %w", err)
 	}
@@ -164,35 +162,6 @@ func (a *acrProvider) GetCredentials(ctx context.Context, image string, args []s
 	return response, nil
 }
 
-// ParseConfig returns a parsed configuration for an Azure cloudprovider config file
-func parseConfig(configReader io.Reader) (*auth.AzureAuthConfig, *azure.Environment, error) {
-	var config auth.AzureAuthConfig
-
-	if configReader == nil {
-		return nil, nil, errors.New("nil config is provided")
-	}
-
-	limitedReader := &io.LimitedReader{R: configReader, N: maxReadLength}
-	configContents, err := ioutil.ReadAll(limitedReader)
-	if err != nil {
-		return nil, nil, err
-	}
-	if limitedReader.N <= 0 {
-		return nil, nil, errors.New("the read limit is reached")
-	}
-	err = yaml.Unmarshal(configContents, &config)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	environment, err := auth.ParseAzureEnvironment(config.Cloud, config.ResourceManagerEndpoint, config.IdentitySystem)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	return &config, environment, nil
-}
-
 // getFromACR gets credentials from ACR.
 func (a *acrProvider) getFromACR(loginServer string) (string, string, error) {
 	// Run EnsureFresh to make sure the token is valid and does not expire
diff --git a/pkg/provider/azure.go b/pkg/provider/azure.go
index 575057069..caacea3ef 100644
--- a/pkg/provider/azure.go
+++ b/pkg/provider/azure.go
@@ -48,7 +48,6 @@ import (
 	cloudprovider "k8s.io/cloud-provider"
 	"k8s.io/klog/v2"
 
-	"sigs.k8s.io/cloud-provider-azure/pkg/auth"
 	azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/blobclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/containerserviceclient"
@@ -105,7 +104,7 @@ var (
 // See https://kubernetes.io/docs/reference/using-api/deprecation-policy/#deprecating-a-flag-or-cli
 // for more details.
 type Config struct {
-	auth.AzureAuthConfig
+	ratelimitconfig.AzureAuthConfig
 	ratelimitconfig.CloudProviderRateLimitConfig
 
 	// The cloud configure type for Azure cloud provider. Supported values are file, secret and merge.
@@ -548,13 +547,13 @@ func (az *Cloud) InitializeCloudFromConfig(ctx context.Context, config *Config,
 		}
 	}
 
-	env, err := auth.ParseAzureEnvironment(config.Cloud, config.ResourceManagerEndpoint, config.IdentitySystem)
+	env, err := ratelimitconfig.ParseAzureEnvironment(config.Cloud, config.ResourceManagerEndpoint, config.IdentitySystem)
 	if err != nil {
 		return err
 	}
 
-	servicePrincipalToken, err := auth.GetServicePrincipalToken(&config.AzureAuthConfig, env, env.ServiceManagementEndpoint)
-	if errors.Is(err, auth.ErrorNoAuth) {
+	servicePrincipalToken, err := ratelimitconfig.GetServicePrincipalToken(&config.AzureAuthConfig, env, env.ServiceManagementEndpoint)
+	if errors.Is(err, ratelimitconfig.ErrorNoAuth) {
 		// Only controller-manager would lazy-initialize from secret, and credentials are required for such case.
 		if fromSecret {
 			err := fmt.Errorf("no credentials provided for Azure cloud provider")
@@ -733,11 +732,11 @@ func (az *Cloud) configureMultiTenantClients(servicePrincipalToken *adal.Service
 	var multiTenantServicePrincipalToken *adal.MultiTenantServicePrincipalToken
 	var networkResourceServicePrincipalToken *adal.ServicePrincipalToken
 	if az.Config.UsesNetworkResourceInDifferentTenant() {
-		multiTenantServicePrincipalToken, err = auth.GetMultiTenantServicePrincipalToken(&az.Config.AzureAuthConfig, &az.Environment)
+		multiTenantServicePrincipalToken, err = ratelimitconfig.GetMultiTenantServicePrincipalToken(&az.Config.AzureAuthConfig, &az.Environment)
 		if err != nil {
 			return err
 		}
-		networkResourceServicePrincipalToken, err = auth.GetNetworkResourceServicePrincipalToken(&az.Config.AzureAuthConfig, &az.Environment)
+		networkResourceServicePrincipalToken, err = ratelimitconfig.GetNetworkResourceServicePrincipalToken(&az.Config.AzureAuthConfig, &az.Environment)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/provider/azure_fakes.go b/pkg/provider/azure_fakes.go
index 77919a094..8c849dd16 100644
--- a/pkg/provider/azure_fakes.go
+++ b/pkg/provider/azure_fakes.go
@@ -20,12 +20,13 @@ import (
 	"context"
 	"fmt"
 
+	"sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
+
 	"github.com/golang/mock/gomock"
 
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/client-go/tools/record"
 
-	"sigs.k8s.io/cloud-provider-azure/pkg/auth"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/interfaceclient/mockinterfaceclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient"
@@ -75,7 +76,7 @@ func NewTestFlexScaleSet(ctrl *gomock.Controller) (*FlexScaleSet, error) {
 func GetTestCloud(ctrl *gomock.Controller) (az *Cloud) {
 	az = &Cloud{
 		Config: Config{
-			AzureAuthConfig: auth.AzureAuthConfig{
+			AzureAuthConfig: config.AzureAuthConfig{
 				TenantID:       "tenant",
 				SubscriptionID: "subscription",
 			},
diff --git a/pkg/auth/azure_auth.go b/pkg/provider/config/azure_auth.go
similarity index 93%
rename from pkg/auth/azure_auth.go
rename to pkg/provider/config/azure_auth.go
index 766c36736..a7ba9ea9b 100644
--- a/pkg/auth/azure_auth.go
+++ b/pkg/provider/config/azure_auth.go
@@ -14,15 +14,19 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package auth
+package config
 
 import (
 	"crypto/rsa"
 	"crypto/x509"
+	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
+	"os"
 	"strings"
 
+	"sigs.k8s.io/yaml"
+
 	"github.com/Azure/go-autorest/autorest/adal"
 	"github.com/Azure/go-autorest/autorest/azure"
 
@@ -38,6 +42,10 @@ var (
 	ErrorNoAuth = fmt.Errorf("no credentials provided for Azure cloud provider")
 )
 
+const (
+	maxReadLength = 10 * 1 << 20 // 10MB
+)
+
 // AzureAuthConfig holds auth related part of cloud config
 type AzureAuthConfig struct {
 	// The cloud environment identifier. Takes values from https://github.com/Azure/go-autorest/blob/ec5f4903f77ed9927ac95b19ab8e44ada64c1356/autorest/azure/environments.go#L13
@@ -137,7 +145,7 @@ func GetServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment, r
 
 	if len(config.AADClientCertPath) > 0 && len(config.AADClientCertPassword) > 0 {
 		klog.V(2).Infoln("azure: using jwt client_assertion (client_cert+client_private_key) to retrieve access token")
-		certData, err := ioutil.ReadFile(config.AADClientCertPath)
+		certData, err := os.ReadFile(config.AADClientCertPath)
 		if err != nil {
 			return nil, fmt.Errorf("reading the client certificate from file %s: %w", config.AADClientCertPath, err)
 		}
@@ -248,6 +256,35 @@ func ParseAzureEnvironment(cloudName, resourceManagerEndpoint, identitySystem st
 	return &env, err
 }
 
+// ParseAzureAuthConfig returns a parsed configuration for an Azure cloudprovider config file
+func ParseAzureAuthConfig(configReader io.Reader) (*AzureAuthConfig, *azure.Environment, error) {
+	var config AzureAuthConfig
+
+	if configReader == nil {
+		return nil, nil, errors.New("nil config is provided")
+	}
+
+	limitedReader := &io.LimitedReader{R: configReader, N: maxReadLength}
+	configContents, err := io.ReadAll(limitedReader)
+	if err != nil {
+		return nil, nil, err
+	}
+	if limitedReader.N <= 0 {
+		return nil, nil, errors.New("the read limit is reached")
+	}
+	err = yaml.Unmarshal(configContents, &config)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	environment, err := ParseAzureEnvironment(config.Cloud, config.ResourceManagerEndpoint, config.IdentitySystem)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return &config, environment, nil
+}
+
 // UsesNetworkResourceInDifferentTenant determines whether the AzureAuthConfig indicates to use network resources in
 // different AAD Tenant than those for the cluster. Return true when NetworkResourceTenantID is specified  and not equal
 // to one defined in global configs
diff --git a/pkg/auth/doc.go b/pkg/provider/config/doc.go
similarity index 88%
rename from pkg/auth/doc.go
rename to pkg/provider/config/doc.go
index 52e1d5da9..3ad7a5daa 100644
--- a/pkg/auth/doc.go
+++ b/pkg/provider/config/doc.go
@@ -15,4 +15,4 @@ limitations under the License.
 */
 
 // Package auth provides a general library to authorize Azure ARM clients.
-package auth // import "sigs.k8s.io/cloud-provider-azure/pkg/auth"
+package config // import "sigs.k8s.io/cloud-provider-azure/pkg/provider/config"


Test patch:
diff --git a/pkg/provider/azure_config_test.go b/pkg/provider/azure_config_test.go
index ac2e2eaa6..3f6ddabb0 100644
--- a/pkg/provider/azure_config_test.go
+++ b/pkg/provider/azure_config_test.go
@@ -20,6 +20,8 @@ import (
 	"context"
 	"testing"
 
+	"sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
+
 	"sigs.k8s.io/cloud-provider-azure/pkg/consts"
 
 	"github.com/golang/mock/gomock"
@@ -34,13 +36,11 @@ import (
 	fakeclient "k8s.io/client-go/kubernetes/fake"
 
 	"sigs.k8s.io/yaml"
-
-	"sigs.k8s.io/cloud-provider-azure/pkg/auth"
 )
 
 func getTestConfig() *Config {
 	return &Config{
-		AzureAuthConfig: auth.AzureAuthConfig{
+		AzureAuthConfig: config.AzureAuthConfig{
 			TenantID:        "TenantID",
 			SubscriptionID:  "SubscriptionID",
 			AADClientID:     "AADClientID",
@@ -61,7 +61,7 @@ func getTestConfig() *Config {
 
 func getTestCloudConfigTypeSecretConfig() *Config {
 	return &Config{
-		AzureAuthConfig: auth.AzureAuthConfig{
+		AzureAuthConfig: config.AzureAuthConfig{
 			TenantID:       "TenantID",
 			SubscriptionID: "SubscriptionID",
 		},
@@ -75,7 +75,7 @@ func getTestCloudConfigTypeSecretConfig() *Config {
 
 func getTestCloudConfigTypeMergeConfig() *Config {
 	return &Config{
-		AzureAuthConfig: auth.AzureAuthConfig{
+		AzureAuthConfig: config.AzureAuthConfig{
 			TenantID:       "TenantID",
 			SubscriptionID: "SubscriptionID",
 		},
diff --git a/pkg/provider/azure_test.go b/pkg/provider/azure_test.go
index 443e6dca6..a87cf097b 100644
--- a/pkg/provider/azure_test.go
+++ b/pkg/provider/azure_test.go
@@ -41,7 +41,6 @@ import (
 	cloudproviderapi "k8s.io/cloud-provider/api"
 	servicehelpers "k8s.io/cloud-provider/service/helpers"
 
-	"sigs.k8s.io/cloud-provider-azure/pkg/auth"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/interfaceclient/mockinterfaceclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatelinkserviceclient/mockprivatelinkserviceclient"
@@ -51,6 +50,7 @@ import (
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmclient/mockvmclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/mockzoneclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/consts"
+	providerconfig "sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
 	"sigs.k8s.io/cloud-provider-azure/pkg/retry"
 )
 
@@ -3619,7 +3619,7 @@ func TestInitializeCloudFromConfig(t *testing.T) {
 	assert.Equal(t, expectedErr, err)
 
 	config = Config{
-		AzureAuthConfig: auth.AzureAuthConfig{
+		AzureAuthConfig: providerconfig.AzureAuthConfig{
 			Cloud: "AZUREPUBLICCLOUD",
 		},
 		CloudConfigType: cloudConfigTypeFile,
diff --git a/pkg/auth/azure_auth_test.go b/pkg/provider/config/azure_auth_test.go
similarity index 99%
rename from pkg/auth/azure_auth_test.go
rename to pkg/provider/config/azure_auth_test.go
index 47acdaeb4..b818333c1 100644
--- a/pkg/auth/azure_auth_test.go
+++ b/pkg/provider/config/azure_auth_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package auth
+package config
 
 import (
 	"io/ioutil"