Skip to content

Commit 5b2cbce

Browse files
authored
Merge pull request #5283 from nojnhuh/credcache
cache credentials from AzureClusterIdentity
2 parents 4179aa1 + 34b748e commit 5b2cbce

34 files changed

+274
-253
lines changed

azure/scope/cluster.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ import (
5858
// ClusterScopeParams defines the input parameters used to create a new Scope.
5959
type ClusterScopeParams struct {
6060
AzureClients
61-
Client client.Client
62-
Cluster *clusterv1.Cluster
63-
AzureCluster *infrav1.AzureCluster
64-
Cache *ClusterCache
65-
Timeouts azure.AsyncReconciler
61+
Client client.Client
62+
Cluster *clusterv1.Cluster
63+
AzureCluster *infrav1.AzureCluster
64+
Cache *ClusterCache
65+
Timeouts azure.AsyncReconciler
66+
CredentialCache azure.CredentialCache
6667
}
6768

6869
// NewClusterScope creates a new Scope from the supplied parameters.
@@ -78,7 +79,7 @@ func NewClusterScope(ctx context.Context, params ClusterScopeParams) (*ClusterSc
7879
return nil, errors.New("failed to generate new scope from nil AzureCluster")
7980
}
8081

81-
credentialsProvider, err := NewAzureCredentialsProvider(ctx, params.Client, params.AzureCluster.Spec.IdentityRef, params.AzureCluster.Namespace)
82+
credentialsProvider, err := NewAzureCredentialsProvider(ctx, params.CredentialCache, params.Client, params.AzureCluster.Spec.IdentityRef, params.AzureCluster.Namespace)
8283
if err != nil {
8384
return nil, errors.Wrap(err, "failed to init credentials provider")
8485
}

azure/scope/cluster_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,10 @@ func TestNewClusterScope(t *testing.T) {
116116
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build()
117117

118118
_, err := NewClusterScope(context.TODO(), ClusterScopeParams{
119-
Cluster: cluster,
120-
AzureCluster: azureCluster,
121-
Client: fakeClient,
119+
Cluster: cluster,
120+
AzureCluster: azureCluster,
121+
Client: fakeClient,
122+
CredentialCache: azure.NewCredentialCache(),
122123
})
123124
g.Expect(err).NotTo(HaveOccurred())
124125
}

azure/scope/identity.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"sigs.k8s.io/controller-runtime/pkg/client"
3333

3434
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
35+
"sigs.k8s.io/cluster-api-provider-azure/azure"
3536
"sigs.k8s.io/cluster-api-provider-azure/pkg/ot"
3637
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
3738
)
@@ -52,10 +53,12 @@ type CredentialsProvider interface {
5253
type AzureCredentialsProvider struct {
5354
Client client.Client
5455
Identity *infrav1.AzureClusterIdentity
56+
57+
cache azure.CredentialCache
5558
}
5659

5760
// NewAzureCredentialsProvider creates a new AzureClusterCredentialsProvider from the supplied inputs.
58-
func NewAzureCredentialsProvider(ctx context.Context, kubeClient client.Client, identityRef *corev1.ObjectReference, defaultNamespace string) (*AzureCredentialsProvider, error) {
61+
func NewAzureCredentialsProvider(ctx context.Context, cache azure.CredentialCache, kubeClient client.Client, identityRef *corev1.ObjectReference, defaultNamespace string) (*AzureCredentialsProvider, error) {
5962
if identityRef == nil {
6063
return nil, errors.New("failed to generate new AzureClusterCredentialsProvider from empty identityName")
6164
}
@@ -74,6 +77,7 @@ func NewAzureCredentialsProvider(ctx context.Context, kubeClient client.Client,
7477
return &AzureCredentialsProvider{
7578
Client: kubeClient,
7679
Identity: identity,
80+
cache: cache,
7781
}, nil
7882
}
7983

@@ -93,15 +97,14 @@ func (p *AzureCredentialsProvider) GetTokenCredential(ctx context.Context, resou
9397

9498
switch p.Identity.Spec.Type {
9599
case infrav1.WorkloadIdentity:
96-
azwiCredOptions, err := NewWorkloadIdentityCredentialOptions().
97-
WithTenantID(p.Identity.Spec.TenantID).
98-
WithClientID(p.Identity.Spec.ClientID).
99-
WithDefaults()
100-
if err != nil {
101-
return nil, errors.Wrapf(err, "failed to setup azwi options for identity %s", p.Identity.Name)
102-
}
103-
azwiCredOptions.ClientOptions.TracingProvider = tracingProvider
104-
cred, authErr = NewWorkloadIdentityCredential(azwiCredOptions)
100+
cred, authErr = p.cache.GetOrStoreWorkloadIdentity(&azidentity.WorkloadIdentityCredentialOptions{
101+
ClientOptions: azcore.ClientOptions{
102+
TracingProvider: tracingProvider,
103+
},
104+
TenantID: p.Identity.Spec.TenantID,
105+
ClientID: p.Identity.Spec.ClientID,
106+
TokenFilePath: GetProjectedTokenPath(),
107+
})
105108

106109
case infrav1.ManualServicePrincipal:
107110
log.Info("Identity type ManualServicePrincipal is deprecated and will be removed in a future release. See https://capz.sigs.k8s.io/topics/identities to find a supported identity type.")
@@ -125,7 +128,7 @@ func (p *AzureCredentialsProvider) GetTokenCredential(ctx context.Context, resou
125128
},
126129
},
127130
}
128-
cred, authErr = azidentity.NewClientSecretCredential(p.GetTenantID(), p.Identity.Spec.ClientID, clientSecret, &options)
131+
cred, authErr = p.cache.GetOrStoreClientSecret(p.GetTenantID(), p.Identity.Spec.ClientID, clientSecret, &options)
129132

130133
case infrav1.ServicePrincipalCertificate:
131134
var certsContent []byte
@@ -141,11 +144,7 @@ func (p *AzureCredentialsProvider) GetTokenCredential(ctx context.Context, resou
141144
}
142145
certsContent = []byte(clientSecret)
143146
}
144-
certs, key, err := azidentity.ParseCertificates(certsContent, nil)
145-
if err != nil {
146-
return nil, errors.Wrap(err, "failed to parse certificate data")
147-
}
148-
cred, authErr = azidentity.NewClientCertificateCredential(p.GetTenantID(), p.Identity.Spec.ClientID, certs, key, &azidentity.ClientCertificateCredentialOptions{
147+
cred, authErr = p.cache.GetOrStoreClientCert(p.GetTenantID(), p.Identity.Spec.ClientID, certsContent, nil, &azidentity.ClientCertificateCredentialOptions{
149148
ClientOptions: azcore.ClientOptions{
150149
TracingProvider: tracingProvider,
151150
},
@@ -158,7 +157,7 @@ func (p *AzureCredentialsProvider) GetTokenCredential(ctx context.Context, resou
158157
},
159158
ID: azidentity.ClientID(p.Identity.Spec.ClientID),
160159
}
161-
cred, authErr = azidentity.NewManagedIdentityCredential(&options)
160+
cred, authErr = p.cache.GetOrStoreManagedIdentity(&options)
162161

163162
default:
164163
return nil, errors.Errorf("identity type %s not supported", p.Identity.Spec.Type)

azure/scope/identity_test.go

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,21 @@ package scope
1818

1919
import (
2020
"context"
21-
"encoding/base64"
21+
"os"
22+
"reflect"
2223
"testing"
2324

25+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
26+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
2427
. "github.com/onsi/gomega"
28+
"go.uber.org/mock/gomock"
2529
corev1 "k8s.io/api/core/v1"
2630
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2731
"k8s.io/apimachinery/pkg/runtime"
2832
"sigs.k8s.io/controller-runtime/pkg/client/fake"
2933

3034
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
35+
"sigs.k8s.io/cluster-api-provider-azure/azure/mock_azure"
3136
)
3237

3338
func TestAllowedNamespaces(t *testing.T) {
@@ -202,20 +207,15 @@ func TestHasClientSecret(t *testing.T) {
202207
}
203208

204209
func TestGetTokenCredential(t *testing.T) {
205-
g := NewWithT(t)
206-
207-
// Test cert data was generated with this command:
208-
// openssl req -x509 -noenc -days 3650 -newkey rsa:2048 --keyout - -subj /CN=localhost | base64
209-
encodedCertData := "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRRGpyZEVyOVAwVGFVRVMKZHNwRTZjeW8yMk5VOHloUnJiWWxWOVZIMnZXdm5Qc1RoWGN4aG5kK2NVcWRORUJzd2h3Z0ZsVVFjZy9lU1Z4dwpyciszbmgrYkZUWldQY1krMUxRWXhmcEtHc3JDWFFmQjgyTERKSVpEWDRnSFlyV2YzWjI3MmpYTjFYZUZBS3RpCndES2dEWFh1UEg3cjVsSDd2QzNSWGVBZmZxTHdRSmhaZitOb0hOdHY5TUg5SWRVa1FmbURGWnRJL0NRekNyYjYKK3ZPUzZFbVVEL1EyRk5IQnpneENndUdxZ055QmNRYnhKOVFuZytaaklGdWhHWVhKbHN5UlV0ZXh5elRSNS92MApWTks4VXNaZ1JCRmhYcXJCdi9Sb0NDRyt4VkpZdG1kMFFzcnZOekRxRzZRbmpVQjIxelZYcXpLRWtXMmdSdGpYCmN3NHZZUWVoQWdNQkFBRUNnZ0VBUzZ4dGpnMG5Bb2trMGpTK1pPcEtsa01aQUZhemEzWnZ5SGlwa0hEejRQTXQKdGw3UmI1b1FaR3ZXVDJyYkVPcnhleTdCQmk3TEhHaEl1OEV4UXAvaFJHUG9CQUVUUDdYbHlDZ2hXUGtQdEV0RQpkVS9tWHhMb04wTnN6SHVmLzJzaTdwbUg4WXFHWjZRQjB0Z3IyMnV0NjBtYksrQUpGc0VFZjRhU3BCVXNwZXBKCjI4MDBzUUhzcVBFNkw2a1lrZloyR1JSWTFWOXZVcllFT0RLWnBXek1oTjNVQTluQUtIOVBCNnh2UDJPZHlNTmgKaEtnbVVVTU5JRnR3cjhwWmxKbjYwY2YwVXJXcmM1Q3ZxUUx1YUdZbHpEZ1VRR1Y0SkVWanFtOUY2bE1mRVBVdwplTjcwTVZlMXBjTGVMcTJyR0NWV1UzZ2FraC9IdkpxbFIvc2E1NDZIZ3dLQmdRRHlmMXZreVg0dzVzYm9pNkRKCmNsNWRNVUx0TU1ScEIxT2FNRlZPSmpJOWdaSjhtQ2RSanFYZFlvNWFTMktJcXhpZTh0R0c5K1NvaHhEQVdsNHQKbFNVdERzRTQ0ZlNtSUxxQzV6SWF3TlJRbm5rdjBYOEx3bVl1MFFkN1lBakpNbExUV3lEUnNqRDlYUnE0bnNSKwptSlZ3cnQ4NWlTcFM1VUZ5cnlFelBiRmowd0tCZ1FEd1d6cmFlTjBFY2NmMWlJWW1Rc1l5K3lNRUFsSE5SNXlpCmdQWHVBaFN5YnYySlJlUmhkVWIzOWhMci9Mdkt3MFplWGlMV1htWVVHcGJ5elB5WEltMHMrUEwzTFdsNjVHVEYKbCtjZlY1d2ZBZERrazZyQWRFUEVFMnB4Tjg1Q2h5YVBZUG9ZcjBvaG1WOTdWUWNZYzVGcVkrajF0TTZSMVJEdAovZldCU2E4aU93S0JnUUNwYTFkdFdXVERqNGdxVWRyc3d1MndtRWtVNDd4bFVJd1ZMbTE2NHU2NHovemk5WDZLCjJXbUNhV2ZoSjhmWWlnanlpOXpkT2ZYVDFFRmMwZ1g0UExvelo1cVJQalFwbUxZVjNLYkIwRFRGZW1KYWlUZ0UKcERXMXdhNURnUTNDVzFsSWR1TlAvZm1DR2ZrZ1FUUXc2ak9GL1hiUmdNWkVFZzJPclZJNXRZRm9wd0tCZ0VSOQppcWpFdGg1VkdlakNqWStMaVpUdmNVdnNLVWs0dGM2c3R1ZXFtaUU2ZFc3UGhzT3F1cDFmOW9aZWoxaTVDbTFMCm45dThMSlJmKzFHV3pnZDNIT3NxeVhsYjdHbkRlVi9BNkhCSzg4YjJLb05uL01rNG1ETGdZWDEvckh2U3JVOUEKRUNSR2x2WTZFVFpBeFhQWFFzR3hWS25uYXRHdGlGUjVBS05senMwUEFvR0FhNStYK0RVcUdoOWFFNUlEM3dydgpqa2p4UTJLTEZKQ05TcThmOUdTdXZwdmdYc3RIaDZ3S29NNnZNd0lTaGpnWHVVUkg4VWI0dWhSc1dueE1pbGRGCjdFRStRYVdVOWpuQ20ySFFZQXJmWHJBV3c2REJ1ZGlTa0JxZ0tjNkhqREh1bjVmWGxZVW84VWVzTk1RT3JnN2IKYnlkUVo1LzRWLzFvU1dQRVRrN2pTcjA9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDVENDQWZHZ0F3SUJBZ0lVRlNudEVuK1R2NkhNMnhKUmVFQ0pwSmNDN2lVd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF3d0piRzlqWVd4b2IzTjBNQjRYRFRJME1ERXdPREU1TlRReE5Gb1hEVE0wTURFdwpOVEU1TlRReE5Gb3dGREVTTUJBR0ExVUVBd3dKYkc5allXeG9iM04wTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCkFBT0NBUThBTUlJQkNnS0NBUUVBNDYzUksvVDlFMmxCRW5iS1JPbk1xTnRqVlBNb1VhMjJKVmZWUjlyMXI1ejcKRTRWM01ZWjNmbkZLblRSQWJNSWNJQlpWRUhJUDNrbGNjSzYvdDU0Zm14VTJWajNHUHRTMEdNWDZTaHJLd2wwSAp3Zk5pd3lTR1ExK0lCMksxbjkyZHU5bzF6ZFYzaFFDcllzQXlvQTExN2p4KzYrWlIrN3d0MFYzZ0gzNmk4RUNZCldYL2phQnpiYi9UQi9TSFZKRUg1Z3hXYlNQd2tNd3EyK3Zyemt1aEpsQS8wTmhUUndjNE1Rb0xocW9EY2dYRUcKOFNmVUo0UG1ZeUJib1JtRnlaYk1rVkxYc2NzMDBlZjc5RlRTdkZMR1lFUVJZVjZxd2IvMGFBZ2h2c1ZTV0xabgpkRUxLN3pjdzZodWtKNDFBZHRjMVY2c3loSkZ0b0ViWTEzTU9MMkVIb1FJREFRQUJvMU13VVRBZEJnTlZIUTRFCkZnUVVmcnkvS0R0YW13TWxSUXNGUGJCaHpkdjJVNWN3SHdZRFZSMGpCQmd3Rm9BVWZyeS9LRHRhbXdNbFJRc0YKUGJCaHpkdjJVNWN3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBeVlzdApWdmV3S1JScHVZUldjNFhHNlduWXBoVWR5WkxNb0lscTBzeVoxYWo2WWJxb0s5Tk1IQVlFbkN2U292NnpJWk9hCnRyaHVVY2Y5R0Z6NWUwaUoyeklsRGMzMTJJd3N2NDF4aUMvYnMxNmtFbjhZZi9TdWpFWGFzajd2bUEzSHJGV2YKd1pUSC95Rkw1YXpvL2YrbEExUTI4WXdxRnBIbWxlMHkwTzUzVXRoNHAwdG13bG51K0NyTzlmSHAza1RsYjdmRAo2bXFmazlOcnQ4dE9DNGFIWURvcXRZVWdaaHg1OHhzSE1PVGV0S2VSbHA4SE1GOW9ST3RyaXo0blltNkloVHdvCjVrMUExM1MzQmpheGtaQ3lQWENnWHNzdVhhZ05MYXNycjVRcStWZ2RiL25EaFZlaFY4K1o0SjBZbnp5OU1ac0UKSDFOMU5mTXRzQStQRXF0UFhBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
210-
certPEM, err := base64.StdEncoding.DecodeString(encodedCertData)
211-
g.Expect(err).NotTo(HaveOccurred())
210+
testCertPath := "../../test/setup/certificate"
212211

213212
tests := []struct {
214213
name string
215214
cluster *infrav1.AzureCluster
216215
secret *corev1.Secret
217216
identity *infrav1.AzureClusterIdentity
218217
ActiveDirectoryAuthorityHost string
218+
cacheExpect func(*mock_azure.MockCredentialCache)
219219
}{
220220
{
221221
name: "workload identity",
@@ -235,6 +235,14 @@ func TestGetTokenCredential(t *testing.T) {
235235
TenantID: fakeTenantID,
236236
},
237237
},
238+
cacheExpect: func(cache *mock_azure.MockCredentialCache) {
239+
cache.EXPECT().GetOrStoreWorkloadIdentity(gomock.Cond(func(opts *azidentity.WorkloadIdentityCredentialOptions) bool {
240+
// ignore tracing provider
241+
return opts.TenantID == fakeTenantID &&
242+
opts.ClientID == fakeClientID &&
243+
opts.TokenFilePath == GetProjectedTokenPath()
244+
}))
245+
},
238246
},
239247
{
240248
name: "manual service principal",
@@ -251,6 +259,7 @@ func TestGetTokenCredential(t *testing.T) {
251259
Spec: infrav1.AzureClusterIdentitySpec{
252260
Type: infrav1.ManualServicePrincipal,
253261
TenantID: fakeTenantID,
262+
ClientID: fakeClientID,
254263
ClientSecret: corev1.SecretReference{
255264
Name: "test-identity-secret",
256265
},
@@ -265,6 +274,20 @@ func TestGetTokenCredential(t *testing.T) {
265274
},
266275
},
267276
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com",
277+
cacheExpect: func(cache *mock_azure.MockCredentialCache) {
278+
cache.EXPECT().GetOrStoreClientSecret(fakeTenantID, fakeClientID, "fooSecret", gomock.Cond(func(opts *azidentity.ClientSecretCredentialOptions) bool {
279+
// ignore tracing provider
280+
return reflect.DeepEqual(opts.ClientOptions.Cloud, cloud.Configuration{
281+
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com",
282+
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
283+
cloud.ResourceManager: {
284+
Audience: "",
285+
Endpoint: "",
286+
},
287+
},
288+
})
289+
}))
290+
},
268291
},
269292
{
270293
name: "service principal",
@@ -281,6 +304,7 @@ func TestGetTokenCredential(t *testing.T) {
281304
Spec: infrav1.AzureClusterIdentitySpec{
282305
Type: infrav1.ServicePrincipal,
283306
TenantID: fakeTenantID,
307+
ClientID: fakeClientID,
284308
ClientSecret: corev1.SecretReference{
285309
Name: "test-identity-secret",
286310
},
@@ -295,6 +319,20 @@ func TestGetTokenCredential(t *testing.T) {
295319
},
296320
},
297321
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com",
322+
cacheExpect: func(cache *mock_azure.MockCredentialCache) {
323+
cache.EXPECT().GetOrStoreClientSecret(fakeTenantID, fakeClientID, "fooSecret", gomock.Cond(func(opts *azidentity.ClientSecretCredentialOptions) bool {
324+
// ignore tracing provider
325+
return reflect.DeepEqual(opts.ClientOptions.Cloud, cloud.Configuration{
326+
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com",
327+
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
328+
cloud.ResourceManager: {
329+
Audience: "",
330+
Endpoint: "",
331+
},
332+
},
333+
})
334+
}))
335+
},
298336
},
299337
{
300338
name: "service principal certificate",
@@ -311,17 +349,23 @@ func TestGetTokenCredential(t *testing.T) {
311349
Spec: infrav1.AzureClusterIdentitySpec{
312350
Type: infrav1.ServicePrincipalCertificate,
313351
TenantID: fakeTenantID,
314-
CertPath: "../../test/setup/certificate",
352+
ClientID: fakeClientID,
353+
ClientSecret: corev1.SecretReference{
354+
Name: "test-identity-secret",
355+
},
315356
},
316357
},
317358
secret: &corev1.Secret{
318359
ObjectMeta: metav1.ObjectMeta{
319360
Name: "test-identity-secret",
320361
},
321362
Data: map[string][]byte{
322-
"clientSecret": certPEM,
363+
"clientSecret": []byte("fooSecret"),
323364
},
324365
},
366+
cacheExpect: func(cache *mock_azure.MockCredentialCache) {
367+
cache.EXPECT().GetOrStoreClientCert(fakeTenantID, fakeClientID, []byte("fooSecret"), gomock.Nil(), gomock.Any())
368+
},
325369
},
326370
{
327371
name: "service principal certificate with certificate filepath",
@@ -338,9 +382,17 @@ func TestGetTokenCredential(t *testing.T) {
338382
Spec: infrav1.AzureClusterIdentitySpec{
339383
Type: infrav1.ServicePrincipalCertificate,
340384
TenantID: fakeTenantID,
341-
CertPath: "../../test/setup/certificate",
385+
ClientID: fakeClientID,
386+
CertPath: testCertPath,
342387
},
343388
},
389+
cacheExpect: func(cache *mock_azure.MockCredentialCache) {
390+
expectedCert, err := os.ReadFile(testCertPath)
391+
if err != nil {
392+
panic(err)
393+
}
394+
cache.EXPECT().GetOrStoreClientCert(fakeTenantID, fakeClientID, expectedCert, gomock.Nil(), gomock.Any())
395+
},
344396
},
345397
{
346398
name: "user-assigned identity",
@@ -357,8 +409,15 @@ func TestGetTokenCredential(t *testing.T) {
357409
Spec: infrav1.AzureClusterIdentitySpec{
358410
Type: infrav1.UserAssignedMSI,
359411
TenantID: fakeTenantID,
412+
ClientID: fakeClientID,
360413
},
361414
},
415+
cacheExpect: func(cache *mock_azure.MockCredentialCache) {
416+
cache.EXPECT().GetOrStoreManagedIdentity(gomock.Cond(func(opts *azidentity.ManagedIdentityCredentialOptions) bool {
417+
// ignore tracing provider
418+
return opts.ID == azidentity.ClientID(fakeClientID)
419+
}))
420+
},
362421
},
363422
}
364423

@@ -377,11 +436,15 @@ func TestGetTokenCredential(t *testing.T) {
377436
initObjects = append(initObjects, tt.secret)
378437
}
379438
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjects...).Build()
380-
provider, err := NewAzureCredentialsProvider(context.Background(), fakeClient, tt.cluster.Spec.IdentityRef, "")
439+
440+
mockCtrl := gomock.NewController(t)
441+
cache := mock_azure.NewMockCredentialCache(mockCtrl)
442+
tt.cacheExpect(cache)
443+
444+
provider, err := NewAzureCredentialsProvider(context.Background(), cache, fakeClient, tt.cluster.Spec.IdentityRef, "")
381445
g.Expect(err).NotTo(HaveOccurred())
382-
cred, err := provider.GetTokenCredential(context.Background(), "", tt.ActiveDirectoryAuthorityHost, "")
446+
_, err = provider.GetTokenCredential(context.Background(), "", tt.ActiveDirectoryAuthorityHost, "")
383447
g.Expect(err).NotTo(HaveOccurred())
384-
g.Expect(cred).NotTo(BeNil())
385448
})
386449
}
387450
}

azure/scope/managedcontrolplane.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type ManagedControlPlaneScopeParams struct {
7575
ManagedMachinePools []ManagedMachinePool
7676
Cache *ManagedControlPlaneCache
7777
Timeouts azure.AsyncReconciler
78+
CredentialCache azure.CredentialCache
7879
}
7980

8081
// NewManagedControlPlaneScope creates a new Scope from the supplied parameters.
@@ -91,7 +92,7 @@ func NewManagedControlPlaneScope(ctx context.Context, params ManagedControlPlane
9192
return nil, errors.New("failed to generate new scope from nil ControlPlane")
9293
}
9394

94-
credentialsProvider, err := NewAzureCredentialsProvider(ctx, params.Client, params.ControlPlane.Spec.IdentityRef, params.ControlPlane.Namespace)
95+
credentialsProvider, err := NewAzureCredentialsProvider(ctx, params.CredentialCache, params.Client, params.ControlPlane.Spec.IdentityRef, params.ControlPlane.Namespace)
9596
if err != nil {
9697
return nil, errors.Wrap(err, "failed to init credentials provider")
9798
}

azure/scope/managedcontrolplane_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func TestNewManagedControlPlaneScope(t *testing.T) {
7070
},
7171
},
7272
},
73+
CredentialCache: azure.NewCredentialCache(),
7374
}
7475
fakeIdentity := &infrav1.AzureClusterIdentity{
7576
ObjectMeta: metav1.ObjectMeta{

0 commit comments

Comments
 (0)