Skip to content

Commit c1b34bb

Browse files
authored
Merge pull request #5000 from nojnhuh/capi-self-hosted
use managed identity for CAPI self-hosted e2e test
2 parents 0dee597 + dc5b1dc commit c1b34bb

File tree

5 files changed

+84
-1
lines changed

5 files changed

+84
-1
lines changed

azure/scope/clients.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
2828
azureautorest "github.com/Azure/go-autorest/autorest/azure"
2929
"github.com/Azure/go-autorest/autorest/azure/auth"
30+
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
3031
)
3132

3233
// AzureClients contains all the Azure clients used by the scopes.
@@ -36,6 +37,8 @@ type AzureClients struct {
3637
TokenCredential azcore.TokenCredential
3738
ResourceManagerEndpoint string
3839
ResourceManagerVMDNSSuffix string
40+
41+
authType infrav1.IdentityType
3942
}
4043

4144
// CloudEnvironment returns the Azure environment the controller runs in.
@@ -73,7 +76,7 @@ func (c *AzureClients) Token() azcore.TokenCredential {
7376
// ClientID).
7477
func (c *AzureClients) HashKey() string {
7578
hasher := sha256.New()
76-
_, _ = hasher.Write([]byte(c.TenantID() + c.CloudEnvironment() + c.SubscriptionID() + c.ClientID()))
79+
_, _ = hasher.Write([]byte(c.TenantID() + c.CloudEnvironment() + c.SubscriptionID() + c.ClientID() + string(c.authType)))
7780
return base64.URLEncoding.EncodeToString(hasher.Sum(nil))
7881
}
7982

@@ -107,6 +110,8 @@ func (c *AzureClients) setCredentialsWithProvider(ctx context.Context, subscript
107110
}
108111
c.Values["AZURE_CLIENT_SECRET"] = strings.TrimSuffix(clientSecret, "\n")
109112

113+
c.authType = credentialsProvider.Type()
114+
110115
tokenCredential, err := credentialsProvider.GetTokenCredential(ctx, c.ResourceManagerEndpoint, c.Environment.ActiveDirectoryEndpoint, c.Environment.TokenAudience)
111116
if err != nil {
112117
return err

azure/scope/identity.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type CredentialsProvider interface {
4141
GetClientSecret(ctx context.Context) (string, error)
4242
GetTenantID() string
4343
GetTokenCredential(ctx context.Context, resourceManagerEndpoint, activeDirectoryEndpoint, tokenAudience string) (azcore.TokenCredential, error)
44+
Type() infrav1.IdentityType
4445
}
4546

4647
// AzureCredentialsProvider represents a credential provider with azure cluster identity.
@@ -228,6 +229,11 @@ func (p *AzureCredentialsProvider) GetTenantID() string {
228229
return p.Identity.Spec.TenantID
229230
}
230231

232+
// Type returns the auth mechanism used.
233+
func (p *AzureCredentialsProvider) Type() infrav1.IdentityType {
234+
return p.Identity.Spec.Type
235+
}
236+
231237
// hasClientSecret returns true if the identity has a Service Principal Client Secret.
232238
// This does not include managed identities.
233239
func (p *AzureCredentialsProvider) hasClientSecret() bool {

test/e2e/azure_selfhosted.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ import (
2525
"os"
2626
"path/filepath"
2727

28+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
29+
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi"
2830
. "github.com/onsi/ginkgo/v2"
2931
. "github.com/onsi/gomega"
3032
corev1 "k8s.io/api/core/v1"
33+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34+
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
3135
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
36+
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
3237
capi_e2e "sigs.k8s.io/cluster-api/test/e2e"
3338
"sigs.k8s.io/cluster-api/test/framework"
3439
"sigs.k8s.io/cluster-api/test/framework/clusterctl"
@@ -141,6 +146,40 @@ func SelfHostedSpec(ctx context.Context, inputGetter func() SelfHostedSpecInput)
141146
Namespace: namespace.Name,
142147
})
143148

149+
// The workload cluster is not set up for workload identity. Use UserAssignedMSI there instead.
150+
err := selfHostedClusterProxy.GetClient().Delete(ctx, &infrav1.AzureClusterIdentity{
151+
ObjectMeta: metav1.ObjectMeta{
152+
Namespace: cluster.Namespace,
153+
Name: e2eConfig.GetVariable(ClusterIdentityName),
154+
},
155+
})
156+
Expect(err).NotTo(HaveOccurred())
157+
cred, err := azidentity.NewDefaultAzureCredential(nil)
158+
Expect(err).NotTo(HaveOccurred())
159+
identityClient, err := armmsi.NewUserAssignedIdentitiesClient(getSubscriptionID(Default), cred, nil)
160+
Expect(err).NotTo(HaveOccurred())
161+
identityRG := e2eConfig.GetVariable(AzureIdentityResourceGroup)
162+
identityName := e2eConfig.GetVariable(AzureUserIdentity)
163+
identity, err := identityClient.Get(ctx, identityRG, identityName, nil)
164+
Expect(err).NotTo(HaveOccurred())
165+
err = selfHostedClusterProxy.GetClient().Create(ctx, &infrav1.AzureClusterIdentity{
166+
ObjectMeta: metav1.ObjectMeta{
167+
Namespace: cluster.Namespace,
168+
Name: e2eConfig.GetVariable(ClusterIdentityName),
169+
Labels: map[string]string{
170+
clusterctlv1.ClusterctlMoveHierarchyLabel: "true",
171+
},
172+
},
173+
Spec: infrav1.AzureClusterIdentitySpec{
174+
AllowedNamespaces: &infrav1.AllowedNamespaces{},
175+
ClientID: *identity.Properties.ClientID,
176+
ResourceID: *identity.ID,
177+
TenantID: e2eConfig.GetVariable(AzureTenantID),
178+
Type: infrav1.UserAssignedMSI,
179+
},
180+
})
181+
Expect(err).NotTo(HaveOccurred())
182+
144183
Log("Waiting for the cluster to be reconciled after moving to self hosted")
145184
selfHostedCluster = framework.DiscoveryAndWaitForCluster(ctx, framework.DiscoveryAndWaitForClusterInput{
146185
Getter: selfHostedClusterProxy.GetClient(),
@@ -193,6 +232,31 @@ func SelfHostedSpec(ctx context.Context, inputGetter func() SelfHostedSpecInput)
193232
Namespace: selfHostedNamespace.Name,
194233
})
195234

235+
// Restore the workload identity AzureClusterIdentity
236+
err := input.BootstrapClusterProxy.GetClient().Delete(ctx, &infrav1.AzureClusterIdentity{
237+
ObjectMeta: metav1.ObjectMeta{
238+
Namespace: namespace.Name,
239+
Name: e2eConfig.GetVariable(ClusterIdentityName),
240+
},
241+
})
242+
Expect(err).NotTo(HaveOccurred())
243+
err = input.BootstrapClusterProxy.GetClient().Create(ctx, &infrav1.AzureClusterIdentity{
244+
ObjectMeta: metav1.ObjectMeta{
245+
Namespace: namespace.Name,
246+
Name: e2eConfig.GetVariable(ClusterIdentityName),
247+
Labels: map[string]string{
248+
clusterctlv1.ClusterctlMoveHierarchyLabel: "true",
249+
},
250+
},
251+
Spec: infrav1.AzureClusterIdentitySpec{
252+
AllowedNamespaces: &infrav1.AllowedNamespaces{},
253+
ClientID: e2eConfig.GetVariable(AzureClientIDUserAssignedIdentity),
254+
TenantID: e2eConfig.GetVariable(AzureTenantID),
255+
Type: infrav1.WorkloadIdentity,
256+
},
257+
})
258+
Expect(err).NotTo(HaveOccurred())
259+
196260
Log("Waiting for the cluster to be reconciled after moving back to booststrap")
197261
clusterResources.Cluster = framework.DiscoveryAndWaitForCluster(ctx, framework.DiscoveryAndWaitForClusterInput{
198262
Getter: input.BootstrapClusterProxy.GetClient(),

test/e2e/data/infrastructure-azure/v1beta1/cluster-template.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,13 @@ spec:
284284
- diskSizeGB: 256
285285
lun: 0
286286
nameSuffix: etcddisk
287+
identity: UserAssigned
287288
osDisk:
288289
diskSizeGB: 128
289290
osType: Linux
290291
sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""}
292+
userAssignedIdentities:
293+
- providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${CI_RG:=capz-ci}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_IDENTITY:=cloud-provider-user-identity}
291294
vmSize: ${AZURE_CONTROL_PLANE_MACHINE_TYPE}
292295
---
293296
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
@@ -298,10 +301,13 @@ metadata:
298301
spec:
299302
template:
300303
spec:
304+
identity: UserAssigned
301305
osDisk:
302306
diskSizeGB: 128
303307
managedDisk:
304308
storageAccountType: Premium_LRS
305309
osType: Linux
306310
sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""}
311+
userAssignedIdentities:
312+
- providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${CI_RG:=capz-ci}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_IDENTITY:=cloud-provider-user-identity}
307313
vmSize: ${AZURE_NODE_MACHINE_TYPE}

test/e2e/data/infrastructure-azure/v1beta1/cluster-template/kustomization.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ patches:
1212
- path: ../../../../../../templates/azure-cluster-identity/azurecluster-identity-ref.yaml
1313
- path: ../../../../../../templates/test/ci/patches/cluster-label-calico.yaml
1414
- path: ../../../../../../templates/test/ci/patches/cluster-label-cloud-provider-azure.yaml
15+
- path: ../../../../../../templates/test/ci/patches/uami-control-plane.yaml
16+
- path: ../../../../../../templates/test/ci/patches/uami-md-0.yaml

0 commit comments

Comments
 (0)