Skip to content

Commit

Permalink
Merge pull request #3851 from adriananeci/azwi-aso
Browse files Browse the repository at this point in the history
Allow authentication with Azure Workload Identity for ASO
  • Loading branch information
k8s-ci-robot authored Aug 17, 2023
2 parents 594467c + b017ee3 commit ccb8614
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 9 deletions.
7 changes: 6 additions & 1 deletion controllers/asosecret_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,19 @@ func (asos *ASOSecretReconciler) createSecretFromClusterIdentity(ctx context.Con
newASOSecret.Data["AZURE_TENANT_ID"] = []byte(identity.Spec.TenantID)
newASOSecret.Data["AZURE_CLIENT_ID"] = []byte(identity.Spec.ClientID)

// If the identity type is WorkloadIdentity or UserAssignedMSI, then we don't need to fetch the secret so return early
if identity.Spec.Type == infrav1.WorkloadIdentity || identity.Spec.Type == infrav1.UserAssignedMSI {
return newASOSecret, nil
}

// Fetch identity secret, if it exists
key = types.NamespacedName{
Namespace: identity.Spec.ClientSecret.Namespace,
Name: identity.Spec.ClientSecret.Name,
}
identitySecret := &corev1.Secret{}
err := asos.Get(ctx, key, identitySecret)
if err != nil && !apierrors.IsNotFound(err) {
if err != nil {
return nil, errors.Wrap(err, "failed to fetch AzureClusterIdentity secret")
}

Expand Down
88 changes: 80 additions & 8 deletions controllers/asosecret_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func TestASOSecretReconcile(t *testing.T) {
defaultAzureCluster := getASOAzureCluster()
defaultAzureManagedControlPlane := getASOAzureManagedControlPlane()
defaultASOSecret := getASOSecret(defaultAzureCluster)
defaultClusterIdentityType := infrav1.ServicePrincipal

cases := map[string]struct {
clusterName string
Expand All @@ -80,7 +81,13 @@ func TestASOSecretReconcile(t *testing.T) {
Namespace: "default",
}
}),
getASOAzureClusterIdentity(),
getASOAzureClusterIdentity(func(identity *infrav1.AzureClusterIdentity) {
identity.Spec.Type = defaultClusterIdentityType
identity.Spec.ClientSecret = corev1.SecretReference{
Name: "fooSecret",
Namespace: "default",
}
}),
getASOAzureClusterIdentitySecret(),
defaultCluster,
},
Expand All @@ -102,7 +109,13 @@ func TestASOSecretReconcile(t *testing.T) {
Namespace: "default",
}
}),
getASOAzureClusterIdentity(),
getASOAzureClusterIdentity(func(identity *infrav1.AzureClusterIdentity) {
identity.Spec.Type = defaultClusterIdentityType
identity.Spec.ClientSecret = corev1.SecretReference{
Name: "fooSecret",
Namespace: "default",
}
}),
getASOAzureClusterIdentitySecret(),
defaultCluster,
},
Expand All @@ -115,6 +128,70 @@ func TestASOSecretReconcile(t *testing.T) {
}
}),
},
"should reconcile normally for AzureCluster with an IdentityRef of type WorkloadIdentity": {
clusterName: defaultAzureCluster.Name,
objects: []runtime.Object{
getASOAzureCluster(func(c *infrav1.AzureCluster) {
c.Spec.IdentityRef = &corev1.ObjectReference{
Name: "my-azure-cluster-identity",
Namespace: "default",
}
}),
getASOAzureClusterIdentity(func(identity *infrav1.AzureClusterIdentity) {
identity.Spec.Type = "WorkloadIdentity"
}),
defaultCluster,
},
asoSecret: getASOSecret(defaultAzureCluster, func(s *corev1.Secret) {
s.Data = map[string][]byte{
"AZURE_SUBSCRIPTION_ID": []byte("123"),
"AZURE_TENANT_ID": []byte("fooTenant"),
"AZURE_CLIENT_ID": []byte("fooClient"),
}
}),
},
"should reconcile normally for AzureManagedControlPlane with an IdentityRef of type WorkloadIdentity": {
clusterName: defaultAzureManagedControlPlane.Name,
objects: []runtime.Object{
getASOAzureManagedControlPlane(func(c *infrav1.AzureManagedControlPlane) {
c.Spec.IdentityRef = &corev1.ObjectReference{
Name: "my-azure-cluster-identity",
Namespace: "default",
}
}),
getASOAzureClusterIdentity(func(identity *infrav1.AzureClusterIdentity) {
identity.Spec.Type = infrav1.WorkloadIdentity
}),
defaultCluster,
},
asoSecret: getASOSecret(defaultAzureManagedControlPlane, func(s *corev1.Secret) {
s.Data = map[string][]byte{
"AZURE_SUBSCRIPTION_ID": []byte("fooSubscription"),
"AZURE_TENANT_ID": []byte("fooTenant"),
"AZURE_CLIENT_ID": []byte("fooClient"),
}
}),
},
"should fail if IdentityRef secret doesn't exist": {
clusterName: defaultAzureManagedControlPlane.Name,
objects: []runtime.Object{
getASOAzureManagedControlPlane(func(c *infrav1.AzureManagedControlPlane) {
c.Spec.IdentityRef = &corev1.ObjectReference{
Name: "my-azure-cluster-identity",
Namespace: "default",
}
}),
getASOAzureClusterIdentity(func(identity *infrav1.AzureClusterIdentity) {
identity.Spec.Type = defaultClusterIdentityType
identity.Spec.ClientSecret = corev1.SecretReference{
Name: "fooSecret",
Namespace: "default",
}
}),
defaultCluster,
},
err: "secrets \"fooSecret\" not found",
},
"should return if cluster does not exist": {
clusterName: defaultAzureCluster.Name,
objects: []runtime.Object{
Expand Down Expand Up @@ -175,7 +252,7 @@ func TestASOSecretReconcile(t *testing.T) {
g.Expect(reconciler.Recorder.(*record.FakeRecorder).Events).To(Receive(ContainSubstring(tc.event)))
}
if tc.err != "" {
g.Expect(err).To(MatchError(tc.err))
g.Expect(err).To(MatchError(ContainSubstring(tc.err)))
} else {
g.Expect(err).NotTo(HaveOccurred())
}
Expand Down Expand Up @@ -265,12 +342,7 @@ func getASOAzureClusterIdentity(changes ...func(identity *infrav1.AzureClusterId
Namespace: "default",
},
Spec: infrav1.AzureClusterIdentitySpec{
Type: infrav1.IdentityType("ServicePrincipal"),
ClientID: "fooClient",
ClientSecret: corev1.SecretReference{
Name: "fooSecret",
Namespace: "default",
},
TenantID: "fooTenant",
},
}
Expand Down

0 comments on commit ccb8614

Please sign in to comment.