@@ -17,156 +17,59 @@ limitations under the License.
1717package azclient
1818
1919import (
20- "context "
20+ "errors "
2121 "fmt"
22- "os"
2322 "strings"
2423
2524 "github.com/Azure/azure-sdk-for-go/sdk/azcore"
25+ "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
2626 "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
27- "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
28- "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
29- "github.com/Azure/msi-dataplane/pkg/dataplane"
27+ )
3028
31- "sigs.k8s.io/cloud-provider-azure/pkg/azclient/armauth"
29+ var (
30+ ErrNoValidAuthMethodFound = errors .New ("no valid authentication method found" )
3231)
3332
3433type AuthProvider struct {
35- ComputeCredential azcore.TokenCredential
36- NetworkCredential azcore. TokenCredential
37- MultiTenantCredential azcore.TokenCredential
38- CloudConfig cloud.Configuration
34+ ComputeCredential azcore.TokenCredential
35+ AdditionalComputeClientOptions [] func ( option * arm. ClientOptions )
36+ NetworkCredential azcore.TokenCredential
37+ CloudConfig cloud.Configuration
3938}
4039
41- func NewAuthProvider (armConfig * ARMClientConfig , config * AzureAuthConfig , clientOptionsMutFn ... func (option * policy.ClientOptions )) (* AuthProvider , error ) {
40+ func NewAuthProvider (
41+ armConfig * ARMClientConfig ,
42+ config * AzureAuthConfig ,
43+ options ... AuthProviderOption ,
44+ ) (* AuthProvider , error ) {
45+ opts := defaultAuthProviderOptions ()
46+ for _ , opt := range options {
47+ opt (opts )
48+ }
49+
4250 clientOption , _ , err := GetAzCoreClientOption (armConfig )
4351 if err != nil {
4452 return nil , err
4553 }
46- for _ , fn := range clientOptionsMutFn {
54+ for _ , fn := range opts . ClientOptionsMutFn {
4755 fn (clientOption )
4856 }
49- var computeCredential azcore.TokenCredential
50- var networkTokenCredential azcore.TokenCredential
51- var multiTenantCredential azcore.TokenCredential
52-
53- // federatedIdentityCredential is used for workload identity federation
54- if aadFederatedTokenFile , enabled := config .GetAzureFederatedTokenFile (); enabled {
55- computeCredential , err = azidentity .NewWorkloadIdentityCredential (& azidentity.WorkloadIdentityCredentialOptions {
56- ClientOptions : * clientOption ,
57- ClientID : config .GetAADClientID (),
58- TenantID : armConfig .GetTenantID (),
59- TokenFilePath : aadFederatedTokenFile ,
60- })
61- if err != nil {
62- return nil , err
63- }
64- }
65- // managedIdentityCredential is used for managed identity extension
66- if computeCredential == nil && config .UseManagedIdentityExtension {
67- credOptions := & azidentity.ManagedIdentityCredentialOptions {
68- ClientOptions : * clientOption ,
69- }
70- if len (config .UserAssignedIdentityID ) > 0 {
71- if strings .Contains (strings .ToUpper (config .UserAssignedIdentityID ), "/SUBSCRIPTIONS/" ) {
72- credOptions .ID = azidentity .ResourceID (config .UserAssignedIdentityID )
73- } else {
74- credOptions .ID = azidentity .ClientID (config .UserAssignedIdentityID )
75- }
76- }
77- computeCredential , err = azidentity .NewManagedIdentityCredential (credOptions )
78- if err != nil {
79- return nil , err
80- }
81- if config .AuxiliaryTokenProvider != nil && IsMultiTenant (armConfig ) {
82- networkTokenCredential , err = armauth .NewKeyVaultCredential (
83- computeCredential ,
84- config .AuxiliaryTokenProvider .SecretResourceID (),
85- )
86- if err != nil {
87- return nil , fmt .Errorf ("create KeyVaultCredential for auxiliary token provider: %w" , err )
88- }
89- }
90- }
91-
92- // Client secret authentication
93- if computeCredential == nil && len (config .GetAADClientSecret ()) > 0 {
94- credOptions := & azidentity.ClientSecretCredentialOptions {
95- ClientOptions : * clientOption ,
96- }
97- computeCredential , err = azidentity .NewClientSecretCredential (armConfig .GetTenantID (), config .GetAADClientID (), config .GetAADClientSecret (), credOptions )
98- if err != nil {
99- return nil , err
100- }
101- if IsMultiTenant (armConfig ) {
102- credOptions := & azidentity.ClientSecretCredentialOptions {
103- ClientOptions : * clientOption ,
104- }
105- networkTokenCredential , err = azidentity .NewClientSecretCredential (armConfig .NetworkResourceTenantID , config .GetAADClientID (), config .AADClientSecret , credOptions )
106- if err != nil {
107- return nil , err
108- }
109-
110- credOptions = & azidentity.ClientSecretCredentialOptions {
111- ClientOptions : * clientOption ,
112- AdditionallyAllowedTenants : []string {armConfig .NetworkResourceTenantID },
113- }
114- multiTenantCredential , err = azidentity .NewClientSecretCredential (armConfig .GetTenantID (), config .GetAADClientID (), config .GetAADClientSecret (), credOptions )
115- if err != nil {
116- return nil , err
117- }
118-
119- }
120- }
12157
122- // ClientCertificateCredential is used for client certificate
123- if computeCredential == nil && len (config .AADClientCertPath ) > 0 {
124- credOptions := & azidentity.ClientCertificateCredentialOptions {
125- ClientOptions : * clientOption ,
126- SendCertificateChain : true ,
127- }
128- certData , err := os .ReadFile (config .AADClientCertPath )
129- if err != nil {
130- return nil , fmt .Errorf ("reading the client certificate from file %s: %w" , config .AADClientCertPath , err )
131- }
132- certificate , privateKey , err := azidentity .ParseCertificates (certData , []byte (config .AADClientCertPassword ))
133- if err != nil {
134- return nil , fmt .Errorf ("decoding the client certificate: %w" , err )
135- }
136- computeCredential , err = azidentity .NewClientCertificateCredential (armConfig .GetTenantID (), config .GetAADClientID (), certificate , privateKey , credOptions )
137- if err != nil {
138- return nil , err
139- }
140- if IsMultiTenant (armConfig ) {
141- networkTokenCredential , err = azidentity .NewClientCertificateCredential (armConfig .NetworkResourceTenantID , config .GetAADClientID (), certificate , privateKey , credOptions )
142- if err != nil {
143- return nil , err
144- }
145- credOptions = & azidentity.ClientCertificateCredentialOptions {
146- ClientOptions : * clientOption ,
147- AdditionallyAllowedTenants : []string {armConfig .NetworkResourceTenantID },
148- }
149- multiTenantCredential , err = azidentity .NewClientCertificateCredential (armConfig .GetTenantID (), config .GetAADClientID (), certificate , privateKey , credOptions )
150- if err != nil {
151- return nil , err
152- }
153- }
58+ aadFederatedTokenFile , federatedTokenEnabled := config .GetAzureFederatedTokenFile ()
59+ switch {
60+ case federatedTokenEnabled :
61+ return newAuthProviderWithWorkloadIdentity (aadFederatedTokenFile , armConfig , config , clientOption , opts )
62+ case config .UseManagedIdentityExtension :
63+ return newAuthProviderWithManagedIdentity (armConfig , config , clientOption , opts )
64+ case len (config .GetAADClientSecret ()) > 0 :
65+ return newAuthProviderWithServicePrincipalClientSecret (armConfig , config , clientOption , opts )
66+ case len (config .AADClientCertPath ) > 0 :
67+ return newAuthProviderWithServicePrincipalClientCertificate (armConfig , config , clientOption , opts )
68+ case len (config .AADMSIDataPlaneIdentityPath ) > 0 :
69+ return newAuthProviderWithUserAssignedIdentity (config , clientOption , opts )
70+ default :
71+ return nil , ErrNoValidAuthMethodFound
15472 }
155-
156- // UserAssignedIdentityCredentials authentication
157- if computeCredential == nil && len (config .AADMSIDataPlaneIdentityPath ) > 0 {
158- computeCredential , err = dataplane .NewUserAssignedIdentityCredential (context .Background (), config .AADMSIDataPlaneIdentityPath , dataplane .WithClientOpts (azcore.ClientOptions {Cloud : clientOption .Cloud }))
159- if err != nil {
160- return nil , err
161- }
162- }
163-
164- return & AuthProvider {
165- ComputeCredential : computeCredential ,
166- NetworkCredential : networkTokenCredential ,
167- MultiTenantCredential : multiTenantCredential ,
168- CloudConfig : clientOption .Cloud ,
169- }, nil
17073}
17174
17275func (factory * AuthProvider ) GetAzIdentity () azcore.TokenCredential {
@@ -180,18 +83,11 @@ func (factory *AuthProvider) GetNetworkAzIdentity() azcore.TokenCredential {
18083 return factory .ComputeCredential
18184}
18285
183- func (factory * AuthProvider ) GetMultiTenantIdentity () azcore.TokenCredential {
184- if factory .MultiTenantCredential != nil {
185- return factory .MultiTenantCredential
186- }
187- return factory .ComputeCredential
188- }
189-
190- func (factory * AuthProvider ) IsMultiTenantModeEnabled () bool {
191- return factory .MultiTenantCredential != nil
86+ func (factory * AuthProvider ) DefaultTokenScope () string {
87+ return DefaultTokenScopeFor (factory .CloudConfig )
19288}
19389
194- func ( factory * AuthProvider ) DefaultTokenScope ( ) string {
195- audience := factory . CloudConfig .Services [cloud .ResourceManager ].Audience
90+ func DefaultTokenScopeFor ( cloudCfg cloud. Configuration ) string {
91+ audience := cloudCfg .Services [cloud .ResourceManager ].Audience
19692 return fmt .Sprintf ("%s/.default" , strings .TrimRight (audience , "/" ))
19793}
0 commit comments