diff --git a/pkg/background/update_request_controller.go b/pkg/background/update_request_controller.go index 6839675cb6..d1a924587d 100644 --- a/pkg/background/update_request_controller.go +++ b/pkg/background/update_request_controller.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" common "github.com/kyverno/kyverno/pkg/background/common" "github.com/kyverno/kyverno/pkg/background/generate" @@ -17,6 +18,7 @@ import ( "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/event" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/runtime" @@ -90,12 +92,12 @@ func NewController( DeleteFunc: c.deleteUR, }) cpolInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - UpdateFunc: c.updatePolicy, // We only handle updates to policy - // Deletion of policy will be handled by cleanup controller + UpdateFunc: c.updatePolicy, + DeleteFunc: c.deletePolicy, }) polInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - UpdateFunc: c.updatePolicy, // We only handle updates to policy - // Deletion of policy will be handled by cleanup controller + UpdateFunc: c.updatePolicy, + DeleteFunc: c.deletePolicy, }) return &c } @@ -188,6 +190,22 @@ func (c *controller) syncUpdateRequest(key string) error { return err } } + // try to get the linked policy + if _, err := c.getPolicy(ur.Spec.Policy); err != nil { + if apierrors.IsNotFound(err) { + // here only takes care of mutateExisting policies + // generate cleanup controller handles policy deletion + selector := &metav1.LabelSelector{ + MatchLabels: common.MutateLabelsSet(ur.Spec.Policy, nil), + } + return c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).DeleteCollection( + context.TODO(), + metav1.DeleteOptions{}, + metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)}, + ) + } + return err + } // if in pending state, try to acquire ur and eventually process it if ur.Status.State == kyvernov1beta1.Pending { ur, ok, err := c.acquireUR(ur) @@ -242,6 +260,24 @@ func (c *controller) updatePolicy(_, obj interface{}) { } } +func (c *controller) deletePolicy(obj interface{}) { + key, err := cache.MetaNamespaceKeyFunc(kubeutils.GetObjectWithTombstone(obj)) + if err != nil { + logger.Error(err, "failed to compute policy key") + } else { + logger.V(4).Info("updating policy", "key", key) + urs, err := c.urLister.GetUpdateRequestsForClusterPolicy(key) + if err != nil { + logger.Error(err, "failed to list update requests for policy", "key", key) + return + } + // re-evaluate the UR as the policy was updated + for _, ur := range urs { + c.enqueueUpdateRequest(ur) + } + } +} + func (c *controller) addUR(obj interface{}) { ur := obj.(*kyvernov1beta1.UpdateRequest) c.enqueueUpdateRequest(ur) @@ -330,3 +366,14 @@ func (c *controller) cleanUR(ur *kyvernov1beta1.UpdateRequest) error { } return nil } + +func (c *controller) getPolicy(key string) (kyvernov1.PolicyInterface, error) { + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, err + } + if namespace == "" { + return c.cpolLister.Get(name) + } + return c.polLister.Policies(namespace).Get(key) +} diff --git a/pkg/policy/policy_controller.go b/pkg/policy/policy_controller.go index a5760d61ab..4760f547bc 100644 --- a/pkg/policy/policy_controller.go +++ b/pkg/policy/policy_controller.go @@ -483,10 +483,6 @@ func (pc *PolicyController) syncPolicy(key string) error { policy, err := pc.getPolicy(key) if err != nil { if errors.IsNotFound(err) { - // here only takes care of mutateExisting policies - // generate cleanup controller handles policy deletion - mutateURs := pc.listMutateURs(key, nil) - deleteUR(pc.kyvernoClient, key, mutateURs, logger) return nil } return err @@ -496,23 +492,16 @@ func (pc *PolicyController) syncPolicy(key string) error { logger.Error(err, "failed to updateUR on Policy update") } } - pc.processExistingResources(policy) return nil } -func (pc *PolicyController) getPolicy(key string) (policy kyvernov1.PolicyInterface, err error) { +func (pc *PolicyController) getPolicy(key string) (kyvernov1.PolicyInterface, error) { namespace, key, isNamespacedPolicy := ParseNamespacedPolicy(key) if !isNamespacedPolicy { return pc.pLister.Get(key) } - - nsPolicy, err := pc.npLister.Policies(namespace).Get(key) - if err == nil && nsPolicy != nil { - policy = nsPolicy - } - - return + return pc.npLister.Policies(namespace).Get(key) } func generateTriggers(client dclient.Interface, rule kyvernov1.Rule, log logr.Logger) []*unstructured.Unstructured { @@ -530,17 +519,6 @@ func generateTriggers(client dclient.Interface, rule kyvernov1.Rule, log logr.Lo return convertlist(list.Items) } -func deleteUR(kyvernoClient kyvernoclient.Interface, policyKey string, grList []*kyvernov1beta1.UpdateRequest, logger logr.Logger) { - for _, v := range grList { - if policyKey == v.Spec.Policy { - err := kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Delete(context.TODO(), v.GetName(), metav1.DeleteOptions{}) - if err != nil && !errors.IsNotFound(err) { - logger.Error(err, "failed to delete ur", "name", v.GetName()) - } - } - } -} - func updateUR(kyvernoClient kyvernoclient.Interface, urLister kyvernov1beta1listers.UpdateRequestNamespaceLister, policyKey string, urList []*kyvernov1beta1.UpdateRequest, logger logr.Logger) { for _, ur := range urList { if policyKey == ur.Spec.Policy {