sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/scope/clients.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package scope
    18  
    19  import (
    20  	"context"
    21  	"crypto/sha256"
    22  	"encoding/base64"
    23  	"fmt"
    24  	"os"
    25  	"strings"
    26  
    27  	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
    28  	"github.com/Azure/go-autorest/autorest"
    29  	azureautorest "github.com/Azure/go-autorest/autorest/azure"
    30  	"github.com/Azure/go-autorest/autorest/azure/auth"
    31  )
    32  
    33  // AzureClients contains all the Azure clients used by the scopes.
    34  type AzureClients struct {
    35  	auth.EnvironmentSettings
    36  
    37  	Authorizer                 autorest.Authorizer
    38  	TokenCredential            azcore.TokenCredential
    39  	ResourceManagerEndpoint    string
    40  	ResourceManagerVMDNSSuffix string
    41  }
    42  
    43  // CloudEnvironment returns the Azure environment the controller runs in.
    44  func (c *AzureClients) CloudEnvironment() string {
    45  	return c.Environment.Name
    46  }
    47  
    48  // TenantID returns the Azure tenant id the controller runs in.
    49  func (c *AzureClients) TenantID() string {
    50  	return c.Values[auth.TenantID]
    51  }
    52  
    53  // ClientID returns the Azure client id from the controller environment.
    54  func (c *AzureClients) ClientID() string {
    55  	return c.Values[auth.ClientID]
    56  }
    57  
    58  // ClientSecret returns the Azure client secret from the controller environment.
    59  func (c *AzureClients) ClientSecret() string {
    60  	return c.Values[auth.ClientSecret]
    61  }
    62  
    63  // SubscriptionID returns the Azure subscription id of the cluster,
    64  // either specified or from the environment.
    65  func (c *AzureClients) SubscriptionID() string {
    66  	return c.Values[auth.SubscriptionID]
    67  }
    68  
    69  // Token returns the Azure token credential of the cluster used for SDKv2 services.
    70  func (c *AzureClients) Token() azcore.TokenCredential {
    71  	return c.TokenCredential
    72  }
    73  
    74  // HashKey returns a base64 url encoded sha256 hash for the Auth scope (Azure TenantID + CloudEnv + SubscriptionID +
    75  // ClientID).
    76  func (c *AzureClients) HashKey() string {
    77  	hasher := sha256.New()
    78  	_, _ = hasher.Write([]byte(c.TenantID() + c.CloudEnvironment() + c.SubscriptionID() + c.ClientID()))
    79  	return base64.URLEncoding.EncodeToString(hasher.Sum(nil))
    80  }
    81  
    82  func (c *AzureClients) setCredentialsWithProvider(ctx context.Context, subscriptionID, environmentName string, credentialsProvider CredentialsProvider) error {
    83  	if credentialsProvider == nil {
    84  		return fmt.Errorf("credentials provider cannot have an empty value")
    85  	}
    86  
    87  	settings, err := c.getSettingsFromEnvironment(environmentName)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	if subscriptionID == "" {
    93  		subscriptionID = settings.GetSubscriptionID()
    94  		if subscriptionID == "" {
    95  			return fmt.Errorf("error creating azure services. subscriptionID is not set in cluster or AZURE_SUBSCRIPTION_ID env var")
    96  		}
    97  	}
    98  
    99  	c.EnvironmentSettings = settings
   100  	c.ResourceManagerEndpoint = settings.Environment.ResourceManagerEndpoint
   101  	c.ResourceManagerVMDNSSuffix = settings.Environment.ResourceManagerVMDNSSuffix
   102  	c.Values[auth.SubscriptionID] = strings.TrimSuffix(subscriptionID, "\n")
   103  	c.Values[auth.TenantID] = strings.TrimSuffix(credentialsProvider.GetTenantID(), "\n")
   104  	c.Values[auth.ClientID] = strings.TrimSuffix(credentialsProvider.GetClientID(), "\n")
   105  
   106  	clientSecret, err := credentialsProvider.GetClientSecret(ctx)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	c.Values[auth.ClientSecret] = strings.TrimSuffix(clientSecret, "\n")
   111  
   112  	tokenCredential, err := credentialsProvider.GetTokenCredential(ctx, c.ResourceManagerEndpoint, c.Environment.ActiveDirectoryEndpoint, c.Environment.TokenAudience)
   113  	if err != nil {
   114  		return err
   115  	}
   116  	c.TokenCredential = tokenCredential
   117  	c.Authorizer, err = credentialsProvider.GetAuthorizer(ctx, tokenCredential, c.Environment.TokenAudience)
   118  	return err
   119  }
   120  
   121  func (c *AzureClients) getSettingsFromEnvironment(environmentName string) (s auth.EnvironmentSettings, err error) {
   122  	s = auth.EnvironmentSettings{
   123  		Values: map[string]string{},
   124  	}
   125  	s.Values[auth.EnvironmentName] = environmentName
   126  	setValue(s, auth.SubscriptionID)
   127  	setValue(s, auth.TenantID)
   128  	setValue(s, auth.AuxiliaryTenantIDs)
   129  	setValue(s, auth.ClientID)
   130  	setValue(s, auth.ClientSecret)
   131  	setValue(s, auth.CertificatePath)
   132  	setValue(s, auth.CertificatePassword)
   133  	setValue(s, auth.Username)
   134  	setValue(s, auth.Password)
   135  	setValue(s, auth.Resource)
   136  	if v := s.Values[auth.EnvironmentName]; v == "" {
   137  		s.Environment = azureautorest.PublicCloud
   138  	} else {
   139  		s.Environment, err = azureautorest.EnvironmentFromName(v)
   140  	}
   141  	if s.Values[auth.Resource] == "" {
   142  		s.Values[auth.Resource] = s.Environment.ResourceManagerEndpoint
   143  	}
   144  	return
   145  }
   146  
   147  // setValue adds the specified environment variable value to the Values map if it exists.
   148  func setValue(settings auth.EnvironmentSettings, key string) {
   149  	if v := os.Getenv(key); v != "" {
   150  		settings.Values[key] = v
   151  	}
   152  }