open-cluster-management.io/governance-policy-propagator@v0.13.0/controllers/propagator/replicatepolicy_pr_eventHandler.go (about) 1 package propagator 2 3 import ( 4 "context" 5 6 "k8s.io/apimachinery/pkg/types" 7 "k8s.io/client-go/util/workqueue" 8 appsv1 "open-cluster-management.io/multicloud-operators-subscription/pkg/apis/apps/placementrule/v1" 9 "sigs.k8s.io/controller-runtime/pkg/client" 10 "sigs.k8s.io/controller-runtime/pkg/event" 11 "sigs.k8s.io/controller-runtime/pkg/handler" 12 "sigs.k8s.io/controller-runtime/pkg/reconcile" 13 14 "open-cluster-management.io/governance-policy-propagator/controllers/common" 15 ) 16 17 // HandlerForRule maps a PlacementRule to all replicated policies which are in the namespace as 18 // PlacementRule status.decisions. This finds placementBindings, of which placementRef is the placementRule, 19 // then collects all rootPolicies in placementBindings. Replicated policies are determined 20 // from decisions in the placementRule and a rootPolicy name 21 func HandlerForRule(c client.Client) handler.EventHandler { 22 return &handlerForRule{ 23 c, 24 } 25 } 26 27 type handlerForRule struct { 28 c client.Client 29 } 30 31 // Create implements EventHandler. 32 func (e *handlerForRule) Create(ctx context.Context, 33 evt event.CreateEvent, q workqueue.RateLimitingInterface, 34 ) { 35 e.mapAndEnqueue(ctx, q, evt.Object) 36 } 37 38 // Update implements EventHandler. Update only targeted(modified) objects 39 func (e *handlerForRule) Update(ctx context.Context, 40 evt event.UpdateEvent, q workqueue.RateLimitingInterface, 41 ) { 42 log.Info("Detect placementDecision and update targeted replicated-policies") 43 //nolint:forcetypeassert 44 newObj := evt.ObjectNew.(*appsv1.PlacementRule) 45 //nolint:forcetypeassert 46 oldObj := evt.ObjectOld.(*appsv1.PlacementRule) 47 48 newOjbDecisions := newObj.Status.Decisions 49 oldObjDecisions := oldObj.Status.Decisions 50 51 // Select only affected(Deleted in old or Created in new) objs 52 affectedDecisions := common.GetAffectedObjs(newOjbDecisions, oldObjDecisions) 53 54 // These is no status.decision change. Nothing to reconcile 55 if len(affectedDecisions) == 0 { 56 return 57 } 58 59 rootPolicyResults, err := common.GetRootPolicyRequests(ctx, e.c, 60 newObj.GetNamespace(), newObj.GetName(), common.PlacementRule) 61 if err != nil { 62 log.Error(err, "Failed to get RootPolicyResults to update by Rule event") 63 64 return 65 } 66 67 for _, pr := range rootPolicyResults { 68 for _, decision := range affectedDecisions { 69 q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ 70 Namespace: decision.ClusterNamespace, 71 Name: pr.Namespace + "." + pr.Name, 72 }}) 73 } 74 } 75 } 76 77 // Delete implements EventHandler. 78 func (e *handlerForRule) Delete(ctx context.Context, 79 evt event.DeleteEvent, q workqueue.RateLimitingInterface, 80 ) { 81 e.mapAndEnqueue(ctx, q, evt.Object) 82 } 83 84 // Generic implements EventHandler. 85 func (e *handlerForRule) Generic(ctx context.Context, 86 evt event.GenericEvent, q workqueue.RateLimitingInterface, 87 ) { 88 e.mapAndEnqueue(ctx, q, evt.Object) 89 } 90 91 func (e *handlerForRule) mapAndEnqueue(ctx context.Context, 92 q workqueue.RateLimitingInterface, obj client.Object, 93 ) { 94 pRule := obj.(*appsv1.PlacementRule) 95 reqs := e.getMappedReplicatedPolicy(ctx, pRule) 96 97 for _, req := range reqs { 98 q.Add(req) 99 } 100 } 101 102 func (e *handlerForRule) getMappedReplicatedPolicy(ctx context.Context, 103 pRule *appsv1.PlacementRule, 104 ) []reconcile.Request { 105 if len(pRule.Status.Decisions) == 0 { 106 return nil 107 } 108 109 rootPolicyResults, err := common.GetRootPolicyRequests(ctx, e.c, 110 pRule.GetNamespace(), pRule.GetName(), common.PlacementRule) 111 if err != nil { 112 log.Error(err, "Failed to get RootPolicyResults By Rule event") 113 114 return nil 115 } 116 117 var result []reconcile.Request 118 119 for _, pr := range rootPolicyResults { 120 for _, decision := range pRule.Status.Decisions { 121 result = append(result, reconcile.Request{NamespacedName: types.NamespacedName{ 122 Namespace: decision.ClusterNamespace, 123 Name: pr.Namespace + "." + pr.Name, 124 }}) 125 } 126 } 127 128 return result 129 }