From 69f52b987922aea59f6b30a2f07a8857a4951b0c Mon Sep 17 00:00:00 2001
From: "gcp-cherry-pick-bot[bot]"
<98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com>
Date: Tue, 19 Dec 2023 10:51:47 +0000
Subject: [PATCH] fix: add `skipBackgoundRequests` to configure loop protection
option (#9157) (#9207)
* fix typo
* add new attribute skipBackgroundRequests
* move to per rule config
* check flag
* clean up
* update docs
* fix logger
* add retryCount to ur.status
* add chainsaw tests
---------
Signed-off-by: ShutingZhao
Co-authored-by: shuting
---
api/kyverno/v1/rule_types.go | 7 +
api/kyverno/v1beta1/updaterequest_types.go | 2 +
api/kyverno/v2beta1/rule_types.go | 7 +
.../kyverno/charts/crds/templates/crds.yaml | 58 +++++
.../data/crds/kyverno.io_clusterpolicies.yaml | 28 +++
.../data/crds/kyverno.io_policies.yaml | 28 +++
config/crds/kyverno.io_clusterpolicies.yaml | 28 +++
config/crds/kyverno.io_policies.yaml | 28 +++
config/crds/kyverno.io_updaterequests.yaml | 2 +
config/install-latest-testing.yaml | 58 +++++
docs/user/crd/index.html | 36 ++++
pkg/background/common/util.go | 52 +----
pkg/background/generate/generate.go | 30 ++-
pkg/background/mutate/mutate.go | 10 +-
.../applyconfigurations/kyverno/v1/rule.go | 31 ++-
.../kyverno/v1beta1/updaterequeststatus.go | 9 +
.../kyverno/v2beta1/rule.go | 31 ++-
pkg/webhooks/policy/handlers.go | 6 +-
pkg/webhooks/resource/handlers.go | 6 +-
pkg/webhooks/resource/updaterequest.go | 14 +-
pkg/webhooks/resource/utils.go | 13 ++
.../README.md | 11 +
.../chainsaw-step-01-apply-1-1.yaml | 198 ++++++++++++++++++
.../chainsaw-step-01-assert-1-1.yaml | 9 +
.../chainsaw-step-02-apply-1-1.yaml | 13 ++
.../chainsaw-step-02-assert-1-1.yaml | 28 +++
.../chainsaw-test.yaml | 19 ++
.../README.md | 11 +
.../chainsaw-step-01-apply-1-1.yaml | 198 ++++++++++++++++++
.../chainsaw-step-01-assert-1-1.yaml | 9 +
.../chainsaw-step-02-apply-1-1.yaml | 13 ++
.../chainsaw-step-02-assert-1-1.yaml | 14 ++
.../chainsaw-step-02-error-1-1.yaml | 5 +
.../chainsaw-test.yaml | 21 ++
.../new.yaml | 13 ++
35 files changed, 958 insertions(+), 88 deletions(-)
create mode 100644 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/README.md
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-test.yaml
create mode 100644 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/README.md
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-error-1-1.yaml
create mode 100755 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-test.yaml
create mode 100644 test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/new.yaml
diff --git a/api/kyverno/v1/rule_types.go b/api/kyverno/v1/rule_types.go
index c0d26db287..82cc0e8850 100644
--- a/api/kyverno/v1/rule_types.go
+++ b/api/kyverno/v1/rule_types.go
@@ -98,6 +98,13 @@ type Rule struct {
// VerifyImages is used to verify image signatures and mutate them to add a digest
// +optional
VerifyImages []ImageVerification `json:"verifyImages,omitempty" yaml:"verifyImages,omitempty"`
+
+ // SkipBackgroundRequests bypasses admission requests that are sent by the background controller.
+ // The default value is set to "true", it must be set to "false" to apply
+ // generate and mutateExisting rules to those requests.
+ // +kubebuilder:default=true
+ // +kubebuilder:validation:Optional
+ SkipBackgroundRequests bool `json:"skipBackgroundRequests,omitempty" yaml:"skipBackgroundRequests,omitempty"`
}
// HasMutate checks for mutate rule
diff --git a/api/kyverno/v1beta1/updaterequest_types.go b/api/kyverno/v1beta1/updaterequest_types.go
index fa0987f3d2..a5a07e8cd7 100644
--- a/api/kyverno/v1beta1/updaterequest_types.go
+++ b/api/kyverno/v1beta1/updaterequest_types.go
@@ -38,6 +38,8 @@ type UpdateRequestStatus struct {
// This will track the resources that are updated by the generate Policy.
// Will be used during clean up resources.
GeneratedResources []kyvernov1.ResourceSpec `json:"generatedResources,omitempty" yaml:"generatedResources,omitempty"`
+
+ RetryCount int `json:"retryCount,omitempty" yaml:"retryCount,omitempty"`
}
// +genclient
diff --git a/api/kyverno/v2beta1/rule_types.go b/api/kyverno/v2beta1/rule_types.go
index 5b76ef96e1..e956288acb 100644
--- a/api/kyverno/v2beta1/rule_types.go
+++ b/api/kyverno/v2beta1/rule_types.go
@@ -65,6 +65,13 @@ type Rule struct {
// VerifyImages is used to verify image signatures and mutate them to add a digest
// +optional
VerifyImages []ImageVerification `json:"verifyImages,omitempty" yaml:"verifyImages,omitempty"`
+
+ // SkipBackgroundRequests bypasses admission requests that are sent by the background controller.
+ // The default value is set to "true", it must be set to "false" to apply
+ // generate and mutateExisting rules to those requests.
+ // +kubebuilder:default=true
+ // +kubebuilder:validation:Optional
+ SkipBackgroundRequests bool `json:"skipBackgroundRequests,omitempty" yaml:"skipBackgroundRequests,omitempty"`
}
// HasMutate checks for mutate rule
diff --git a/charts/kyverno/charts/crds/templates/crds.yaml b/charts/kyverno/charts/crds/templates/crds.yaml
index b55666c232..4defa2ad27 100644
--- a/charts/kyverno/charts/crds/templates/crds.yaml
+++ b/charts/kyverno/charts/crds/templates/crds.yaml
@@ -8706,6 +8706,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -13140,6 +13147,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -17356,6 +17370,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -21856,6 +21877,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -26438,6 +26466,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -30873,6 +30908,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -35090,6 +35132,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -39590,6 +39639,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -43177,6 +43233,8 @@ spec:
message:
description: Specifies request status message.
type: string
+ retryCount:
+ type: integer
state:
description: State represents state of the update request.
type: string
diff --git a/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_clusterpolicies.yaml b/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_clusterpolicies.yaml
index 13ed761c4d..8f0fea113c 100644
--- a/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_clusterpolicies.yaml
+++ b/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_clusterpolicies.yaml
@@ -2410,6 +2410,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -6844,6 +6851,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -11060,6 +11074,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -15560,6 +15581,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
diff --git a/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policies.yaml b/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policies.yaml
index 656e9e423f..cf03f69018 100644
--- a/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policies.yaml
+++ b/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policies.yaml
@@ -2411,6 +2411,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -6846,6 +6853,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -11063,6 +11077,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -15563,6 +15584,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml
index 13ed761c4d..8f0fea113c 100644
--- a/config/crds/kyverno.io_clusterpolicies.yaml
+++ b/config/crds/kyverno.io_clusterpolicies.yaml
@@ -2410,6 +2410,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -6844,6 +6851,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -11060,6 +11074,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -15560,6 +15581,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml
index 656e9e423f..cf03f69018 100644
--- a/config/crds/kyverno.io_policies.yaml
+++ b/config/crds/kyverno.io_policies.yaml
@@ -2411,6 +2411,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -6846,6 +6853,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -11063,6 +11077,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -15563,6 +15584,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
diff --git a/config/crds/kyverno.io_updaterequests.yaml b/config/crds/kyverno.io_updaterequests.yaml
index f1ed657058..c1ff4500e2 100644
--- a/config/crds/kyverno.io_updaterequests.yaml
+++ b/config/crds/kyverno.io_updaterequests.yaml
@@ -392,6 +392,8 @@ spec:
message:
description: Specifies request status message.
type: string
+ retryCount:
+ type: integer
state:
description: State represents state of the update request.
type: string
diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml
index dc1a914b2d..86c3624108 100644
--- a/config/install-latest-testing.yaml
+++ b/config/install-latest-testing.yaml
@@ -8925,6 +8925,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -13359,6 +13366,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -17575,6 +17589,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -22075,6 +22096,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -26659,6 +26687,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -31094,6 +31129,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -35311,6 +35353,13 @@ spec:
type: object
type: array
type: object
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default value
+ is set to "true", it must be set to "false" to apply generate
+ and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -39811,6 +39860,13 @@ spec:
is supported for backwards compatibility but will be deprecated
in the next major release. See: https://kyverno.io/docs/writing-policies/preconditions/'
x-kubernetes-preserve-unknown-fields: true
+ skipBackgroundRequests:
+ default: true
+ description: SkipBackgroundRequests bypasses admission requests
+ that are sent by the background controller. The default
+ value is set to "true", it must be set to "false" to apply
+ generate and mutateExisting rules to those requests.
+ type: boolean
validate:
description: Validation is used to validate matching resources.
properties:
@@ -43402,6 +43458,8 @@ spec:
message:
description: Specifies request status message.
type: string
+ retryCount:
+ type: integer
state:
description: State represents state of the update request.
type: string
diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html
index 44496d6a4a..52bf1f66f2 100644
--- a/docs/user/crd/index.html
+++ b/docs/user/crd/index.html
@@ -3496,6 +3496,19 @@ Generation
VerifyImages is used to verify image signatures and mutate them to add a digest
+
+
+skipBackgroundRequests
+
+bool
+
+ |
+
+ SkipBackgroundRequests bypasses admission requests that are sent by the background controller.
+The default value is set to “true”, it must be set to “false” to apply
+generate and mutateExisting rules to those requests.
+ |
+
@@ -5411,6 +5424,16 @@ string
Will be used during clean up resources.
+
+
+retryCount
+
+int
+
+ |
+
+ |
+
@@ -7739,6 +7762,19 @@ Generation
VerifyImages is used to verify image signatures and mutate them to add a digest
+
+
+skipBackgroundRequests
+
+bool
+
+ |
+
+ SkipBackgroundRequests bypasses admission requests that are sent by the background controller.
+The default value is set to “true”, it must be set to “false” to apply
+generate and mutateExisting rules to those requests.
+ |
+
diff --git a/pkg/background/common/util.go b/pkg/background/common/util.go
index 2b5663791d..3a9db924d0 100644
--- a/pkg/background/common/util.go
+++ b/pkg/background/common/util.go
@@ -2,8 +2,6 @@ package common
import (
"context"
- "fmt"
- "strconv"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
@@ -30,6 +28,11 @@ func UpdateStatus(client versioned.Interface, urLister kyvernov1beta1listers.Upd
latest.Status.GeneratedResources = genResources
}
+ if state == kyvernov1beta1.Failed {
+ if latest, err = retryOrDeleteOnFailure(client, latest, 3); err != nil {
+ return nil, err
+ }
+ }
new, err := client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), latest, metav1.UpdateOptions{})
if err != nil {
return ur, errors.Wrapf(err, "failed to update ur status to %s", string(state))
@@ -56,50 +59,17 @@ func ResourceSpecFromUnstructured(obj unstructured.Unstructured) kyvernov1.Resou
}
}
-func increaseRetryAnnotation(ur *kyvernov1beta1.UpdateRequest) (int, map[string]string, error) {
- urAnnotations := ur.Annotations
- if len(urAnnotations) == 0 {
- urAnnotations = map[string]string{
- kyvernov1beta1.URGenerateRetryCountAnnotation: "1",
- }
- }
-
- retry := 1
- val, ok := urAnnotations[kyvernov1beta1.URGenerateRetryCountAnnotation]
- if !ok {
- urAnnotations[kyvernov1beta1.URGenerateRetryCountAnnotation] = "1"
- } else {
- retryUint, err := strconv.ParseUint(val, 10, 64)
- if err != nil {
- return retry, urAnnotations, fmt.Errorf("unable to convert retry-count %v: %w", val, err)
- }
- retry = int(retryUint)
- retry += 1
- incrementedRetryString := strconv.Itoa(retry)
- urAnnotations[kyvernov1beta1.URGenerateRetryCountAnnotation] = incrementedRetryString
- }
-
- return retry, urAnnotations, nil
-}
-
-func UpdateRetryAnnotation(kyvernoClient versioned.Interface, ur *kyvernov1beta1.UpdateRequest) error {
- retry, urAnnotations, err := increaseRetryAnnotation(ur)
- if err != nil {
- return err
- }
- if retry > 3 {
+func retryOrDeleteOnFailure(kyvernoClient versioned.Interface, ur *kyvernov1beta1.UpdateRequest, limit int) (latest *kyvernov1beta1.UpdateRequest, err error) {
+ if ur.Status.RetryCount > limit {
err = kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Delete(context.TODO(), ur.GetName(), metav1.DeleteOptions{})
if err != nil {
- return errors.Wrapf(err, "exceeds retry limit, failed to delete the UR: %s, retry: %v, resourceVersion: %s", ur.Name, retry, ur.GetResourceVersion())
+ return nil, errors.Wrapf(err, "exceeds retry limit, failed to delete the UR: %s, retry: %v, resourceVersion: %s", ur.Name, ur.Status.RetryCount, ur.GetResourceVersion())
}
} else {
- ur.SetAnnotations(urAnnotations)
- _, err = kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Update(context.TODO(), ur, metav1.UpdateOptions{})
- if err != nil {
- return errors.Wrapf(err, "failed to update annotation in update request: %s for the resource, retry: %v, resourceVersion %s, annotations: %v", ur.Name, retry, ur.GetResourceVersion(), urAnnotations)
- }
+ ur.Status.RetryCount++
}
- return nil
+
+ return ur, nil
}
func FindDownstream(client dclient.Interface, apiVersion, kind string, labels map[string]string) (*unstructured.UnstructuredList, error) {
diff --git a/pkg/background/generate/generate.go b/pkg/background/generate/generate.go
index 21b96f1ab0..5f56f06cbe 100644
--- a/pkg/background/generate/generate.go
+++ b/pkg/background/generate/generate.go
@@ -22,6 +22,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
+ "github.com/kyverno/kyverno/pkg/engine/validate"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/event"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
@@ -100,9 +101,10 @@ func (c *GenerateController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
trigger, err := c.getTrigger(ur.Spec)
if err != nil {
logger.V(3).Info("the trigger resource does not exist or is pending creation, re-queueing", "details", err.Error())
- if err := common.UpdateRetryAnnotation(c.kyvernoClient, ur); err != nil {
+ if err := updateStatus(c.statusControl, *ur, err, nil); err != nil {
return err
}
+ return nil
}
if trigger == nil {
@@ -112,19 +114,27 @@ func (c *GenerateController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
namespaceLabels := engineutils.GetNamespaceSelectorsFromNamespaceLister(trigger.GetKind(), trigger.GetNamespace(), c.nsLister, logger)
genResources, err = c.applyGenerate(*trigger, *ur, namespaceLabels)
if err != nil {
- // Need not update the status when policy doesn't apply on resource, because all the update requests are removed by the cleanup controller
if strings.Contains(err.Error(), doesNotApply) {
- logger.V(4).Info("skipping updating status of update request")
- return nil
+ ur.Status.State = kyvernov1beta1.Completed
+ logger.V(4).Info(fmt.Sprintf("%s, updating UR status to Completed", err.Error()))
+ _, err := c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), ur, metav1.UpdateOptions{})
+ return err
+ }
+
+ policy, err := c.getPolicySpec(*ur)
+ if err != nil {
+ return err
}
- policy, _ := c.getPolicySpec(*ur)
events := event.NewBackgroundFailedEvent(err, policy, ur.Spec.Rule, event.GeneratePolicyController,
kyvernov1.ResourceSpec{Kind: trigger.GetKind(), Namespace: trigger.GetNamespace(), Name: trigger.GetName()})
c.eventGen.Add(events...)
}
- return updateStatus(c.statusControl, *ur, err, genResources)
+ if err = updateStatus(c.statusControl, *ur, err, genResources); err != nil {
+ return err
+ }
+ return err
}
const doesNotApply = "policy does not apply to resource"
@@ -365,8 +375,7 @@ func (c *GenerateController) ApplyGeneratePolicy(log logr.Logger, policyContext
genResource, err = applyRule(log, c.client, rule, resource, jsonContext, policy, ur)
if err != nil {
- log.Error(err, "failed to apply generate rule", "policy", policy.GetName(),
- "rule", rule.Name, "resource", resource.GetName(), "suggestion", "users need to grant Kyverno's service account additional privileges")
+ log.Error(err, "failed to apply generate rule", "policy", policy.GetName(), "rule", rule.Name, "resource", resource.GetName())
return nil, err
}
ruleNameToProcessingTime[rule.Name] = time.Since(startTime)
@@ -452,6 +461,11 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyvernov1.Rule, t
} else {
if !rule.Generation.Synchronize {
logger.V(4).Info("synchronize disabled, skip syncing changes")
+ continue
+ }
+ if err := validate.MatchPattern(logger, generatedObj.Object, newResource.Object); err == nil {
+ logger.V(4).Info("patterns match, skipping updates")
+ continue
}
logger.V(4).Info("updating existing resource")
if targetMeta.GetAPIVersion() == "" {
diff --git a/pkg/background/mutate/mutate.go b/pkg/background/mutate/mutate.go
index 90dfdf36f9..281b5d659b 100644
--- a/pkg/background/mutate/mutate.go
+++ b/pkg/background/mutate/mutate.go
@@ -97,9 +97,8 @@ func (c *mutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
trigger, err = common.GetResource(c.client, ur.Spec, c.log)
if err != nil || trigger == nil {
logger.WithName(rule.Name).Error(err, "failed to get trigger resource")
- errs = append(errs, err)
- if err := common.UpdateRetryAnnotation(c.kyvernoClient, ur); err != nil {
- errs = append(errs, err)
+ if err := updateURStatus(c.statusControl, *ur, err); err != nil {
+ return err
}
continue
}
@@ -109,9 +108,8 @@ func (c *mutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
if err != nil || trigger == nil {
if admissionRequest.SubResource == "" {
logger.WithName(rule.Name).Error(err, "failed to get trigger resource")
- errs = append(errs, err)
- if err := common.UpdateRetryAnnotation(c.kyvernoClient, ur); err != nil {
- errs = append(errs, err)
+ if err := updateURStatus(c.statusControl, *ur, err); err != nil {
+ return err
}
continue
} else {
diff --git a/pkg/client/applyconfigurations/kyverno/v1/rule.go b/pkg/client/applyconfigurations/kyverno/v1/rule.go
index cd21d724e9..dbf9f622bf 100644
--- a/pkg/client/applyconfigurations/kyverno/v1/rule.go
+++ b/pkg/client/applyconfigurations/kyverno/v1/rule.go
@@ -27,17 +27,18 @@ import (
// RuleApplyConfiguration represents an declarative configuration of the Rule type for use
// with apply.
type RuleApplyConfiguration struct {
- Name *string `json:"name,omitempty"`
- Context []ContextEntryApplyConfiguration `json:"context,omitempty"`
- MatchResources *MatchResourcesApplyConfiguration `json:"match,omitempty"`
- ExcludeResources *MatchResourcesApplyConfiguration `json:"exclude,omitempty"`
- ImageExtractors *kyvernov1.ImageExtractorConfigs `json:"imageExtractors,omitempty"`
- RawAnyAllConditions *apiextensionsv1.JSON `json:"preconditions,omitempty"`
- CELPreconditions []v1alpha1.MatchCondition `json:"celPreconditions,omitempty"`
- Mutation *MutationApplyConfiguration `json:"mutate,omitempty"`
- Validation *ValidationApplyConfiguration `json:"validate,omitempty"`
- Generation *GenerationApplyConfiguration `json:"generate,omitempty"`
- VerifyImages []ImageVerificationApplyConfiguration `json:"verifyImages,omitempty"`
+ Name *string `json:"name,omitempty"`
+ Context []ContextEntryApplyConfiguration `json:"context,omitempty"`
+ MatchResources *MatchResourcesApplyConfiguration `json:"match,omitempty"`
+ ExcludeResources *MatchResourcesApplyConfiguration `json:"exclude,omitempty"`
+ ImageExtractors *kyvernov1.ImageExtractorConfigs `json:"imageExtractors,omitempty"`
+ RawAnyAllConditions *apiextensionsv1.JSON `json:"preconditions,omitempty"`
+ CELPreconditions []v1alpha1.MatchCondition `json:"celPreconditions,omitempty"`
+ Mutation *MutationApplyConfiguration `json:"mutate,omitempty"`
+ Validation *ValidationApplyConfiguration `json:"validate,omitempty"`
+ Generation *GenerationApplyConfiguration `json:"generate,omitempty"`
+ VerifyImages []ImageVerificationApplyConfiguration `json:"verifyImages,omitempty"`
+ SkipBackgroundRequests *bool `json:"skipBackgroundRequests,omitempty"`
}
// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with
@@ -145,3 +146,11 @@ func (b *RuleApplyConfiguration) WithVerifyImages(values ...*ImageVerificationAp
}
return b
}
+
+// WithSkipBackgroundRequests sets the SkipBackgroundRequests field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the SkipBackgroundRequests field is set to the value of the last call.
+func (b *RuleApplyConfiguration) WithSkipBackgroundRequests(value bool) *RuleApplyConfiguration {
+ b.SkipBackgroundRequests = &value
+ return b
+}
diff --git a/pkg/client/applyconfigurations/kyverno/v1beta1/updaterequeststatus.go b/pkg/client/applyconfigurations/kyverno/v1beta1/updaterequeststatus.go
index 9d9fa62ced..f618029624 100644
--- a/pkg/client/applyconfigurations/kyverno/v1beta1/updaterequeststatus.go
+++ b/pkg/client/applyconfigurations/kyverno/v1beta1/updaterequeststatus.go
@@ -30,6 +30,7 @@ type UpdateRequestStatusApplyConfiguration struct {
State *v1beta1.UpdateRequestState `json:"state,omitempty"`
Message *string `json:"message,omitempty"`
GeneratedResources []v1.ResourceSpecApplyConfiguration `json:"generatedResources,omitempty"`
+ RetryCount *int `json:"retryCount,omitempty"`
}
// UpdateRequestStatusApplyConfiguration constructs an declarative configuration of the UpdateRequestStatus type for use with
@@ -74,3 +75,11 @@ func (b *UpdateRequestStatusApplyConfiguration) WithGeneratedResources(values ..
}
return b
}
+
+// WithRetryCount sets the RetryCount field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the RetryCount field is set to the value of the last call.
+func (b *UpdateRequestStatusApplyConfiguration) WithRetryCount(value int) *UpdateRequestStatusApplyConfiguration {
+ b.RetryCount = &value
+ return b
+}
diff --git a/pkg/client/applyconfigurations/kyverno/v2beta1/rule.go b/pkg/client/applyconfigurations/kyverno/v2beta1/rule.go
index a0de73193c..2fe65b89d0 100644
--- a/pkg/client/applyconfigurations/kyverno/v2beta1/rule.go
+++ b/pkg/client/applyconfigurations/kyverno/v2beta1/rule.go
@@ -27,17 +27,18 @@ import (
// RuleApplyConfiguration represents an declarative configuration of the Rule type for use
// with apply.
type RuleApplyConfiguration struct {
- Name *string `json:"name,omitempty"`
- Context []v1.ContextEntryApplyConfiguration `json:"context,omitempty"`
- MatchResources *MatchResourcesApplyConfiguration `json:"match,omitempty"`
- ExcludeResources *MatchResourcesApplyConfiguration `json:"exclude,omitempty"`
- ImageExtractors *kyvernov1.ImageExtractorConfigs `json:"imageExtractors,omitempty"`
- RawAnyAllConditions *AnyAllConditionsApplyConfiguration `json:"preconditions,omitempty"`
- CELPreconditions []admissionregistrationv1.MatchCondition `json:"celPreconditions,omitempty"`
- Mutation *v1.MutationApplyConfiguration `json:"mutate,omitempty"`
- Validation *ValidationApplyConfiguration `json:"validate,omitempty"`
- Generation *v1.GenerationApplyConfiguration `json:"generate,omitempty"`
- VerifyImages []ImageVerificationApplyConfiguration `json:"verifyImages,omitempty"`
+ Name *string `json:"name,omitempty"`
+ Context []v1.ContextEntryApplyConfiguration `json:"context,omitempty"`
+ MatchResources *MatchResourcesApplyConfiguration `json:"match,omitempty"`
+ ExcludeResources *MatchResourcesApplyConfiguration `json:"exclude,omitempty"`
+ ImageExtractors *kyvernov1.ImageExtractorConfigs `json:"imageExtractors,omitempty"`
+ RawAnyAllConditions *AnyAllConditionsApplyConfiguration `json:"preconditions,omitempty"`
+ CELPreconditions []admissionregistrationv1.MatchCondition `json:"celPreconditions,omitempty"`
+ Mutation *v1.MutationApplyConfiguration `json:"mutate,omitempty"`
+ Validation *ValidationApplyConfiguration `json:"validate,omitempty"`
+ Generation *v1.GenerationApplyConfiguration `json:"generate,omitempty"`
+ VerifyImages []ImageVerificationApplyConfiguration `json:"verifyImages,omitempty"`
+ SkipBackgroundRequests *bool `json:"skipBackgroundRequests,omitempty"`
}
// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with
@@ -145,3 +146,11 @@ func (b *RuleApplyConfiguration) WithVerifyImages(values ...*ImageVerificationAp
}
return b
}
+
+// WithSkipBackgroundRequests sets the SkipBackgroundRequests field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the SkipBackgroundRequests field is set to the value of the last call.
+func (b *RuleApplyConfiguration) WithSkipBackgroundRequests(value bool) *RuleApplyConfiguration {
+ b.SkipBackgroundRequests = &value
+ return b
+}
diff --git a/pkg/webhooks/policy/handlers.go b/pkg/webhooks/policy/handlers.go
index e05199eff5..e2d0b1dece 100644
--- a/pkg/webhooks/policy/handlers.go
+++ b/pkg/webhooks/policy/handlers.go
@@ -14,13 +14,13 @@ import (
type policyHandlers struct {
client dclient.Interface
- backgroungServiceAccountName string
+ backgroundServiceAccountName string
}
func NewHandlers(client dclient.Interface, serviceaccount string) webhooks.PolicyHandlers {
return &policyHandlers{
client: client,
- backgroungServiceAccountName: serviceaccount,
+ backgroundServiceAccountName: serviceaccount,
}
}
@@ -30,7 +30,7 @@ func (h *policyHandlers) Validate(ctx context.Context, logger logr.Logger, reque
logger.Error(err, "failed to unmarshal policies from admission request")
return admissionutils.Response(request.UID, err)
}
- warnings, err := policyvalidate.Validate(policy, oldPolicy, h.client, false, h.backgroungServiceAccountName)
+ warnings, err := policyvalidate.Validate(policy, oldPolicy, h.client, false, h.backgroundServiceAccountName)
if err != nil {
logger.Error(err, "policy validation errors")
}
diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go
index 499cb11dd2..cac3653da3 100644
--- a/pkg/webhooks/resource/handlers.go
+++ b/pkg/webhooks/resource/handlers.go
@@ -56,7 +56,7 @@ type resourceHandlers struct {
pcBuilder webhookutils.PolicyContextBuilder
admissionReports bool
- backgroungServiceAccountName string
+ backgroundServiceAccountName string
}
func NewHandlers(
@@ -73,7 +73,7 @@ func NewHandlers(
urGenerator webhookgenerate.Generator,
eventGen event.Interface,
admissionReports bool,
- backgroungServiceAccountName string,
+ backgroundServiceAccountName string,
jp jmespath.Interface,
) webhooks.ResourceHandlers {
return &resourceHandlers{
@@ -91,7 +91,7 @@ func NewHandlers(
eventGen: eventGen,
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, jp),
admissionReports: admissionReports,
- backgroungServiceAccountName: backgroungServiceAccountName,
+ backgroundServiceAccountName: backgroundServiceAccountName,
}
}
diff --git a/pkg/webhooks/resource/updaterequest.go b/pkg/webhooks/resource/updaterequest.go
index 3b037f76c7..e3a34175eb 100644
--- a/pkg/webhooks/resource/updaterequest.go
+++ b/pkg/webhooks/resource/updaterequest.go
@@ -17,9 +17,6 @@ import (
// handleBackgroundApplies applies generate and mutateExisting policies, and creates update requests for background reconcile
func (h *resourceHandlers) handleBackgroundApplies(ctx context.Context, logger logr.Logger, request admissionv1.AdmissionRequest, policyContext *engine.PolicyContext, generatePolicies, mutatePolicies []kyvernov1.PolicyInterface, ts time.Time) {
- if h.backgroungServiceAccountName == policyContext.AdmissionInfo().AdmissionUserInfo.Username {
- return
- }
go h.handleMutateExisting(ctx, logger, request, mutatePolicies, policyContext, ts)
h.handleGenerate(ctx, logger, request, generatePolicies, policyContext, ts)
}
@@ -34,10 +31,12 @@ func (h *resourceHandlers) handleMutateExisting(ctx context.Context, logger logr
if !policy.GetSpec().IsMutateExisting() {
continue
}
+
+ policyNew := skipBackgroundRequests(policy, logger, h.backgroundServiceAccountName, policyContext.AdmissionInfo().AdmissionUserInfo.Username)
logger.V(4).Info("update request for mutateExisting policy")
var rules []engineapi.RuleResponse
- policyContext := policyContext.WithPolicy(policy)
+ policyContext := policyContext.WithPolicy(policyNew)
engineResponse := h.engine.ApplyBackgroundChecks(ctx, policyContext)
for _, rule := range engineResponse.PolicyResponse.Rules {
@@ -73,5 +72,10 @@ func (h *resourceHandlers) handleMutateExisting(ctx context.Context, logger logr
func (h *resourceHandlers) handleGenerate(ctx context.Context, logger logr.Logger, request admissionv1.AdmissionRequest, generatePolicies []kyvernov1.PolicyInterface, policyContext *engine.PolicyContext, ts time.Time) {
gh := generation.NewGenerationHandler(logger, h.engine, h.client, h.kyvernoClient, h.nsLister, h.urLister, h.cpolLister, h.polLister, h.urGenerator, h.eventGen, h.metricsConfig)
- go gh.Handle(ctx, request, generatePolicies, policyContext)
+ var policies []kyvernov1.PolicyInterface
+ for _, p := range generatePolicies {
+ new := skipBackgroundRequests(p, logger, h.backgroundServiceAccountName, policyContext.AdmissionInfo().AdmissionUserInfo.Username)
+ policies = append(policies, new)
+ }
+ go gh.Handle(ctx, request, policies, policyContext)
}
diff --git a/pkg/webhooks/resource/utils.go b/pkg/webhooks/resource/utils.go
index cdcedd0e63..c7008f2f0b 100644
--- a/pkg/webhooks/resource/utils.go
+++ b/pkg/webhooks/resource/utils.go
@@ -100,3 +100,16 @@ func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, u
return urs
}
+
+func skipBackgroundRequests(policy kyvernov1.PolicyInterface, logger logr.Logger, bgsaDesired, bgsaActual string) kyvernov1.PolicyInterface {
+ policyNew := policy.CreateDeepCopy()
+ policyNew.GetSpec().Rules = nil
+ for _, rule := range policy.GetSpec().Rules {
+ if rule.SkipBackgroundRequests && (bgsaDesired == bgsaActual) {
+ continue
+ }
+ logger.V(4).Info("applying background rule", "rule", rule.Name, "skipBackgroundRequests", rule.SkipBackgroundRequests, "backgroundSaDesired", bgsaDesired, "backgroundSaActual", bgsaActual)
+ policyNew.GetSpec().Rules = append(policyNew.GetSpec().Rules, *rule.DeepCopy())
+ }
+ return policyNew
+}
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/README.md b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/README.md
new file mode 100644
index 0000000000..49b9a456d2
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/README.md
@@ -0,0 +1,11 @@
+## Description
+
+This test checks the generate rule to be applied on Kyverno generated resources when `skipBackgroundRequests` is disabled.
+
+## Expected Behavior
+
+The serviceaccount is created when Kyverno creates a new secret.
+
+## Reference Issue(s)
+
+https://github.com/kyverno/kyverno/issues/9131
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml
new file mode 100755
index 0000000000..5dea128479
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml
@@ -0,0 +1,198 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: background-controller
+ app.kubernetes.io/instance: kyverno
+ app.kubernetes.io/part-of: kyverno
+ name: kyverno:background-controller:additional
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - ""
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+ - get
+ - list
+- apiGroups:
+ - ""
+ resources:
+ - serviceaccounts
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: cpol-data-sync-create-upon-generated-resource
+spec:
+ rules:
+ - generate:
+ apiVersion: v1
+ data:
+ kind: Secret
+ metadata:
+ name: otel-collector-signalfx-config
+ stringData:
+ otel-collector-signalfx-config: |
+ service:
+ extensions:
+ - health_check
+ - http_forwarder
+ pipelines:
+ metrics:
+ receivers:
+ # but actually, it's a scraper
+ - prometheus
+ processors:
+ - batch
+ - metricstransform
+ - k8sattributes
+ - resourcedetection
+ exporters:
+ - signalfx
+ - logging
+ telemetry:
+ metrics:
+ address: 0.0.0.0:8888
+ receivers:
+ prometheus:
+ config:
+ scrape_configs:
+ - job_name: k8s
+ kubernetes_sd_configs:
+ - role: pod
+ namespaces:
+ own_namespace: true
+ # todo: needs to be replaced by Kyverno
+ relabel_configs:
+ # Only keep the discovered targets that has the label otel.collector.signalfx/scrape
+ # Only keep the discovered targets that has the label otel.collector.signalfx/scrape
+ - action: keep
+ regex: "true"
+ source_labels:
+ - __meta_kubernetes_pod_label_otel_collector_signalfx_scrape
+ # Add
+ - action: replace
+ regex: ([^:]+)(?::\d+)?;(\d+)
+ replacement: $$1:$$2
+ source_labels:
+ - __address__
+ - __meta_kubernetes_pod_label_otel_collector_signalfx_port
+ target_label: __address__
+ - action: replace
+ regex: (.+)
+ source_labels:
+ - __meta_kubernetes_pod_annotation_otel_collector_signalfx_metric_path
+ target_label: __metrics_path__
+ - action: replace
+ regex: (.*)-.*-.*$
+ source_labels:
+ - __meta_kubernetes_pod_name
+ target_label: deployment
+ - action: replace
+ source_labels:
+ - __meta_kubernetes_namespace
+ target_label: kubernetes_namespace
+ - action: replace
+ source_labels:
+ - __meta_kubernetes_pod_name
+ target_label: kubernetes_pod_name
+ - action: replace
+ source_labels:
+ - __meta_kubernetes_pod_container_name
+ target_label: kubernetes_container_name
+ scrape_interval: 10s
+ # Process the datapoints, enrich with more labels
+ processors:
+ attributes/newenvironment:
+ actions:
+ - action: insert
+ key: environment
+ value: managed-gke-dev
+ batch: {}
+ k8sattributes:
+ extract:
+ metadata:
+ - podName
+ - podUID
+ - namespace
+ - cluster
+ - node
+ passthrough: false
+ filter:
+ namespace: "{{request.object.metadata.namespace}}"
+ memory_limiter:
+ check_interval: 5s
+ limit_mib: 1638
+ spike_limit_mib: 512
+ metricstransform:
+ transforms:
+ - action: update
+ include: .*
+ match_type: regexp
+ operations:
+ - action: add_label
+ new_label: metric_source
+ new_value: managed_gke
+ - action: add_label
+ new_label: managed_gke
+ new_value: "true"
+ - action: add_label
+ new_label: kubernetes_cluster
+ new_value: ccoe-europe-west4-dev-1
+ resourcedetection:
+ detectors:
+ - system
+ override: true
+ exporters:
+ signalfx:
+ access_token: "{{request.object.data.auth_token | base64_decode(@) || 'BACKGROUND'}}"
+ access_token_passthrough: true
+ realm: eu0
+ logging:
+ loglevel: info
+ extensions:
+ health_check:
+ endpoint: 0.0.0.0:13133
+ http_forwarder:
+ egress:
+ endpoint: https://api.eu0.signalfx.com
+ memory_ballast: {}
+ zpages: null
+ type: Opaque
+ kind: Secret
+ name: otel-collector-signalfx-secret
+ namespace: '{{request.object.metadata.namespace}}'
+ synchronize: true
+ match:
+ any:
+ - resources:
+ kinds:
+ - Secret
+ names:
+ - otel-collector-signalfx-token
+ name: generate-otel-secret-config
+ skipBackgroundRequests: true
+ - generate:
+ apiVersion: v1
+ kind: ServiceAccount
+ name: otel-collector-signalfx-sa
+ namespace: '{{request.object.metadata.namespace}}'
+ synchronize: true
+ match:
+ any:
+ - resources:
+ kinds:
+ - Secret
+ names:
+ - otel-collector-signalfx-secret
+ name: generate-otel-sa
+ skipBackgroundRequests: false
\ No newline at end of file
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml
new file mode 100755
index 0000000000..12939cb668
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml
@@ -0,0 +1,9 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: cpol-data-sync-create-upon-generated-resource
+status:
+ conditions:
+ - reason: Succeeded
+ status: "True"
+ type: Ready
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml
new file mode 100755
index 0000000000..5287b994f8
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: cpol-data-sync-create-upon-generated-resource-ns
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: otel-collector-signalfx-token
+ namespace: cpol-data-sync-create-upon-generated-resource-ns
+data:
+ auth_token: YmFy
+type: Opaque
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml
new file mode 100755
index 0000000000..35cad808ce
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml
@@ -0,0 +1,28 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ labels:
+ app.kubernetes.io/managed-by: kyverno
+ generate.kyverno.io/policy-name: cpol-data-sync-create-upon-generated-resource
+ generate.kyverno.io/rule-name: generate-otel-secret-config
+ generate.kyverno.io/trigger-group: ""
+ generate.kyverno.io/trigger-kind: Secret
+ generate.kyverno.io/trigger-namespace: cpol-data-sync-create-upon-generated-resource-ns
+ generate.kyverno.io/trigger-version: v1
+ name: otel-collector-signalfx-secret
+ namespace: cpol-data-sync-create-upon-generated-resource-ns
+type: Opaque
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app.kubernetes.io/managed-by: kyverno
+ generate.kyverno.io/policy-name: cpol-data-sync-create-upon-generated-resource
+ generate.kyverno.io/rule-name: generate-otel-sa
+ generate.kyverno.io/trigger-group: ""
+ generate.kyverno.io/trigger-kind: Secret
+ generate.kyverno.io/trigger-namespace: cpol-data-sync-create-upon-generated-resource-ns
+ generate.kyverno.io/trigger-version: v1
+ name: otel-collector-signalfx-sa
+ namespace: cpol-data-sync-create-upon-generated-resource-ns
\ No newline at end of file
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-test.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-test.yaml
new file mode 100755
index 0000000000..5ffd23bd25
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-create-upon-generated-resource/chainsaw-test.yaml
@@ -0,0 +1,19 @@
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+ creationTimestamp: null
+ name: cpol-data-sync-create
+spec:
+ steps:
+ - name: step-01
+ try:
+ - apply:
+ file: chainsaw-step-01-apply-1-1.yaml
+ - assert:
+ file: chainsaw-step-01-assert-1-1.yaml
+ - name: step-02
+ try:
+ - apply:
+ file: chainsaw-step-02-apply-1-1.yaml
+ - assert:
+ file: chainsaw-step-02-assert-1-1.yaml
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/README.md b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/README.md
new file mode 100644
index 0000000000..14eb96d15a
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/README.md
@@ -0,0 +1,11 @@
+## Description
+
+This test checks the generate rule doesn't apply on Kyverno generated resources when `skipBackgroundRequests` is enabled.
+
+## Expected Behavior
+
+The serviceaccount is not created when Kyverno creates a new secret.
+
+## Reference Issue(s)
+
+https://github.com/kyverno/kyverno/issues/9131
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml
new file mode 100755
index 0000000000..576514409d
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-apply-1-1.yaml
@@ -0,0 +1,198 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/component: background-controller
+ app.kubernetes.io/instance: kyverno
+ app.kubernetes.io/part-of: kyverno
+ name: kyverno:background-controller:additional
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - ""
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+ - get
+ - list
+- apiGroups:
+ - ""
+ resources:
+ - serviceaccounts
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: cpol-data-sync-no-creation-upon-generated-resource
+spec:
+ rules:
+ - generate:
+ apiVersion: v1
+ data:
+ kind: Secret
+ metadata:
+ name: otel-collector-signalfx-config
+ stringData:
+ otel-collector-signalfx-config: |
+ service:
+ extensions:
+ - health_check
+ - http_forwarder
+ pipelines:
+ metrics:
+ receivers:
+ # but actually, it's a scraper
+ - prometheus
+ processors:
+ - batch
+ - metricstransform
+ - k8sattributes
+ - resourcedetection
+ exporters:
+ - signalfx
+ - logging
+ telemetry:
+ metrics:
+ address: 0.0.0.0:8888
+ receivers:
+ prometheus:
+ config:
+ scrape_configs:
+ - job_name: k8s
+ kubernetes_sd_configs:
+ - role: pod
+ namespaces:
+ own_namespace: true
+ # todo: needs to be replaced by Kyverno
+ relabel_configs:
+ # Only keep the discovered targets that has the label otel.collector.signalfx/scrape
+ # Only keep the discovered targets that has the label otel.collector.signalfx/scrape
+ - action: keep
+ regex: "true"
+ source_labels:
+ - __meta_kubernetes_pod_label_otel_collector_signalfx_scrape
+ # Add
+ - action: replace
+ regex: ([^:]+)(?::\d+)?;(\d+)
+ replacement: $$1:$$2
+ source_labels:
+ - __address__
+ - __meta_kubernetes_pod_label_otel_collector_signalfx_port
+ target_label: __address__
+ - action: replace
+ regex: (.+)
+ source_labels:
+ - __meta_kubernetes_pod_annotation_otel_collector_signalfx_metric_path
+ target_label: __metrics_path__
+ - action: replace
+ regex: (.*)-.*-.*$
+ source_labels:
+ - __meta_kubernetes_pod_name
+ target_label: deployment
+ - action: replace
+ source_labels:
+ - __meta_kubernetes_namespace
+ target_label: kubernetes_namespace
+ - action: replace
+ source_labels:
+ - __meta_kubernetes_pod_name
+ target_label: kubernetes_pod_name
+ - action: replace
+ source_labels:
+ - __meta_kubernetes_pod_container_name
+ target_label: kubernetes_container_name
+ scrape_interval: 10s
+ # Process the datapoints, enrich with more labels
+ processors:
+ attributes/newenvironment:
+ actions:
+ - action: insert
+ key: environment
+ value: managed-gke-dev
+ batch: {}
+ k8sattributes:
+ extract:
+ metadata:
+ - podName
+ - podUID
+ - namespace
+ - cluster
+ - node
+ passthrough: false
+ filter:
+ namespace: "{{request.object.metadata.namespace}}"
+ memory_limiter:
+ check_interval: 5s
+ limit_mib: 1638
+ spike_limit_mib: 512
+ metricstransform:
+ transforms:
+ - action: update
+ include: .*
+ match_type: regexp
+ operations:
+ - action: add_label
+ new_label: metric_source
+ new_value: managed_gke
+ - action: add_label
+ new_label: managed_gke
+ new_value: "true"
+ - action: add_label
+ new_label: kubernetes_cluster
+ new_value: ccoe-europe-west4-dev-1
+ resourcedetection:
+ detectors:
+ - system
+ override: true
+ exporters:
+ signalfx:
+ access_token: "{{request.object.data.auth_token | base64_decode(@) || 'BACKGROUND'}}"
+ access_token_passthrough: true
+ realm: eu0
+ logging:
+ loglevel: info
+ extensions:
+ health_check:
+ endpoint: 0.0.0.0:13133
+ http_forwarder:
+ egress:
+ endpoint: https://api.eu0.signalfx.com
+ memory_ballast: {}
+ zpages: null
+ type: Opaque
+ kind: Secret
+ name: otel-collector-signalfx-secret
+ namespace: '{{request.object.metadata.namespace}}'
+ synchronize: true
+ match:
+ any:
+ - resources:
+ kinds:
+ - Secret
+ names:
+ - otel-collector-signalfx-token
+ name: generate-otel-secret-config
+ skipBackgroundRequests: true
+ - generate:
+ apiVersion: v1
+ kind: ServiceAccount
+ name: otel-collector-signalfx-sa
+ namespace: '{{request.object.metadata.namespace}}'
+ synchronize: true
+ match:
+ any:
+ - resources:
+ kinds:
+ - Secret
+ names:
+ - otel-collector-signalfx-secret
+ name: generate-otel-sa
+ skipBackgroundRequests: true
\ No newline at end of file
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml
new file mode 100755
index 0000000000..29c18ddebe
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-01-assert-1-1.yaml
@@ -0,0 +1,9 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: cpol-data-sync-no-creation-upon-generated-resource
+status:
+ conditions:
+ - reason: Succeeded
+ status: "True"
+ type: Ready
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml
new file mode 100755
index 0000000000..dbe4a09012
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-apply-1-1.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: cpol-data-sync-no-creation-upon-generated-resource-ns
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: otel-collector-signalfx-token
+ namespace: cpol-data-sync-no-creation-upon-generated-resource-ns
+data:
+ auth_token: YmFy
+type: Opaque
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml
new file mode 100755
index 0000000000..5ad96d7b11
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-assert-1-1.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ labels:
+ app.kubernetes.io/managed-by: kyverno
+ generate.kyverno.io/policy-name: cpol-data-sync-no-creation-upon-generated-resource
+ generate.kyverno.io/rule-name: generate-otel-secret-config
+ generate.kyverno.io/trigger-group: ""
+ generate.kyverno.io/trigger-kind: Secret
+ generate.kyverno.io/trigger-namespace: cpol-data-sync-no-creation-upon-generated-resource-ns
+ generate.kyverno.io/trigger-version: v1
+ name: otel-collector-signalfx-secret
+ namespace: cpol-data-sync-no-creation-upon-generated-resource-ns
+type: Opaque
\ No newline at end of file
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-error-1-1.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-error-1-1.yaml
new file mode 100755
index 0000000000..554d566d5d
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-step-02-error-1-1.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: otel-collector-signalfx-sa
+ namespace: cpol-data-sync-no-creation-upon-generated-resource-ns
\ No newline at end of file
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-test.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-test.yaml
new file mode 100755
index 0000000000..2f38831512
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/chainsaw-test.yaml
@@ -0,0 +1,21 @@
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+ creationTimestamp: null
+ name: cpol-data-sync-create
+spec:
+ steps:
+ - name: step-01
+ try:
+ - apply:
+ file: chainsaw-step-01-apply-1-1.yaml
+ - assert:
+ file: chainsaw-step-01-assert-1-1.yaml
+ - name: step-02
+ try:
+ - apply:
+ file: chainsaw-step-02-apply-1-1.yaml
+ - assert:
+ file: chainsaw-step-02-assert-1-1.yaml
+ - error:
+ file: chainsaw-step-02-error-1-1.yaml
diff --git a/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/new.yaml b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/new.yaml
new file mode 100644
index 0000000000..6033c78503
--- /dev/null
+++ b/test/conformance/chainsaw/generate/clusterpolicy/cornercases/cpol-data-sync-no-creation-upon-generated-resource/new.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app.kubernetes.io/managed-by: kyverno
+ generate.kyverno.io/policy-name: cpol-data-sync-create-upon-generated-resource
+ generate.kyverno.io/rule-name: generate-otel-sa
+ generate.kyverno.io/trigger-group: ""
+ generate.kyverno.io/trigger-kind: Secret
+ generate.kyverno.io/trigger-namespace: cpol-data-sync-create-upon-generated-resource-ns
+ generate.kyverno.io/trigger-version: v1
+ name: otel-collector-signalfx-sa
+ namespace: cpol-data-sync-create-upon-generated-resource-ns
\ No newline at end of file