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  }