|
9 | 9 | "reflect"
|
10 | 10 | "regexp"
|
11 | 11 | "strings"
|
| 12 | + "sync" |
12 | 13 | "time"
|
13 | 14 |
|
14 | 15 | "github.com/Azure/azure-pipeline-go/pipeline"
|
@@ -53,6 +54,7 @@ const (
|
53 | 54 | storageExistsReasonContainerDeleted = "ContainerDeleted"
|
54 | 55 | storageExistsReasonAccountDeleted = "AccountDeleted"
|
55 | 56 | storageExistsReasonAccountNotFound = "AccountNotFound"
|
| 57 | + azureCredentialsKey = "AzureCredentials" |
56 | 58 | )
|
57 | 59 |
|
58 | 60 | // storageAccountInvalidCharRe is a regular expression for characters that
|
@@ -316,6 +318,10 @@ type driver struct {
|
316 | 318 | // policies is for new Azure Client Pipeline execution.
|
317 | 319 | // Added as a member to the struct to allow injection for testing.
|
318 | 320 | policies []policy.Policy
|
| 321 | + |
| 322 | + // azureCredentials keeps track if we have already loaded an Azure |
| 323 | + // credentials token when using UAMI for managed Azure on HCP. |
| 324 | + azureCredentials sync.Map |
319 | 325 | }
|
320 | 326 |
|
321 | 327 | // NewDriver creates a new storage driver for Azure Blob Storage.
|
@@ -371,16 +377,29 @@ func (d *driver) storageAccountsClient(cfg *Azure, environment autorestazure.Env
|
371 | 377 | cred azcore.TokenCredential
|
372 | 378 | err error
|
373 | 379 | )
|
| 380 | + |
| 381 | + // UserAssignedIdentityCredentials is specifically for managed Azure HCP |
374 | 382 | userAssignedIdentityCredentialsFilePath := os.Getenv("MANAGED_AZURE_HCP_CREDENTIALS_FILE_PATH")
|
375 | 383 | if userAssignedIdentityCredentialsFilePath != "" {
|
376 |
| - // UserAssignedIdentityCredentials for managed Azure HCP |
377 |
| - klog.V(2).Info("Using UserAssignedIdentityCredentials for Azure authentication for managed Azure HCP") |
378 |
| - clientOptions := azcore.ClientOptions{ |
379 |
| - Cloud: cloudConfig, |
380 |
| - } |
381 |
| - cred, err = dataplane.NewUserAssignedIdentityCredential(context.Background(), userAssignedIdentityCredentialsFilePath, dataplane.WithClientOpts(clientOptions)) |
382 |
| - if err != nil { |
383 |
| - return storage.AccountsClient{}, err |
| 384 | + var ok bool |
| 385 | + |
| 386 | + // We need to only store the Azure credentials once and reuse them after that. |
| 387 | + storedCreds, found := d.azureCredentials.Load(userAssignedIdentityCredentialsFilePath) |
| 388 | + if !found { |
| 389 | + klog.V(2).Info("Using UserAssignedIdentityCredentials for Azure authentication for managed Azure HCP") |
| 390 | + clientOptions := azcore.ClientOptions{ |
| 391 | + Cloud: cloudConfig, |
| 392 | + } |
| 393 | + cred, err = dataplane.NewUserAssignedIdentityCredential(context.Background(), userAssignedIdentityCredentialsFilePath, dataplane.WithClientOpts(clientOptions)) |
| 394 | + if err != nil { |
| 395 | + return storage.AccountsClient{}, err |
| 396 | + } |
| 397 | + d.azureCredentials.Store(azureCredentialsKey, cred) |
| 398 | + } else { |
| 399 | + cred, ok = storedCreds.(azcore.TokenCredential) |
| 400 | + if !ok { |
| 401 | + return storage.AccountsClient{}, fmt.Errorf("expected %T to be a TokenCredential", storedCreds) |
| 402 | + } |
384 | 403 | }
|
385 | 404 | } else if strings.TrimSpace(cfg.ClientSecret) == "" {
|
386 | 405 | options := azidentity.WorkloadIdentityCredentialOptions{
|
|
0 commit comments