diff --git a/api/kyverno/v1/resource_spec_types.go b/api/kyverno/v1/resource_spec_types.go
index 59890fea7a..88aada79c0 100644
--- a/api/kyverno/v1/resource_spec_types.go
+++ b/api/kyverno/v1/resource_spec_types.go
@@ -1,5 +1,7 @@
package v1
+import "strings"
+
type ResourceSpec struct {
// APIVersion specifies resource apiVersion.
// +optional
@@ -18,3 +20,7 @@ func (s ResourceSpec) GetName() string { return s.Name }
func (s ResourceSpec) GetNamespace() string { return s.Namespace }
func (s ResourceSpec) GetKind() string { return s.Kind }
func (s ResourceSpec) GetAPIVersion() string { return s.APIVersion }
+
+func (s ResourceSpec) String() string {
+ return strings.Join([]string{s.APIVersion, s.Kind, s.Namespace, s.Name}, "/")
+}
diff --git a/api/kyverno/v1beta1/updaterequest_types.go b/api/kyverno/v1beta1/updaterequest_types.go
index b036b5729b..c017a0c5dd 100644
--- a/api/kyverno/v1beta1/updaterequest_types.go
+++ b/api/kyverno/v1beta1/updaterequest_types.go
@@ -83,6 +83,13 @@ type UpdateRequestSpec struct {
// Specifies the name of the policy.
Policy string `json:"policy" yaml:"policy"`
+ // Rule is the associate rule name of the current UR.
+ Rule string `json:"rule" yaml:"rule"`
+
+ // Synchronize represents the sync behavior of the corresponding rule
+ // Optional. Defaults to "false" if not specified.
+ Synchronize bool `json:"synchronize,omitempty" yaml:"synchronize,omitempty"`
+
// ResourceSpec is the information to identify the update request.
Resource kyvernov1.ResourceSpec `json:"resource" yaml:"resource"`
@@ -152,3 +159,19 @@ type UpdateRequestList struct {
func (s *UpdateRequestSpec) GetRequestType() RequestType {
return s.Type
}
+
+func (s *UpdateRequestSpec) GetPolicyKey() string {
+ return s.Policy
+}
+
+func (s *UpdateRequestSpec) GetRuleName() string {
+ return s.Rule
+}
+
+func (s *UpdateRequestSpec) GetSynchronize() bool {
+ return s.Synchronize
+}
+
+func (s *UpdateRequestSpec) GetResource() kyvernov1.ResourceSpec {
+ return s.Resource
+}
diff --git a/charts/kyverno/templates/crds/crds.yaml b/charts/kyverno/templates/crds/crds.yaml
index be58e2af04..be7c1a4a1f 100644
--- a/charts/kyverno/templates/crds/crds.yaml
+++ b/charts/kyverno/templates/crds/crds.yaml
@@ -30532,10 +30532,18 @@ spec:
description: Namespace specifies resource namespace.
type: string
type: object
+ rule:
+ description: Rule is the associate rule name of the current UR.
+ type: string
+ synchronize:
+ description: Synchronize represents the sync behavior of the corresponding
+ rule Optional. Defaults to "false" if not specified.
+ type: boolean
required:
- context
- policy
- resource
+ - rule
type: object
status:
description: Status contains statistics related to update request.
diff --git a/config/crds/kyverno.io_updaterequests.yaml b/config/crds/kyverno.io_updaterequests.yaml
index 485a2eec80..4eb72ab294 100644
--- a/config/crds/kyverno.io_updaterequests.yaml
+++ b/config/crds/kyverno.io_updaterequests.yaml
@@ -341,10 +341,18 @@ spec:
description: Namespace specifies resource namespace.
type: string
type: object
+ rule:
+ description: Rule is the associate rule name of the current UR.
+ type: string
+ synchronize:
+ description: Synchronize represents the sync behavior of the corresponding
+ rule Optional. Defaults to "false" if not specified.
+ type: boolean
required:
- context
- policy
- resource
+ - rule
type: object
status:
description: Status contains statistics related to update request.
diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html
index 95d915fa71..ca9b9f5a20 100644
--- a/docs/user/crd/index.html
+++ b/docs/user/crd/index.html
@@ -4386,6 +4386,29 @@ string
+rule
+
+string
+
+ |
+
+ Rule is the associate rule name of the current UR.
+ |
+
+
+
+synchronize
+
+bool
+
+ |
+
+ Synchronize represents the sync behavior of the corresponding rule
+Optional. Defaults to “false” if not specified.
+ |
+
+
+
resource
@@ -4585,6 +4608,29 @@ string
|
+rule
+
+string
+
+ |
+
+ Rule is the associate rule name of the current UR.
+ |
+
+
+
+synchronize
+
+bool
+
+ |
+
+ Synchronize represents the sync behavior of the corresponding rule
+Optional. Defaults to “false” if not specified.
+ |
+
+
+
resource
diff --git a/pkg/background/common/context.go b/pkg/background/common/context.go
index a317c25497..0efb5cefef 100644
--- a/pkg/background/common/context.go
+++ b/pkg/background/common/context.go
@@ -39,7 +39,7 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe
if !reflect.DeepEqual(new, unstructured.Unstructured{}) {
if !check(&new, trigger) {
err := fmt.Errorf("resources don't match")
- return nil, false, fmt.Errorf("resource %v: %w", ur.Spec.Resource, err)
+ return nil, false, fmt.Errorf("resource %v: %w", ur.Spec.GetResource().String(), err)
}
}
}
diff --git a/pkg/background/common/resource.go b/pkg/background/common/resource.go
index 1220fa24f1..44345c2f3f 100644
--- a/pkg/background/common/resource.go
+++ b/pkg/background/common/resource.go
@@ -16,7 +16,7 @@ import (
)
func GetResource(client dclient.Interface, urSpec kyvernov1beta1.UpdateRequestSpec, log logr.Logger) (*unstructured.Unstructured, error) {
- resourceSpec := urSpec.Resource
+ resourceSpec := urSpec.GetResource()
get := func() (*unstructured.Unstructured, error) {
if resourceSpec.Kind == "Namespace" {
@@ -24,7 +24,7 @@ func GetResource(client dclient.Interface, urSpec kyvernov1beta1.UpdateRequestSp
}
resource, err := client.GetResource(context.TODO(), resourceSpec.APIVersion, resourceSpec.Kind, resourceSpec.Namespace, resourceSpec.Name)
if err != nil {
- if urSpec.Type == kyvernov1beta1.Mutate && errors.IsNotFound(err) && urSpec.Context.AdmissionRequestInfo.Operation == admissionv1.Delete {
+ if urSpec.GetRequestType() == kyvernov1beta1.Mutate && errors.IsNotFound(err) && urSpec.Context.AdmissionRequestInfo.Operation == admissionv1.Delete {
log.V(4).Info("trigger resource does not exist for mutateExisting rule", "operation", urSpec.Context.AdmissionRequestInfo.Operation)
return nil, nil
}
diff --git a/pkg/background/generate/generate.go b/pkg/background/generate/generate.go
index a31f85ee34..f6244277be 100644
--- a/pkg/background/generate/generate.go
+++ b/pkg/background/generate/generate.go
@@ -86,7 +86,7 @@ func NewGenerateController(
}
func (c *GenerateController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
- logger := c.log.WithValues("name", ur.Name, "policy", ur.Spec.Policy, "kind", ur.Spec.Resource.Kind, "apiVersion", ur.Spec.Resource.APIVersion, "namespace", ur.Spec.Resource.Namespace, "name", ur.Spec.Resource.Name)
+ logger := c.log.WithValues("name", ur.GetName(), "policy", ur.Spec.GetPolicyKey(), "resource", ur.Spec.GetResource().String())
var err error
var resource *unstructured.Unstructured
var genResources []kyvernov1.ResourceSpec
@@ -148,7 +148,7 @@ func (c *GenerateController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
const doesNotApply = "policy does not apply to resource"
func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, ur kyvernov1beta1.UpdateRequest, namespaceLabels map[string]string) ([]kyvernov1.ResourceSpec, bool, error) {
- logger := c.log.WithValues("name", ur.GetName(), "policy", ur.Spec.Policy, "kind", ur.Spec.Resource.Kind, "apiVersion", ur.Spec.Resource.APIVersion, "namespace", ur.Spec.Resource.Namespace, "name", ur.Spec.Resource.Name)
+ logger := c.log.WithValues("name", ur.GetName(), "policy", ur.Spec.GetPolicyKey(), "resource", ur.Spec.GetResource().String())
logger.V(3).Info("applying generate policy rule")
policy, err := c.getPolicySpec(ur)
diff --git a/pkg/background/mutate/mutate.go b/pkg/background/mutate/mutate.go
index f722c1e3ab..8346335a25 100644
--- a/pkg/background/mutate/mutate.go
+++ b/pkg/background/mutate/mutate.go
@@ -70,7 +70,7 @@ func NewMutateExistingController(
}
func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
- logger := c.log.WithValues("name", ur.Name, "policy", ur.Spec.Policy, "kind", ur.Spec.Resource.Kind, "apiVersion", ur.Spec.Resource.APIVersion, "namespace", ur.Spec.Resource.Namespace, "name", ur.Spec.Resource.Name)
+ logger := c.log.WithValues("name", ur.GetName(), "policy", ur.Spec.GetPolicyKey(), "resource", ur.Spec.GetResource().String())
var errs []error
policy, err := c.getPolicy(ur.Spec.Policy)
diff --git a/pkg/background/update_request_controller.go b/pkg/background/update_request_controller.go
index e8259a9c02..34c1b040ee 100644
--- a/pkg/background/update_request_controller.go
+++ b/pkg/background/update_request_controller.go
@@ -195,7 +195,7 @@ func (c *controller) syncUpdateRequest(key string) error {
}
// try to get the linked policy
if _, err := c.getPolicy(ur.Spec.Policy); err != nil {
- if apierrors.IsNotFound(err) && ur.Spec.Type == kyvernov1beta1.Mutate {
+ if apierrors.IsNotFound(err) && ur.Spec.GetRequestType() == kyvernov1beta1.Mutate {
// here only takes care of mutateExisting policies
// generate cleanup controller handles policy deletion
selector := &metav1.LabelSelector{
@@ -387,7 +387,7 @@ func (c *controller) deleteUR(obj interface{}) {
func (c *controller) processUR(ur *kyvernov1beta1.UpdateRequest) error {
statusControl := common.NewStatusControl(c.kyvernoClient, c.urLister)
- switch ur.Spec.Type {
+ switch ur.Spec.GetRequestType() {
case kyvernov1beta1.Mutate:
ctrl := mutate.NewMutateExistingController(c.client, statusControl, c.engine, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.eventGen, logger)
return ctrl.ProcessUR(ur)
@@ -399,7 +399,7 @@ func (c *controller) processUR(ur *kyvernov1beta1.UpdateRequest) error {
}
func (c *controller) cleanUR(ur *kyvernov1beta1.UpdateRequest) error {
- if ur.Spec.Type == kyvernov1beta1.Mutate && ur.Status.State == kyvernov1beta1.Completed {
+ if ur.Spec.GetRequestType() == kyvernov1beta1.Mutate && ur.Status.State == kyvernov1beta1.Completed {
return c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Delete(context.TODO(), ur.GetName(), metav1.DeleteOptions{})
}
return nil
diff --git a/pkg/client/listers/kyverno/v1beta1/updaterequest_expansion.go b/pkg/client/listers/kyverno/v1beta1/updaterequest_expansion.go
index 48b83dce68..da1cf6c62f 100644
--- a/pkg/client/listers/kyverno/v1beta1/updaterequest_expansion.go
+++ b/pkg/client/listers/kyverno/v1beta1/updaterequest_expansion.go
@@ -33,7 +33,7 @@ func (s updateRequestNamespaceLister) GetUpdateRequestsForClusterPolicy(policy s
return nil, err
}
for idx, ur := range urs {
- if ur.Spec.Policy == policy {
+ if ur.Spec.GetPolicyKey() == policy {
list = append(list, urs[idx])
}
}
diff --git a/pkg/policy/policy_controller.go b/pkg/policy/policy_controller.go
index 527399664a..8afb6e7d5e 100644
--- a/pkg/policy/policy_controller.go
+++ b/pkg/policy/policy_controller.go
@@ -567,7 +567,7 @@ func generateTriggers(client dclient.Interface, rule kyvernov1.Rule, log logr.Lo
func updateUR(kyvernoClient versioned.Interface, urLister kyvernov1beta1listers.UpdateRequestNamespaceLister, policyKey string, urList []*kyvernov1beta1.UpdateRequest, logger logr.Logger) {
for _, ur := range urList {
- if policyKey == ur.Spec.Policy {
+ if policyKey == ur.Spec.GetPolicyKey() {
_, err := backgroundcommon.Update(kyvernoClient, urLister, ur.GetName(), func(ur *kyvernov1beta1.UpdateRequest) {
urLabels := ur.Labels
if len(urLabels) == 0 {
diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go
index 04c65bcaad..5436702b75 100644
--- a/pkg/webhooks/resource/handlers.go
+++ b/pkg/webhooks/resource/handlers.go
@@ -212,7 +212,7 @@ func (h *handlers) handleDelete(logger logr.Logger, request *admissionv1.Admissi
return
}
- if ur.Spec.Type == kyvernov1beta1.Mutate {
+ if ur.Spec.GetRequestType() == kyvernov1beta1.Mutate {
return
}
h.urUpdater.UpdateAnnotation(logger, ur.GetName())
diff --git a/pkg/webhooks/updaterequest/generator.go b/pkg/webhooks/updaterequest/generator.go
index 9747096dc3..f72cdfdd33 100644
--- a/pkg/webhooks/updaterequest/generator.go
+++ b/pkg/webhooks/updaterequest/generator.go
@@ -41,7 +41,7 @@ func NewGenerator(client versioned.Interface, urInformer kyvernov1beta1informers
// Apply creates update request resource
func (g *generator) Apply(ctx context.Context, ur kyvernov1beta1.UpdateRequestSpec, action admissionv1.Operation) error {
logger.V(4).Info("reconcile Update Request", "request", ur)
- if action == admissionv1.Delete && ur.Type == kyvernov1beta1.Generate {
+ if action == admissionv1.Delete && ur.GetRequestType() == kyvernov1beta1.Generate {
return nil
}
go g.applyResource(context.TODO(), ur)
@@ -64,17 +64,17 @@ func (g *generator) applyResource(ctx context.Context, urSpec kyvernov1beta1.Upd
}
func (g *generator) tryApplyResource(ctx context.Context, urSpec kyvernov1beta1.UpdateRequestSpec) error {
- l := logger.WithValues("ruleType", urSpec.Type, "kind", urSpec.Resource.Kind, "name", urSpec.Resource.Name, "namespace", urSpec.Resource.Namespace)
+ l := logger.WithValues("ruleType", urSpec.GetRequestType(), "resource", urSpec.GetResource().String())
var queryLabels labels.Set
- if urSpec.Type == kyvernov1beta1.Mutate {
- queryLabels = common.MutateLabelsSet(urSpec.Policy, urSpec.Resource)
- } else if urSpec.Type == kyvernov1beta1.Generate {
- queryLabels = common.GenerateLabelsSet(urSpec.Policy, urSpec.Resource)
+ if urSpec.GetRequestType() == kyvernov1beta1.Mutate {
+ queryLabels = common.MutateLabelsSet(urSpec.Policy, urSpec.GetResource())
+ } else if urSpec.GetRequestType() == kyvernov1beta1.Generate {
+ queryLabels = common.GenerateLabelsSet(urSpec.Policy, urSpec.GetResource())
}
urList, err := g.urLister.List(labels.SelectorFromSet(queryLabels))
if err != nil {
- l.Error(err, "failed to get update request for the resource", "kind", urSpec.Resource.Kind, "name", urSpec.Resource.Name, "namespace", urSpec.Resource.Namespace)
+ l.Error(err, "failed to get update request for the resource", "resource", urSpec.GetResource().String())
return err
}
for _, v := range urList {
|