package policy import ( "fmt" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2" backgroundcommon "github.com/kyverno/kyverno/pkg/background/common" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" ) func (pc *policyController) handleMutate(policyKey string, policy kyvernov1.PolicyInterface) error { logger := pc.log.WithName("handleMutate").WithName(policyKey) logger.V(4).Info("update URs on policy event") ruleType := kyvernov2.Mutate spec := policy.GetSpec() policyNew := policy.CreateDeepCopy() policyNew.GetSpec().Rules = nil for _, rule := range spec.Rules { if !rule.HasMutateExisting() { continue } mutateExisting := rule.Mutation.MutateExistingOnPolicyUpdate if mutateExisting != nil { if !*mutateExisting { continue } } else if !spec.MutateExistingOnPolicyUpdate { continue } policyNew.GetSpec().SetRules([]kyvernov1.Rule{rule}) triggers := getTriggers(pc.client, rule, policyNew.IsNamespaced(), policyNew.GetNamespace(), pc.log) for _, trigger := range triggers { murs := pc.listMutateURs(policyKey, trigger) if murs != nil { logger.V(4).Info("UR was created", "rule", rule.Name, "rule type", ruleType, "trigger", trigger.GetNamespace()+trigger.GetName()) continue } logger.V(4).Info("creating new UR for mutate") ur := newMutateUR(policy, backgroundcommon.ResourceSpecFromUnstructured(*trigger), rule.Name) skip, err := pc.handleUpdateRequest(ur, trigger, rule.Name, policyNew) if err != nil { pc.log.Error(err, "failed to create new UR on policy update", "policy", policyNew.GetName(), "rule", rule.Name, "rule type", ruleType, "target", fmt.Sprintf("%s/%s/%s/%s", trigger.GetAPIVersion(), trigger.GetKind(), trigger.GetNamespace(), trigger.GetName())) continue } if skip { continue } pc.log.V(2).Info("successfully created UR on policy update", "policy", policyNew.GetName(), "rule", rule.Name, "rule type", ruleType, "target", fmt.Sprintf("%s/%s/%s/%s", trigger.GetAPIVersion(), trigger.GetKind(), trigger.GetNamespace(), trigger.GetName())) } } return nil } func (pc *policyController) listMutateURs(policyKey string, trigger *unstructured.Unstructured) []*kyvernov2.UpdateRequest { mutateURs, err := pc.urLister.List(labels.SelectorFromSet(backgroundcommon.MutateLabelsSet(policyKey, trigger))) if err != nil { pc.log.Error(err, "failed to list update request for mutate policy") } return mutateURs }