@@ -30,12 +30,8 @@ import (
3030 "k8s.io/apimachinery/pkg/types"
3131 "k8s.io/client-go/util/retry"
3232 ctrl "sigs.k8s.io/controller-runtime"
33- "sigs.k8s.io/controller-runtime/pkg/builder"
3433 "sigs.k8s.io/controller-runtime/pkg/client"
35- "sigs.k8s.io/controller-runtime/pkg/event"
36- "sigs.k8s.io/controller-runtime/pkg/handler"
3734 "sigs.k8s.io/controller-runtime/pkg/log"
38- "sigs.k8s.io/controller-runtime/pkg/predicate"
3935 "sigs.k8s.io/controller-runtime/pkg/reconcile"
4036
4137 corev1 "k8s.io/api/core/v1"
@@ -54,43 +50,94 @@ const VALIDATION_MW_RETRY_INTERVAL = 10 * time.Second
5450type ClusterPermissionReconciler struct {
5551 client.Client
5652 Scheme * runtime.Scheme
53+ // customInformer is the custom informer for ManagedClusterAddOn resources
54+ customInformer * ManagedClusterAddOnInformer
5755}
5856
5957// SetupWithManager sets up the controller with the Manager.
6058func (r * ClusterPermissionReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
59+ // Create custom informer for ManagedClusterAddOn resources
60+ config := mgr .GetConfig ()
61+ eventHandler := r .createCustomInformerEventHandler ()
62+
63+ customInformer , err := NewManagedClusterAddOnInformer (config , eventHandler )
64+ if err != nil {
65+ return err
66+ }
67+
68+ // Store the custom informer in the reconciler
69+ r .customInformer = customInformer
70+
71+ // Start the custom informer in a goroutine
72+ go func () {
73+ if err := customInformer .Start (); err != nil {
74+ log .Log .Error (err , "Failed to start custom ManagedClusterAddOn informer" )
75+ }
76+ }()
77+
78+ // Setup the controller without the built-in ManagedClusterAddOn watching
79+ // since we're using the custom informer instead
6180 return ctrl .NewControllerManagedBy (mgr ).
6281 For (& cpv1alpha1.ClusterPermission {}).
63- Watches (& addonv1alpha1.ManagedClusterAddOn {},
64- r .managedClusterAddOnEventHandler (),
65- builder .WithPredicates (predicate.Funcs {
66- CreateFunc : func (e event.CreateEvent ) bool {
67- return false // Don't process Create events
68- },
69- UpdateFunc : func (e event.UpdateEvent ) bool {
70- // Only process Update events for managed-serviceaccount addon when status.namespace changes
71- oldAddon , oldOk := e .ObjectOld .(* addonv1alpha1.ManagedClusterAddOn )
72- newAddon , newOk := e .ObjectNew .(* addonv1alpha1.ManagedClusterAddOn )
82+ Complete (r )
83+ }
7384
74- if ! oldOk || ! newOk {
75- return false
76- }
85+ // Stop stops the custom informer if it exists
86+ func (r * ClusterPermissionReconciler ) Stop () {
87+ if r .customInformer != nil {
88+ r .customInformer .Stop ()
89+ }
90+ }
7791
78- // Only process if this is the managed-serviceaccount addon
79- if newAddon . Name != msacommon . AddonName {
80- return false
81- }
92+ // createCustomInformerEventHandler creates an event handler for the custom informer
93+ func ( r * ClusterPermissionReconciler ) createCustomInformerEventHandler () func ( obj * addonv1alpha1. ManagedClusterAddOn ) {
94+ return func ( addon * addonv1alpha1. ManagedClusterAddOn ) {
95+ log := log . Log . WithName ( "CustomInformerEventHandler" )
8296
83- // Only process if status.namespace has changed
84- return oldAddon .Status .Namespace != newAddon .Status .Namespace
85- },
86- DeleteFunc : func (e event.DeleteEvent ) bool {
87- return false // Don't process Delete events
88- },
89- GenericFunc : func (e event.GenericEvent ) bool {
90- return false // Don't process Generic events
91- },
92- })).
93- Complete (r )
97+ // Find all ClusterPermissions in this addon's namespace that have ManagedServiceAccount subjects
98+ ctx := context .Background ()
99+ var clusterPermissions cpv1alpha1.ClusterPermissionList
100+ err := r .List (ctx , & clusterPermissions , & client.ListOptions {
101+ Namespace : addon .Namespace ,
102+ })
103+ if err != nil {
104+ log .Error (err , "failed to list ClusterPermissions" , "namespace" , addon .Namespace )
105+ return
106+ }
107+
108+ // Process each ClusterPermission that uses ManagedServiceAccount
109+ for _ , cp := range clusterPermissions .Items {
110+ if r .clusterPermissionUsesManagedServiceAccount (& cp ) {
111+ log .Info ("Triggering reconciliation for ClusterPermission due to ManagedClusterAddOn change" ,
112+ "clusterPermission" , cp .Name ,
113+ "namespace" , cp .Namespace ,
114+ "addonNamespace" , addon .Status .Namespace ,
115+ )
116+
117+ // Trigger reconciliation by updating the ClusterPermission
118+ r .reconcileClusterPermission (ctx , & cp )
119+ }
120+ }
121+ }
122+ }
123+
124+ // reconcileClusterPermission triggers reconciliation of a specific ClusterPermission
125+ func (r * ClusterPermissionReconciler ) reconcileClusterPermission (ctx context.Context , cp * cpv1alpha1.ClusterPermission ) {
126+ log := log .FromContext (ctx )
127+
128+ // Create a reconcile request
129+ req := reconcile.Request {
130+ NamespacedName : types.NamespacedName {
131+ Name : cp .Name ,
132+ Namespace : cp .Namespace ,
133+ },
134+ }
135+
136+ // Call the reconcile function directly
137+ _ , err := r .Reconcile (ctx , req )
138+ if err != nil {
139+ log .Error (err , "Failed to reconcile ClusterPermission" , "name" , cp .Name , "namespace" , cp .Namespace )
140+ }
94141}
95142
96143//+kubebuilder:rbac:groups=rbac.open-cluster-management.io,resources=clusterpermissions,verbs=get;list;watch;create;update;patch;delete
@@ -694,47 +741,6 @@ func joinStrings(strings []string, separator string) string {
694741 return result
695742}
696743
697- // managedClusterAddOnEventHandler returns an event handler that reconciles ClusterPermissions
698- // when a ManagedClusterAddOn's status.namespace changes
699- func (r * ClusterPermissionReconciler ) managedClusterAddOnEventHandler () handler.EventHandler {
700- return handler .EnqueueRequestsFromMapFunc (func (ctx context.Context , obj client.Object ) []reconcile.Request {
701- log := log .FromContext (ctx )
702-
703- addon , ok := obj .(* addonv1alpha1.ManagedClusterAddOn )
704- if ! ok {
705- log .Error (nil , "object is not a ManagedClusterAddOn" , "object" , obj )
706- return []reconcile.Request {}
707- }
708-
709- // Find all ClusterPermissions in this addon's namespace that have ManagedServiceAccount subjects
710- var clusterPermissions cpv1alpha1.ClusterPermissionList
711- err := r .List (ctx , & clusterPermissions , & client.ListOptions {
712- Namespace : addon .Namespace ,
713- })
714- if err != nil {
715- log .Error (err , "failed to list ClusterPermissions" , "namespace" , addon .Namespace )
716- return []reconcile.Request {}
717- }
718-
719- var requests []reconcile.Request
720- for _ , cp := range clusterPermissions .Items {
721- if r .clusterPermissionUsesManagedServiceAccount (& cp ) {
722- requests = append (requests , reconcile.Request {
723- NamespacedName : types.NamespacedName {
724- Name : cp .Name ,
725- Namespace : cp .Namespace ,
726- },
727- })
728- }
729- }
730-
731- log .Info ("ManagedClusterAddOn status.namespace changed, reconciling ClusterPermissions" ,
732- "addon" , addon .Name , "namespace" , addon .Namespace , "requests" , len (requests ))
733-
734- return requests
735- })
736- }
737-
738744// clusterPermissionUsesManagedServiceAccount checks if a ClusterPermission uses ManagedServiceAccount subjects
739745func (r * ClusterPermissionReconciler ) clusterPermissionUsesManagedServiceAccount (cp * cpv1alpha1.ClusterPermission ) bool {
740746 // Check ClusterRoleBinding
0 commit comments