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

     1  // Copyright (c) 2022 Red Hat, Inc.
     2  // Copyright Contributors to the Open Cluster Management project
     3  
     4  package controllers
     5  
     6  import (
     7  	"context"
     8  
     9  	"k8s.io/apimachinery/pkg/types"
    10  	clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1"
    11  	"sigs.k8s.io/controller-runtime/pkg/client"
    12  	"sigs.k8s.io/controller-runtime/pkg/handler"
    13  	"sigs.k8s.io/controller-runtime/pkg/reconcile"
    14  
    15  	policiesv1 "open-cluster-management.io/governance-policy-propagator/api/v1"
    16  )
    17  
    18  func placementDecisionMapper(c client.Client) handler.MapFunc {
    19  	return func(ctx context.Context, object client.Object) []reconcile.Request {
    20  		log := log.WithValues("placementDecisionName", object.GetName(), "namespace", object.GetNamespace())
    21  
    22  		log.V(2).Info("Reconcile request for a placement decision")
    23  
    24  		// get the placement name from the placementdecision
    25  		placementName := object.GetLabels()["cluster.open-cluster-management.io/placement"]
    26  		if placementName == "" {
    27  			return nil
    28  		}
    29  
    30  		pbList := &policiesv1.PlacementBindingList{}
    31  		// find pb in the same namespace of placementrule
    32  		lopts := &client.ListOptions{Namespace: object.GetNamespace()}
    33  		opts := client.MatchingFields{"placementRef.name": placementName}
    34  		opts.ApplyToList(lopts)
    35  
    36  		err := c.List(ctx, pbList, lopts)
    37  		if err != nil {
    38  			return nil
    39  		}
    40  
    41  		var result []reconcile.Request
    42  		// loop through pb to find if current placement is used for policy set
    43  		for _, pb := range pbList.Items {
    44  			if pb.PlacementRef.APIGroup != clusterv1beta1.SchemeGroupVersion.Group ||
    45  				pb.PlacementRef.Kind != "Placement" || pb.PlacementRef.Name != placementName {
    46  				continue
    47  			}
    48  
    49  			// found matching placement in pb -- check if it is for policyset
    50  			subjects := pb.Subjects
    51  			for _, subject := range subjects {
    52  				if subject.APIGroup == policiesv1.SchemeGroupVersion.Group {
    53  					if subject.Kind == policiesv1.PolicySetKind {
    54  						log.V(2).Info("Found reconciliation request from policyset placement decision",
    55  							"policySetName", subject.Name)
    56  
    57  						request := reconcile.Request{NamespacedName: types.NamespacedName{
    58  							Name:      subject.Name,
    59  							Namespace: object.GetNamespace(),
    60  						}}
    61  						result = append(result, request)
    62  					}
    63  				}
    64  			}
    65  		}
    66  
    67  		return result
    68  	}
    69  }