open-cluster-management.io/governance-policy-propagator@v0.13.0/controllers/common/policyset_handler.go (about) 1 // Copyright Contributors to the Open Cluster Management project 2 3 package common 4 5 import ( 6 "context" 7 8 "k8s.io/apimachinery/pkg/types" 9 "k8s.io/client-go/util/workqueue" 10 "sigs.k8s.io/controller-runtime/pkg/client" 11 "sigs.k8s.io/controller-runtime/pkg/event" 12 "sigs.k8s.io/controller-runtime/pkg/reconcile" 13 14 policiesv1beta1 "open-cluster-management.io/governance-policy-propagator/api/v1beta1" 15 ) 16 17 // EnqueueRequestsFromPolicySet adds reconcile requests for every policy in the policy set, 18 // except on updates, it'll only add the diff between the old and new sets. 19 type EnqueueRequestsFromPolicySet struct{} 20 21 // mapPolicySetToRequests maps a PolicySet to all the Policies in its policies list. 22 func mapPolicySetToRequests(object client.Object) []reconcile.Request { 23 log := log.WithValues("policySetName", object.GetName(), "namespace", object.GetNamespace()) 24 log.V(2).Info("Reconcile Request for PolicySet") 25 26 var result []reconcile.Request 27 28 //nolint:forcetypeassert 29 policySet := object.(*policiesv1beta1.PolicySet) 30 31 for _, plc := range policySet.Spec.Policies { 32 log.V(2).Info("Found reconciliation request from a policyset", "policyName", string(plc)) 33 34 request := reconcile.Request{NamespacedName: types.NamespacedName{ 35 Name: string(plc), 36 Namespace: object.GetNamespace(), 37 }} 38 result = append(result, request) 39 } 40 41 return result 42 } 43 44 // Create implements EventHandler 45 func (e *EnqueueRequestsFromPolicySet) Create(_ context.Context, evt event.CreateEvent, 46 q workqueue.RateLimitingInterface, 47 ) { 48 for _, policy := range mapPolicySetToRequests(evt.Object) { 49 q.Add(policy) 50 } 51 } 52 53 // Update implements EventHandler 54 // Enqueues the diff between the new and old policy sets in the UpdateEvent 55 func (e *EnqueueRequestsFromPolicySet) Update(_ context.Context, evt event.UpdateEvent, 56 q workqueue.RateLimitingInterface, 57 ) { 58 //nolint:forcetypeassert 59 newPolicySet := evt.ObjectNew.(*policiesv1beta1.PolicySet) 60 //nolint:forcetypeassert 61 oldPolicySet := evt.ObjectOld.(*policiesv1beta1.PolicySet) 62 63 newPoliciesMap := make(map[string]bool) 64 oldPoliciesMap := make(map[string]bool) 65 diffPolicies := []policiesv1beta1.NonEmptyString{} 66 67 for _, plc := range newPolicySet.Spec.Policies { 68 newPoliciesMap[string(plc)] = true 69 } 70 71 for _, plc := range oldPolicySet.Spec.Policies { 72 oldPoliciesMap[string(plc)] = true 73 } 74 75 for _, plc := range oldPolicySet.Spec.Policies { 76 if !newPoliciesMap[string(plc)] { 77 diffPolicies = append(diffPolicies, plc) 78 } 79 } 80 81 for _, plc := range newPolicySet.Spec.Policies { 82 if !oldPoliciesMap[string(plc)] { 83 diffPolicies = append(diffPolicies, plc) 84 } 85 } 86 87 for _, plc := range diffPolicies { 88 log.V(2).Info("Found reconciliation request from a policyset", "policyName", string(plc)) 89 90 request := reconcile.Request{NamespacedName: types.NamespacedName{ 91 Name: string(plc), 92 Namespace: newPolicySet.GetNamespace(), 93 }} 94 q.Add(request) 95 } 96 } 97 98 // Delete implements EventHandler 99 func (e *EnqueueRequestsFromPolicySet) Delete(_ context.Context, evt event.DeleteEvent, 100 q workqueue.RateLimitingInterface, 101 ) { 102 for _, policy := range mapPolicySetToRequests(evt.Object) { 103 q.Add(policy) 104 } 105 } 106 107 // Generic implements EventHandler 108 func (e *EnqueueRequestsFromPolicySet) Generic(_ context.Context, evt event.GenericEvent, 109 q workqueue.RateLimitingInterface, 110 ) { 111 for _, policy := range mapPolicySetToRequests(evt.Object) { 112 q.Add(policy) 113 } 114 }