open-cluster-management.io/governance-policy-propagator@v0.13.0/controllers/propagator/replicatepolicy_pd_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 clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1" 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 // HandlerForDecision maps a PlacementDecision 18 // to all replicated policies that are in namespace as a decision cluster name. 19 // The name of replicated policy is rootpolicy name + namespace which is in Placementbinding subject 20 func HandlerForDecision(c client.Client) handler.EventHandler { 21 return &handlerForDecision{ 22 c, 23 } 24 } 25 26 type handlerForDecision struct { 27 c client.Client 28 } 29 30 // Create implements EventHandler. 31 func (e *handlerForDecision) Create(ctx context.Context, 32 evt event.CreateEvent, q workqueue.RateLimitingInterface, 33 ) { 34 e.mapAndEnqueue(ctx, q, evt.Object) 35 } 36 37 // Update implements EventHandler. Update only targeted(modified) objects 38 func (e *handlerForDecision) Update(ctx context.Context, 39 evt event.UpdateEvent, q workqueue.RateLimitingInterface, 40 ) { 41 log.V(1).Info("Detect placementDecision and update targeted replicated-policies") 42 //nolint:forcetypeassert 43 newObj := evt.ObjectNew.(*clusterv1beta1.PlacementDecision) 44 //nolint:forcetypeassert 45 oldObj := evt.ObjectOld.(*clusterv1beta1.PlacementDecision) 46 47 placementName := newObj.GetLabels()["cluster.open-cluster-management.io/placement"] 48 if placementName == "" { 49 return 50 } 51 52 newOjbDecisions := newObj.Status.Decisions 53 oldObjDecisions := oldObj.Status.Decisions 54 55 // Select only affected(Deleted in old or Created in new) objs 56 affectedDecisions := common.GetAffectedObjs(newOjbDecisions, oldObjDecisions) 57 58 // These is no change. Nothing to reconcile 59 if len(affectedDecisions) == 0 { 60 return 61 } 62 63 rootPolicyResults, err := common.GetRootPolicyRequests(ctx, e.c, 64 newObj.GetNamespace(), placementName, common.Placement) 65 if err != nil { 66 log.Error(err, "Failed to get RootPolicyResults to update by decision event") 67 68 return 69 } 70 71 for _, pr := range rootPolicyResults { 72 for _, decision := range affectedDecisions { 73 q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ 74 Namespace: decision.ClusterName, 75 Name: pr.Namespace + "." + pr.Name, 76 }}) 77 } 78 } 79 } 80 81 // Delete implements EventHandler. 82 func (e *handlerForDecision) Delete(ctx context.Context, 83 evt event.DeleteEvent, q workqueue.RateLimitingInterface, 84 ) { 85 e.mapAndEnqueue(ctx, q, evt.Object) 86 } 87 88 // Generic implements EventHandler. 89 func (e *handlerForDecision) Generic(ctx context.Context, 90 evt event.GenericEvent, q workqueue.RateLimitingInterface, 91 ) { 92 e.mapAndEnqueue(ctx, q, evt.Object) 93 } 94 95 func (e *handlerForDecision) mapAndEnqueue(ctx context.Context, 96 q workqueue.RateLimitingInterface, obj client.Object, 97 ) { 98 pDecision := obj.(*clusterv1beta1.PlacementDecision) 99 reqs := e.getMappedReplicatedPolicy(ctx, pDecision) 100 101 for _, req := range reqs { 102 q.Add(req) 103 } 104 } 105 106 func (e *handlerForDecision) getMappedReplicatedPolicy(ctx context.Context, 107 pDecision *clusterv1beta1.PlacementDecision, 108 ) []reconcile.Request { 109 if len(pDecision.Status.Decisions) == 0 { 110 return nil 111 } 112 113 placementName := pDecision.GetLabels()["cluster.open-cluster-management.io/placement"] 114 if placementName == "" { 115 return nil 116 } 117 118 rootPolicyResults, err := common.GetRootPolicyRequests(ctx, e.c, 119 pDecision.GetNamespace(), placementName, common.Placement) 120 if err != nil { 121 log.Error(err, "Failed to get RootPolicyResults by decision events") 122 123 return nil 124 } 125 126 var result []reconcile.Request 127 128 for _, pr := range rootPolicyResults { 129 for _, decision := range pDecision.Status.Decisions { 130 result = append(result, reconcile.Request{NamespacedName: types.NamespacedName{ 131 Namespace: decision.ClusterName, 132 Name: pr.Namespace + "." + pr.Name, 133 }}) 134 } 135 } 136 137 return result 138 }