Skip to content

Commit 8c678eb

Browse files
committed
reconcile azure identity for managed control plane
1 parent 1b2ace7 commit 8c678eb

File tree

1 file changed

+67
-14
lines changed

1 file changed

+67
-14
lines changed

controllers/azureidentity_controller.go

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ package controllers
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"time"
2223

24+
infraexpv1 "sigs.k8s.io/cluster-api-provider-azure/exp/api/v1alpha4"
25+
"sigs.k8s.io/cluster-api-provider-azure/feature"
26+
2327
aadpodv1 "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
2428
"github.com/go-logr/logr"
2529
"github.com/pkg/errors"
@@ -65,6 +69,17 @@ func (r *AzureIdentityReconciler) SetupWithManager(ctx context.Context, mgr ctrl
6569
return errors.Wrap(err, "error creating controller")
6670
}
6771

72+
// Add a watch on infraexpv1.AzureManagedControlPlane if aks is enabled.
73+
if feature.Gates.Enabled(feature.AKS) {
74+
if err = c.Watch(
75+
&source.Kind{Type: &infraexpv1.AzureManagedControlPlane{}},
76+
&handler.EnqueueRequestForObject{},
77+
predicates.ResourceNotPausedAndHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue),
78+
); err != nil {
79+
return errors.Wrap(err, "failed adding a watch for ready clusters")
80+
}
81+
}
82+
6883
// Add a watch on clusterv1.Cluster object for unpause notifications.
6984
if err = c.Watch(
7085
&source.Kind{Type: &clusterv1.Cluster{}},
@@ -96,20 +111,38 @@ func (r *AzureIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Reques
96111
))
97112
defer span.End()
98113

114+
// identityOwner is the resource that created the identity. This could be either an AzureCluster or AzureManagedControlPlane (if AKS is enabled).
115+
// check for AzureManagedControlPlane first and if it is not found, check for AzureManagedControlPlane.
116+
var identityOwner interface{}
117+
99118
// Fetch the AzureCluster instance
100119
azureCluster := &infrav1.AzureCluster{}
120+
identityOwner = azureCluster
101121
err := r.Get(ctx, req.NamespacedName, azureCluster)
102-
if err != nil {
103-
if apierrors.IsNotFound(err) {
122+
if err != nil && apierrors.IsNotFound(err) {
123+
if feature.Gates.Enabled(feature.AKS) {
124+
// Fetch the AzureManagedControlPlane instance
125+
azureManagedControlPlane := &infraexpv1.AzureManagedControlPlane{}
126+
identityOwner = azureManagedControlPlane
127+
err = r.Get(ctx, req.NamespacedName, azureManagedControlPlane)
128+
if err != nil && apierrors.IsNotFound(err) {
129+
r.Recorder.Eventf(azureCluster, corev1.EventTypeNormal, "AzureClusterObjectNotFound",
130+
fmt.Sprintf("AzureCluster object %s/%s not found", req.Namespace, req.Name))
131+
r.Recorder.Eventf(azureManagedControlPlane, corev1.EventTypeNormal, "AzureManagedControlPlaneObjectNotFound",
132+
fmt.Sprintf("AzureManagedControlPlane object %s/%s not found", req.Namespace, req.Name))
133+
log.Info("object was not found")
134+
return reconcile.Result{}, nil
135+
}
136+
} else {
104137
r.Recorder.Eventf(azureCluster, corev1.EventTypeNormal, "AzureClusterObjectNotFound", err.Error())
105138
log.Info("object was not found")
106139
return reconcile.Result{}, nil
107140
}
141+
}
142+
if err != nil {
108143
return reconcile.Result{}, err
109144
}
110145

111-
log = log.WithValues("azurecluster", azureCluster.Name)
112-
113146
// get all the bindings
114147
var bindings aadpodv1.AzureIdentityBindingList
115148
if err := r.List(ctx, &bindings, client.InNamespace(system.GetManagerNamespace())); err != nil {
@@ -125,16 +158,36 @@ func (r *AzureIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Reques
125158
clusterNamespace := binding.ObjectMeta.Labels[infrav1.ClusterLabelNamespace]
126159

127160
key := client.ObjectKey{Name: clusterName, Namespace: clusterNamespace}
128-
azCluster := &infrav1.AzureCluster{}
129-
if err := r.Get(ctx, key, azCluster); err != nil {
130-
if apierrors.IsNotFound(err) {
131-
bindingsToDelete = append(bindingsToDelete, b)
132-
continue
133-
} else {
134-
return ctrl.Result{}, errors.Wrap(err, "failed to get AzureCluster")
161+
var expectedIdentityName string
162+
163+
// only delete bindings when the identity owner type is not found.
164+
// we should not delete an identity when azureCluster is not found because it could have been created by AzureManagedControlPlane.
165+
switch identityOwner.(type) {
166+
case infrav1.AzureCluster:
167+
azCluster := &infrav1.AzureCluster{}
168+
if err := r.Get(ctx, key, azCluster); err != nil {
169+
if apierrors.IsNotFound(err) {
170+
bindingsToDelete = append(bindingsToDelete, b)
171+
continue
172+
} else {
173+
return ctrl.Result{}, errors.Wrap(err, "failed to get AzureCluster")
174+
}
175+
}
176+
expectedIdentityName = identity.GetAzureIdentityName(azCluster.Name, azCluster.Namespace, azCluster.Spec.IdentityRef.Name)
177+
case infraexpv1.AzureManagedControlPlane:
178+
azManagedControlPlane := &infraexpv1.AzureManagedControlPlane{}
179+
if err := r.Get(ctx, key, azManagedControlPlane); err != nil {
180+
if apierrors.IsNotFound(err) {
181+
bindingsToDelete = append(bindingsToDelete, b)
182+
continue
183+
} else {
184+
return ctrl.Result{}, errors.Wrap(err, "failed to get AzureManagedControlPlane")
185+
}
135186
}
187+
expectedIdentityName = identity.GetAzureIdentityName(azManagedControlPlane.Name, azManagedControlPlane.Namespace,
188+
azManagedControlPlane.Spec.IdentityRef.Name)
136189
}
137-
expectedIdentityName := identity.GetAzureIdentityName(azCluster.Name, azCluster.Namespace, azCluster.Spec.IdentityRef.Name)
190+
138191
if binding.Spec.AzureIdentity != expectedIdentityName {
139192
bindingsToDelete = append(bindingsToDelete, b)
140193
}
@@ -145,7 +198,7 @@ func (r *AzureIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Reques
145198
binding := bindingToDelete
146199
identityName := binding.Spec.AzureIdentity
147200
if err := r.Client.Delete(ctx, &binding); err != nil {
148-
r.Recorder.Eventf(azureCluster, corev1.EventTypeWarning, "Error reconciling AzureIdentity for AzureCluster", err.Error())
201+
r.Recorder.Eventf(azureCluster, corev1.EventTypeWarning, "Error reconciling AzureIdentity", err.Error())
149202
log.Error(err, "failed to delete AzureIdentityBinding")
150203
return ctrl.Result{}, err
151204
}
@@ -155,7 +208,7 @@ func (r *AzureIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Reques
155208
return ctrl.Result{}, err
156209
}
157210
if err := r.Client.Delete(ctx, azureIdentity); err != nil {
158-
r.Recorder.Eventf(azureCluster, corev1.EventTypeWarning, "Error reconciling AzureIdentity for AzureCluster", err.Error())
211+
r.Recorder.Eventf(azureCluster, corev1.EventTypeWarning, "Error reconciling AzureIdentity", err.Error())
159212
log.Error(err, "failed to delete AzureIdentity")
160213
return ctrl.Result{}, err
161214
}

0 commit comments

Comments
 (0)