Skip to content

Commit 2cff080

Browse files
committed
wip
1 parent 5969417 commit 2cff080

File tree

1 file changed

+72
-23
lines changed

1 file changed

+72
-23
lines changed

pkg/storage/azure/azure.go

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ const (
5757
azureCredentialsKey = "AzureCredentials"
5858
)
5959

60+
// globalAzureCredentials caches User Assigned Managed Identity (UAMI) credentials across driver instances so that
61+
// reconciles do not recreate the credential repeatedly.
62+
var globalAzureCredentials sync.Map
63+
6064
// storageAccountInvalidCharRe is a regular expression for characters that
6165
// cannot be used in Azure storage accounts names (i.e. that are not
6266
// numbers nor lower-case letters) and that are not upper-case letters. If
@@ -334,7 +338,7 @@ func NewDriver(ctx context.Context, c *imageregistryv1.ImageRegistryConfigStorag
334338
}
335339

336340
func (d *driver) newAzClient(cfg *Azure, environment autorestazure.Environment, tagset map[string]*string) (*azureclient.Client, error) {
337-
client, err := azureclient.New(&azureclient.Options{
341+
clientOptions := &azureclient.Options{
338342
Environment: environment,
339343
TenantID: cfg.TenantID,
340344
ClientID: cfg.ClientID,
@@ -343,10 +347,19 @@ func (d *driver) newAzClient(cfg *Azure, environment autorestazure.Environment,
343347
SubscriptionID: cfg.SubscriptionID,
344348
TagSet: tagset,
345349
Policies: d.policies,
346-
})
350+
}
351+
352+
if cred, ok, err := d.ensureUAMICred(d.Context, environment); err != nil {
353+
return nil, err
354+
} else if ok {
355+
clientOptions.Creds = cred
356+
}
357+
358+
client, err := azureclient.New(clientOptions)
347359
if err != nil {
348360
return nil, err
349361
}
362+
350363
return client, nil
351364
}
352365

@@ -381,25 +394,10 @@ func (d *driver) storageAccountsClient(cfg *Azure, environment autorestazure.Env
381394
// UserAssignedIdentityCredentials is specifically for managed Azure HCP
382395
userAssignedIdentityCredentialsFilePath := os.Getenv("MANAGED_AZURE_HCP_CREDENTIALS_FILE_PATH")
383396
if userAssignedIdentityCredentialsFilePath != "" {
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(azureCredentialsKey)
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-
}
397+
if c, ok, err := d.ensureUAMICred(d.Context, environment); err != nil {
398+
return storage.AccountsClient{}, err
399+
} else if ok {
400+
cred = c
403401
}
404402
} else if strings.TrimSpace(cfg.ClientSecret) == "" {
405403
options := azidentity.WorkloadIdentityCredentialOptions{
@@ -1237,14 +1235,30 @@ func (d *driver) RemoveStorage(cr *imageregistryv1.Config) (retry bool, err erro
12371235
}
12381236

12391237
if d.Config.NetworkAccess != nil && d.Config.NetworkAccess.Internal != nil && d.Config.NetworkAccess.Internal.PrivateEndpointName != "" {
1240-
azclient, err := azureclient.New(&azureclient.Options{
1238+
clientOptions := &azureclient.Options{
12411239
Environment: environment,
12421240
TenantID: cfg.TenantID,
12431241
ClientID: cfg.ClientID,
12441242
ClientSecret: cfg.ClientSecret,
12451243
FederatedTokenFile: cfg.FederatedTokenFile,
12461244
SubscriptionID: cfg.SubscriptionID,
1247-
})
1245+
}
1246+
1247+
if cred, ok, err := d.ensureUAMICred(d.Context, environment); err != nil {
1248+
util.UpdateCondition(
1249+
cr,
1250+
defaults.StorageExists,
1251+
operatorapiv1.ConditionUnknown,
1252+
storageExistsReasonAzureError,
1253+
fmt.Sprintf("Unable to get azure client: %s", err),
1254+
)
1255+
return false, err
1256+
} else if ok {
1257+
klog.V(2).Infof("Using cached UAMI credential for RemoveStorage client")
1258+
clientOptions.Creds = cred
1259+
}
1260+
1261+
azclient, err := azureclient.New(clientOptions)
12481262
if err != nil {
12491263
util.UpdateCondition(
12501264
cr,
@@ -1320,3 +1334,38 @@ func (d *driver) RemoveStorage(cr *imageregistryv1.Config) (retry bool, err erro
13201334
func (d *driver) ID() string {
13211335
return d.Config.Container
13221336
}
1337+
1338+
func (d *driver) ensureUAMICred(ctx context.Context, env autorestazure.Environment) (azcore.TokenCredential, bool, error) {
1339+
if stored, ok := globalAzureCredentials.Load(azureCredentialsKey); ok {
1340+
if cred, ok := stored.(azcore.TokenCredential); ok {
1341+
klog.V(2).Infof("Loaded UAMICred from driver cache")
1342+
return cred, true, nil
1343+
}
1344+
return nil, false, fmt.Errorf("expected cached credential to be azcore.TokenCredential")
1345+
}
1346+
if os.Getenv("MANAGED_AZURE_HCP_CREDENTIALS_FILE_PATH") == "" {
1347+
return nil, false, nil
1348+
}
1349+
cloudConfig := cloud.Configuration{
1350+
ActiveDirectoryAuthorityHost: env.ActiveDirectoryEndpoint,
1351+
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
1352+
cloud.ResourceManager: {
1353+
Audience: env.TokenAudience,
1354+
Endpoint: env.ResourceManagerEndpoint,
1355+
},
1356+
},
1357+
}
1358+
cred, err := dataplane.NewUserAssignedIdentityCredential(
1359+
ctx,
1360+
os.Getenv("MANAGED_AZURE_HCP_CREDENTIALS_FILE_PATH"),
1361+
dataplane.WithClientOpts(azcore.ClientOptions{Cloud: cloudConfig}),
1362+
)
1363+
if err != nil {
1364+
return nil, false, err
1365+
}
1366+
if actual, loaded := globalAzureCredentials.LoadOrStore(azureCredentialsKey, cred); loaded {
1367+
return actual.(azcore.TokenCredential), true, nil
1368+
}
1369+
klog.V(2).Infof("Storing UAMICred for driver")
1370+
return cred, true, nil
1371+
}

0 commit comments

Comments
 (0)