open-cluster-management.io/governance-policy-propagator@v0.13.0/controllers/propagator/rootpolicy_setup.go (about)

     1  // Copyright (c) 2023 Red Hat, Inc.
     2  // Copyright Contributors to the Open Cluster Management project
     3  
     4  package propagator
     5  
     6  import (
     7  	"k8s.io/apimachinery/pkg/api/equality"
     8  	ctrl "sigs.k8s.io/controller-runtime"
     9  	"sigs.k8s.io/controller-runtime/pkg/builder"
    10  	"sigs.k8s.io/controller-runtime/pkg/controller"
    11  	"sigs.k8s.io/controller-runtime/pkg/event"
    12  	"sigs.k8s.io/controller-runtime/pkg/predicate"
    13  
    14  	policiesv1 "open-cluster-management.io/governance-policy-propagator/api/v1"
    15  	policiesv1beta1 "open-cluster-management.io/governance-policy-propagator/api/v1beta1"
    16  	"open-cluster-management.io/governance-policy-propagator/controllers/common"
    17  )
    18  
    19  //+kubebuilder:rbac:groups=policy.open-cluster-management.io,resources=policies,verbs=get;list;watch;create;update;patch;delete
    20  //+kubebuilder:rbac:groups=policy.open-cluster-management.io,resources=policies/status,verbs=get;update;patch
    21  //+kubebuilder:rbac:groups=policy.open-cluster-management.io,resources=policies/finalizers,verbs=update
    22  //+kubebuilder:rbac:groups=policy.open-cluster-management.io,resources=placementbindings,verbs=get;list;watch;create;update;patch;delete
    23  //+kubebuilder:rbac:groups=policy.open-cluster-management.io,resources=policysets,verbs=get;list;watch
    24  //+kubebuilder:rbac:groups=cluster.open-cluster-management.io,resources=managedclusters;placementdecisions;placements,verbs=get;list;watch
    25  //+kubebuilder:rbac:groups=apps.open-cluster-management.io,resources=placementrules,verbs=get;list;watch
    26  //+kubebuilder:rbac:groups=core,resources=events,verbs=get;list;watch;create;update;patch;delete
    27  //+kubebuilder:rbac:groups=*,resources=*,verbs=get;list;watch
    28  
    29  // SetupWithManager sets up the controller with the Manager.
    30  func (r *RootPolicyReconciler) SetupWithManager(mgr ctrl.Manager, maxConcurrentReconciles uint) error {
    31  	return ctrl.NewControllerManagedBy(mgr).
    32  		WithOptions(controller.Options{MaxConcurrentReconciles: int(maxConcurrentReconciles)}).
    33  		Named("root-policy-spec").
    34  		For(
    35  			&policiesv1.Policy{},
    36  			builder.WithPredicates(rootPolicyNonStatusUpdates())).
    37  		Watches(
    38  			&policiesv1beta1.PolicySet{},
    39  			&common.EnqueueRequestsFromPolicySet{}).
    40  		Complete(r)
    41  }
    42  
    43  // policyNonStatusUpdates triggers reconciliation if the Policy has had a change that is not just
    44  // a status update.
    45  func rootPolicyNonStatusUpdates() predicate.Funcs {
    46  	return predicate.Funcs{
    47  		CreateFunc: func(e event.CreateEvent) bool {
    48  			_, isReplicated := e.Object.GetLabels()[common.RootPolicyLabel]
    49  
    50  			return !isReplicated
    51  		},
    52  		DeleteFunc: func(e event.DeleteEvent) bool {
    53  			_, isReplicated := e.Object.GetLabels()[common.RootPolicyLabel]
    54  
    55  			return !isReplicated
    56  		},
    57  		UpdateFunc: func(e event.UpdateEvent) bool {
    58  			_, newIsReplicated := e.ObjectNew.GetLabels()[common.RootPolicyLabel]
    59  			_, oldIsReplicated := e.ObjectOld.GetLabels()[common.RootPolicyLabel]
    60  
    61  			// if either has the label, it is a replicated policy
    62  			if oldIsReplicated || newIsReplicated {
    63  				return false
    64  			}
    65  
    66  			// Ignore pure status updates since those are handled by a separate controller
    67  			return e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration() ||
    68  				!equality.Semantic.DeepEqual(e.ObjectOld.GetLabels(), e.ObjectNew.GetLabels()) ||
    69  				!equality.Semantic.DeepEqual(e.ObjectOld.GetAnnotations(), e.ObjectNew.GetAnnotations())
    70  		},
    71  	}
    72  }