@@ -60,12 +60,13 @@ var storageAccountInvalidCharRe = regexp.MustCompile(`[^0-9A-Za-z]`)
60
60
// Azure holds configuration used to reach Azure's endpoints.
61
61
type Azure struct {
62
62
// IPI
63
- SubscriptionID string
64
- ClientID string
65
- ClientSecret string
66
- TenantID string
67
- ResourceGroup string
68
- Region string
63
+ SubscriptionID string
64
+ ClientID string
65
+ ClientSecret string
66
+ TenantID string
67
+ ResourceGroup string
68
+ Region string
69
+ FederatedTokenFile string
69
70
70
71
// UPI
71
72
AccountKey string
@@ -95,14 +96,27 @@ func GetConfig(secLister kcorelisters.SecretNamespaceLister, infraLister configl
95
96
return nil , fmt .Errorf ("unable to get cluster minted credentials: %s" , err )
96
97
}
97
98
98
- return & Azure {
99
- SubscriptionID : string (sec .Data ["azure_subscription_id" ]),
100
- ClientID : string (sec .Data ["azure_client_id" ]),
101
- ClientSecret : string (sec .Data ["azure_client_secret" ]),
102
- TenantID : string (sec .Data ["azure_tenant_id" ]),
103
- ResourceGroup : string (sec .Data ["azure_resourcegroup" ]),
104
- Region : string (sec .Data ["azure_region" ]),
105
- }, nil
99
+ cfg := & Azure {
100
+ SubscriptionID : string (sec .Data ["azure_subscription_id" ]),
101
+ ClientID : string (sec .Data ["azure_client_id" ]),
102
+ ClientSecret : string (sec .Data ["azure_client_secret" ]),
103
+ TenantID : string (sec .Data ["azure_tenant_id" ]),
104
+ ResourceGroup : string (sec .Data ["azure_resourcegroup" ]),
105
+ Region : string (sec .Data ["azure_region" ]),
106
+ FederatedTokenFile : string (sec .Data ["azure_federated_token_file" ]),
107
+ }
108
+
109
+ // when using azure workload identities, the secret does not contain
110
+ // a resource group, as it is not known at the time of its creation.
111
+ if cfg .ResourceGroup == "" {
112
+ infra , err := util .GetInfrastructure (infraLister )
113
+ if err != nil {
114
+ return nil , fmt .Errorf ("unable to get infrastructure object: %s" , err )
115
+ }
116
+ cfg .ResourceGroup = infra .Status .PlatformStatus .Azure .ResourceGroupName
117
+ }
118
+
119
+ return cfg , nil
106
120
}
107
121
108
122
// loads user provided account key.
@@ -316,15 +330,36 @@ func (d *driver) storageAccountsClient(cfg *Azure, environment autorestazure.Env
316
330
},
317
331
},
318
332
}
319
- options := azidentity.ClientSecretCredentialOptions {
320
- ClientOptions : azcore.ClientOptions {
321
- Cloud : cloudConfig ,
322
- },
323
- }
324
- cred , err := azidentity .NewClientSecretCredential (cfg .TenantID , cfg .ClientID , cfg .ClientSecret , & options )
325
- if err != nil {
326
- return storage.AccountsClient {}, err
333
+
334
+ var (
335
+ cred azcore.TokenCredential
336
+ err error
337
+ )
338
+ if strings .TrimSpace (cfg .ClientSecret ) == "" {
339
+ options := azidentity.WorkloadIdentityCredentialOptions {
340
+ ClientOptions : azcore.ClientOptions {
341
+ Cloud : cloudConfig ,
342
+ },
343
+ ClientID : cfg .ClientID ,
344
+ TenantID : cfg .TenantID ,
345
+ TokenFilePath : cfg .FederatedTokenFile ,
346
+ }
347
+ cred , err = azidentity .NewWorkloadIdentityCredential (& options )
348
+ if err != nil {
349
+ return storage.AccountsClient {}, err
350
+ }
351
+ } else {
352
+ options := azidentity.ClientSecretCredentialOptions {
353
+ ClientOptions : azcore.ClientOptions {
354
+ Cloud : cloudConfig ,
355
+ },
356
+ }
357
+ cred , err = azidentity .NewClientSecretCredential (cfg .TenantID , cfg .ClientID , cfg .ClientSecret , & options )
358
+ if err != nil {
359
+ return storage.AccountsClient {}, err
360
+ }
327
361
}
362
+
328
363
scope := environment .TokenAudience
329
364
if ! strings .HasSuffix (scope , "/.default" ) {
330
365
scope += "/.default"
0 commit comments