@@ -18,8 +18,12 @@ package controllers
1818
1919import (
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