1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: the same source cannot be used for multiple targets with a generate clone rule (#7436)

* add source labels to targets

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* handle multiple triggers/targets for the same clone source

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* add source labels to targets

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix test

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* remove unused code

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* add kuttl tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* rename the test

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* add kuttl tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* add kuttl tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* split apiversion label into version and group

Signed-off-by: ShutingZhao <shuting@nirmata.com>

---------

Signed-off-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
shuting 2023-06-07 21:50:47 +08:00 committed by GitHub
parent f20c0ed417
commit 0c3351887a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 542 additions and 99 deletions

View file

@ -1,11 +1,18 @@
package common
const (
GeneratePolicyLabel = "generate.kyverno.io/policy-name"
GeneratePolicyNamespaceLabel = "generate.kyverno.io/policy-namespace"
GenerateRuleLabel = "generate.kyverno.io/rule-name"
GenerateTriggerNameLabel = "generate.kyverno.io/trigger-name"
GenerateTriggerNSLabel = "generate.kyverno.io/trigger-namespace"
GenerateTriggerKindLabel = "generate.kyverno.io/trigger-kind"
GenerateTriggerAPIVersionLabel = "generate.kyverno.io/trigger-apiversion"
GeneratePolicyLabel = "generate.kyverno.io/policy-name"
GeneratePolicyNamespaceLabel = "generate.kyverno.io/policy-namespace"
GenerateRuleLabel = "generate.kyverno.io/rule-name"
GenerateTriggerNameLabel = "generate.kyverno.io/trigger-name"
GenerateTriggerNSLabel = "generate.kyverno.io/trigger-namespace"
GenerateTriggerKindLabel = "generate.kyverno.io/trigger-kind"
GenerateTriggerVersionLabel = "generate.kyverno.io/trigger-version"
GenerateTriggerGroupLabel = "generate.kyverno.io/trigger-group"
GenerateSourceNameLabel = "generate.kyverno.io/source-name"
GenerateSourceNSLabel = "generate.kyverno.io/source-namespace"
GenerateSourceKindLabel = "generate.kyverno.io/source-kind"
GenerateSourceVersionLabel = "generate.kyverno.io/source-version"
GenerateSourceGroupLabel = "generate.kyverno.io/source-group"
GenerateTypeCloneSourceLabel = "generate.kyverno.io/clone-source"
)

View file

@ -21,19 +21,14 @@ type Object interface {
}
func ManageLabels(unstr *unstructured.Unstructured, triggerResource unstructured.Unstructured, policy kyvernov1.PolicyInterface, ruleName string) {
// add managedBY label if not defined
labels := unstr.GetLabels()
if labels == nil {
labels = map[string]string{}
}
// handle managedBy label
managedBy(labels)
PolicyInfo(labels, policy, ruleName)
TriggerInfo(labels, &triggerResource)
// update the labels
TriggerInfo(labels, triggerResource)
unstr.SetLabels(labels)
}
@ -93,13 +88,18 @@ func PolicyInfo(labels map[string]string, policy kyvernov1.PolicyInterface, rule
labels[GenerateRuleLabel] = ruleName
}
func TriggerInfo(labels map[string]string, obj Object) {
labels[GenerateTriggerAPIVersionLabel] = obj.GetAPIVersion()
func TriggerInfo(labels map[string]string, obj unstructured.Unstructured) {
labels[GenerateTriggerVersionLabel] = obj.GroupVersionKind().Version
labels[GenerateTriggerGroupLabel] = obj.GroupVersionKind().Group
labels[GenerateTriggerKindLabel] = obj.GetKind()
labels[GenerateTriggerNSLabel] = obj.GetNamespace()
labels[GenerateTriggerNameLabel] = trimByLength(obj.GetName(), 63)
}
func TagSource(labels map[string]string, obj Object) {
labels[GenerateTypeCloneSourceLabel] = ""
}
func trimByLength(value string, character int) string {
if len(value) > character {
return value[0:character]

View file

@ -55,8 +55,13 @@ func (c *GenerateController) deleteDownstreamForClone(policy kyvernov1.PolicyInt
if ur.Spec.Rule != rule.Name {
continue
}
downstreams, err := FindDownstream(c.client, policy, rule)
labels := map[string]string{
common.GeneratePolicyLabel: policy.GetName(),
common.GeneratePolicyNamespaceLabel: policy.GetNamespace(),
common.GenerateRuleLabel: rule.Name,
kyvernov1.LabelAppManagedBy: kyvernov1.ValueKyvernoApp,
}
downstreams, err := FindDownstream(c.client, rule.Generation.GetAPIVersion(), rule.Generation.GetKind(), labels)
if err != nil {
return err
}

View file

@ -40,11 +40,12 @@ func manageClone(log logr.Logger, target, sourceSpec kyvernov1.ResourceSpec, pol
return newSkipGenerateResponse(nil, target, fmt.Errorf("source resource %s not found: %v", target.String(), err))
}
if err := updateSourceLabel(client, sourceObj, ur.Spec.Resource, policy, rule); err != nil {
if err := updateSourceLabel(client, sourceObj); err != nil {
log.Error(err, "failed to add labels to the source", "kind", sourceObj.GetKind(), "namespace", sourceObj.GetNamespace(), "name", sourceObj.GetName())
}
sourceObjCopy := sourceObj.DeepCopy()
addSourceLabels(sourceObjCopy)
targetObj, err := client.GetResource(context.TODO(), target.GetAPIVersion(), target.GetKind(), target.GetNamespace(), target.GetName())
if err != nil {
if apierrors.IsNotFound(err) && len(ur.Status.GeneratedResources) != 0 && !clone.Synchronize {

View file

@ -3,22 +3,33 @@ package generate
import (
"context"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/background/common"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func updateSourceLabel(client dclient.Interface, source *unstructured.Unstructured, trigger kyvernov1.ResourceSpec, policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) error {
func updateSourceLabel(client dclient.Interface, source *unstructured.Unstructured) error {
labels := source.GetLabels()
if labels == nil {
labels = make(map[string]string)
}
common.PolicyInfo(labels, policy, rule.Name)
common.TriggerInfo(labels, trigger)
common.TagSource(labels, source)
source.SetLabels(labels)
_, err := client.UpdateResource(context.TODO(), source.GetAPIVersion(), source.GetKind(), source.GetNamespace(), source, false)
return err
}
func addSourceLabels(source *unstructured.Unstructured) {
labels := source.GetLabels()
if labels == nil {
labels = make(map[string]string, 4)
}
labels[common.GenerateSourceGroupLabel] = source.GroupVersionKind().Group
labels[common.GenerateSourceVersionLabel] = source.GroupVersionKind().Version
labels[common.GenerateSourceKindLabel] = source.GetKind()
labels[common.GenerateSourceNSLabel] = source.GetNamespace()
labels[common.GenerateSourceNameLabel] = source.GetName()
source.SetLabels(labels)
}

View file

@ -14,6 +14,7 @@ import (
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func newResourceSpec(genAPIVersion, genKind, genNamespace, genName string) kyvernov1.ResourceSpec {
@ -72,22 +73,19 @@ func updateRetryAnnotation(kyvernoClient versioned.Interface, ur *kyvernov1beta1
}
func TriggerFromLabels(labels map[string]string) kyvernov1.ResourceSpec {
group := labels[common.GenerateTriggerGroupLabel]
version := labels[common.GenerateTriggerVersionLabel]
apiVersion := schema.GroupVersion{Group: group, Version: version}
return kyvernov1.ResourceSpec{
Kind: labels[common.GenerateTriggerKindLabel],
Namespace: labels[common.GenerateTriggerNSLabel],
Name: labels[common.GenerateTriggerNameLabel],
APIVersion: labels[common.GenerateTriggerAPIVersionLabel],
APIVersion: apiVersion.String(),
}
}
func FindDownstream(client dclient.Interface, policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) (*unstructured.UnstructuredList, error) {
generation := rule.Generation
selector := &metav1.LabelSelector{MatchLabels: map[string]string{
common.GeneratePolicyLabel: policy.GetName(),
common.GeneratePolicyNamespaceLabel: policy.GetNamespace(),
common.GenerateRuleLabel: rule.Name,
kyvernov1.LabelAppManagedBy: kyvernov1.ValueKyvernoApp,
}}
return client.ListResource(context.TODO(), generation.GetAPIVersion(), generation.GetKind(), "", selector)
func FindDownstream(client dclient.Interface, apiVersion, kind string, labels map[string]string) (*unstructured.UnstructuredList, error) {
selector := &metav1.LabelSelector{MatchLabels: labels}
return client.ListResource(context.TODO(), apiVersion, kind, "", selector)
}

View file

@ -88,7 +88,13 @@ func (pc *policyController) createURForDataRule(policy kyvernov1.PolicyInterface
}
var errorList []error
if generate.GetData() != nil {
downstreams, err := generateutils.FindDownstream(pc.client, policy, rule)
labels := map[string]string{
common.GeneratePolicyLabel: policy.GetName(),
common.GeneratePolicyNamespaceLabel: policy.GetNamespace(),
common.GenerateRuleLabel: rule.Name,
kyvernov1.LabelAppManagedBy: kyvernov1.ValueKyvernoApp,
}
downstreams, err := generateutils.FindDownstream(pc.client, rule.Generation.GetAPIVersion(), rule.Generation.GetKind(), labels)
if err != nil {
return downstreamExist, err
}

View file

@ -132,9 +132,9 @@ func (h *generationHandler) handleNonTrigger(
) {
resource := policyContext.OldResource()
labels := resource.GetLabels()
if labels[common.GeneratePolicyLabel] != "" {
if _, ok := labels[common.GenerateTypeCloneSourceLabel]; ok || labels[common.GeneratePolicyLabel] != "" {
h.log.V(4).Info("handle non-trigger resource operation for generate")
if err := h.createUR(ctx, policyContext, request); err != nil {
if err := h.processRequest(ctx, policyContext, request); err != nil {
h.log.Error(err, "failed to create the UR on non-trigger admission request")
}
}
@ -227,46 +227,67 @@ func (h *generationHandler) syncTriggerAction(
}
}
func (h *generationHandler) createUR(ctx context.Context, policyContext *engine.PolicyContext, request admissionv1.AdmissionRequest) (err error) {
// processRequest determine if it needs to re-apply the generate rule to the source or the target changes
func (h *generationHandler) processRequest(ctx context.Context, policyContext *engine.PolicyContext, request admissionv1.AdmissionRequest) (err error) {
var policy kyvernov1.PolicyInterface
new := policyContext.NewResource()
labels := new.GetLabels()
old := policyContext.OldResource()
oldLabels := old.GetLabels()
if !compareLabels(labels, oldLabels) {
return fmt.Errorf("labels have been changed, new: %v, old: %v", labels, oldLabels)
}
var labelsList []map[string]string
var deleteDownstream bool
managedBy := oldLabels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp
deleteDownstream := false
if new.Object == nil {
labels = oldLabels
if !managedBy {
new := policyContext.NewResource()
old := policyContext.OldResource()
labels := old.GetLabels()
managedBy := labels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp
// clone source changes
if !managedBy {
if new.Object == nil {
// clone source deletion
deleteDownstream = true
}
}
pName := labels[common.GeneratePolicyLabel]
pNamespace := labels[common.GeneratePolicyNamespaceLabel]
pRuleName := labels[common.GenerateRuleLabel]
targetSelector := map[string]string{
common.GenerateSourceGroupLabel: old.GroupVersionKind().Group,
common.GenerateSourceVersionLabel: old.GroupVersionKind().Version,
common.GenerateSourceKindLabel: old.GetKind(),
common.GenerateSourceNSLabel: old.GetNamespace(),
common.GenerateSourceNameLabel: old.GetName(),
}
targets, err := generateutils.FindDownstream(h.client, old.GetAPIVersion(), old.GetKind(), targetSelector)
if err != nil {
return fmt.Errorf("failed to list targets resources: %v", err)
}
if pNamespace != "" {
policy, err = h.polLister.Policies(pNamespace).Get(pName)
for i := range targets.Items {
l := targets.Items[i].GetLabels()
labelsList = append(labelsList, l)
}
} else {
policy, err = h.cpolLister.Get(pName)
labelsList = append(labelsList, labels)
}
if err != nil {
return err
}
for _, labels := range labelsList {
pName := labels[common.GeneratePolicyLabel]
pNamespace := labels[common.GeneratePolicyNamespaceLabel]
pRuleName := labels[common.GenerateRuleLabel]
pKey := common.PolicyKey(pNamespace, pName)
for _, rule := range policy.GetSpec().Rules {
if rule.Name == pRuleName && rule.Generation.Synchronize {
ur := buildURSpec(kyvernov1beta1.Generate, pKey, rule.Name, generateutils.TriggerFromLabels(labels), deleteDownstream)
if err := h.urGenerator.Apply(ctx, ur); err != nil {
e := event.NewBackgroundFailedEvent(err, pKey, pRuleName, event.GeneratePolicyController, &new)
h.eventGen.Add(e...)
return err
if pNamespace != "" {
policy, err = h.polLister.Policies(pNamespace).Get(pName)
} else {
policy, err = h.cpolLister.Get(pName)
}
if err != nil {
return err
}
pKey := common.PolicyKey(pNamespace, pName)
for _, rule := range policy.GetSpec().Rules {
if rule.Name == pRuleName && rule.Generation.Synchronize {
ur := buildURSpec(kyvernov1beta1.Generate, pKey, rule.Name, generateutils.TriggerFromLabels(labels), deleteDownstream)
if err := h.urGenerator.Apply(ctx, ur); err != nil {
e := event.NewBackgroundFailedEvent(err, pKey, pRuleName, event.GeneratePolicyController, &new)
h.eventGen.Add(e...)
return err
}
}
}
}

View file

@ -3,7 +3,6 @@ package generation
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/background/common"
"github.com/kyverno/kyverno/pkg/engine"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
admissionv1 "k8s.io/api/admission/v1"
@ -37,18 +36,3 @@ func matchDeleteOperation(rule kyvernov1.Rule) bool {
return datautils.SliceContains(ops, string(admissionv1.Delete))
}
func compareLabels(new, old map[string]string) bool {
if new == nil {
return true
}
if new[common.GeneratePolicyLabel] != old[common.GeneratePolicyLabel] ||
new[common.GeneratePolicyNamespaceLabel] != old[common.GeneratePolicyNamespaceLabel] ||
new[common.GenerateRuleLabel] != old[common.GenerateRuleLabel] ||
new[common.GenerateTriggerNameLabel] != old[common.GenerateTriggerNameLabel] ||
new[common.GenerateTriggerNSLabel] != old[common.GenerateTriggerNSLabel] ||
new[common.GenerateTriggerKindLabel] != old[common.GenerateTriggerKindLabel] {
return false
}
return true
}

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-reinstall-policy
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,35 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-source-multiple-targets-ns
---
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-ns
type: Opaque
data:
foo: Zm9v
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-reinstall-policy
spec:
rules:
- name: sync-image-pull-secret
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: v1
kind: Secret
name: regcred
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: cpol-clone-sync-single-source-multiple-targets-ns
name: regcred

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
---
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
type: Opaque
data:
foo: Zm9v
---
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2
type: Opaque
data:
foo: Zm9v

View file

@ -0,0 +1,7 @@
# Specifying the kind as `TestStep` performs certain behaviors like this delete operation.
apiVersion: kuttl.dev/v1beta1
kind: TestStep
delete:
- apiVersion: kyverno.io/v1
kind: ClusterPolicy
name: cpol-clone-sync-reinstall-policy

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-ns
type: Opaque
data:
foo: aGVyZWlzY2hhbmdlZGRhdGE=

View file

@ -0,0 +1,22 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-reinstall-policy
spec:
generateExisting: true
rules:
- name: sync-image-pull-secret
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: v1
kind: Secret
name: regcred
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: cpol-clone-sync-single-source-multiple-targets-ns
name: regcred

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- command: sleep 3

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
type: Opaque
data:
foo: aGVyZWlzY2hhbmdlZGRhdGE=
---
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2
type: Opaque
data:
foo: aGVyZWlzY2hhbmdlZGRhdGE=

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-ns
type: Opaque
data:
foo: YmFy

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- command: sleep 3

View file

@ -0,0 +1,17 @@
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
type: Opaque
data:
foo: YmFy
---
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2
type: Opaque
data:
foo: YmFy

View file

@ -0,0 +1,13 @@
## Description
This is a corner case test to ensure a generate clone rule can be triggered on the deletion of the trigger resource. It also ensures upgrades to 1.10 are successful for the same clone rule type.
## Expected Behavior
1. when the trigger is created, the corresponding downstream target secret should be generated
2. delete the policy, update the source, then re-install the policy with generateExisting=true, the change should be synced to the downstream target
3. update the source again, the change should be synced to the downstream target
## Reference Issue(s)
https://github.com/kyverno/kyverno/issues/7170

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-single-source-multiple-targets
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,35 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-source-multiple-targets-ns
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: foosource
namespace: cpol-clone-sync-single-source-multiple-targets-ns
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-single-source-multiple-targets
spec:
generateExisting: false
rules:
- name: rule-clone-sync-single-source-multiple-targets
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: v1
kind: ConfigMap
name: footarget
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: cpol-clone-sync-single-source-multiple-targets-ns
name: foosource

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
---
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2

View file

@ -0,0 +1,15 @@
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: footarget
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: footarget
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2

View file

@ -0,0 +1,7 @@
apiVersion: v1
data:
foo: baz
kind: ConfigMap
metadata:
name: foosource
namespace: cpol-clone-sync-single-source-multiple-targets-ns

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- command: sleep 3

View file

@ -0,0 +1,15 @@
apiVersion: v1
data:
foo: baz
kind: ConfigMap
metadata:
name: footarget
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-1
---
apiVersion: v1
data:
foo: baz
kind: ConfigMap
metadata:
name: footarget
namespace: cpol-clone-sync-single-source-multiple-targets-trigger-ns-2

View file

@ -0,0 +1,11 @@
## Description
This is a corner case test to ensure the changes to the clone source can be synced to multiple targets.
## Expected Behavior
If the change from `foo=bar` to `foo=baz` is synced to downstream targets, the test passes. Otherwise fails.
## Reference Issue(s)
https://github.com/kyverno/kyverno/issues/7170

View file

@ -0,0 +1,19 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-single-trigger-source-multiple-targets-1
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready
---
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-single-trigger-source-multiple-targets-2
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,56 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-single-trigger-source-multiple-targets-ns
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: foosource
namespace: cpol-clone-sync-single-trigger-source-multiple-targets-ns
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-single-trigger-source-multiple-targets-1
spec:
rules:
- name: rule-sync-image-pull-secret
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: v1
kind: ConfigMap
name: footarget
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: cpol-clone-sync-single-trigger-source-multiple-targets-ns
name: foosource
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-clone-sync-single-trigger-source-multiple-targets-2
spec:
rules:
- name: rule-sync-image-pull-secret
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: v1
kind: ConfigMap
name: bartarget
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: cpol-clone-sync-single-trigger-source-multiple-targets-ns
name: foosource

View file

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-single-trigger-source-multiple-targets-trigger-ns

View file

@ -0,0 +1,15 @@
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: footarget
namespace: cpol-single-trigger-source-multiple-targets-trigger-ns
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: bartarget
namespace: cpol-single-trigger-source-multiple-targets-trigger-ns

View file

@ -0,0 +1,7 @@
apiVersion: v1
data:
foo: baz
kind: ConfigMap
metadata:
name: foosource
namespace: cpol-clone-sync-single-trigger-source-multiple-targets-ns

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- command: sleep 3

View file

@ -0,0 +1,15 @@
apiVersion: v1
data:
foo: baz
kind: ConfigMap
metadata:
name: footarget
namespace: cpol-single-trigger-source-multiple-targets-trigger-ns
---
apiVersion: v1
data:
foo: baz
kind: ConfigMap
metadata:
name: bartarget
namespace: cpol-single-trigger-source-multiple-targets-trigger-ns

View file

@ -0,0 +1,11 @@
## Description
This is a corner case test to ensure the changes to the clone source can be synced to multiple targets.
## Expected Behavior
If the change from `foo=bar` to `foo=baz` is synced to downstream targets, the test passes. Otherwise fails.
## Reference Issue(s)
https://github.com/kyverno/kyverno/issues/7170

View file

@ -11,7 +11,8 @@ metadata:
generate.kyverno.io/policy-name: generate-event-upon-edit
generate.kyverno.io/policy-namespace: ""
generate.kyverno.io/rule-name: generate-event-on-edit
generate.kyverno.io/trigger-apiversion: v1
generate.kyverno.io/trigger-version: v1
generate.kyverno.io/trigger-group: ""
generate.kyverno.io/trigger-kind: ConfigMap
generate.kyverno.io/trigger-name: generate-event-on-edit-configmap
generate.kyverno.io/trigger-namespace: generate-event-on-edit-ns

View file

@ -11,7 +11,8 @@ metadata:
generate.kyverno.io/policy-name: generate-event-upon-edit
generate.kyverno.io/policy-namespace: ""
generate.kyverno.io/rule-name: generate-event-on-edit
generate.kyverno.io/trigger-apiversion: v1
generate.kyverno.io/trigger-version: v1
generate.kyverno.io/trigger-group: ""
generate.kyverno.io/trigger-kind: ConfigMap
generate.kyverno.io/trigger-name: generate-event-on-edit-configmap
generate.kyverno.io/trigger-namespace: generate-event-on-edit-ns
@ -32,7 +33,8 @@ metadata:
generate.kyverno.io/policy-name: generate-event-upon-edit
generate.kyverno.io/policy-namespace: ""
generate.kyverno.io/rule-name: generate-event-on-edit
generate.kyverno.io/trigger-apiversion: v1
generate.kyverno.io/trigger-version: v1
generate.kyverno.io/trigger-group: ""
generate.kyverno.io/trigger-kind: ConfigMap
generate.kyverno.io/trigger-name: generate-event-on-edit-configmap
generate.kyverno.io/trigger-namespace: generate-event-on-edit-ns

View file

@ -1,5 +0,0 @@
# This clean-up stage is necessary because of https://github.com/kyverno/kyverno/issues/5101
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- command: kubectl delete ur -A --all

View file

@ -4,5 +4,5 @@ data:
kind: Secret
metadata:
name: regcred
namespace: myfoons
namespace: cpol-clone-sync-modify-source-trigger-ns
type: Opaque

View file

@ -4,5 +4,5 @@ data:
kind: Secret
metadata:
name: regcred
namespace: default
namespace: cpol-clone-sync-modify-source-ns
type: Opaque

View file

@ -1,4 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: myfoons
name: cpol-clone-sync-modify-source-trigger-ns

View file

@ -1,10 +1,15 @@
apiVersion: v1
kind: Namespace
metadata:
name: cpol-clone-sync-modify-source-ns
---
apiVersion: v1
data:
foo: YmFy
kind: Secret
metadata:
name: regcred
namespace: default
namespace: cpol-clone-sync-modify-source-ns
type: Opaque
---
apiVersion: kyverno.io/v2beta1
@ -26,6 +31,6 @@ spec:
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: default
namespace: cpol-clone-sync-modify-source-ns
name: regcred
---

View file

@ -4,5 +4,5 @@ data:
kind: Secret
metadata:
name: regcred
namespace: myfoons
namespace: cpol-clone-sync-modify-source-trigger-ns
type: Opaque

View file

@ -9,7 +9,8 @@ metadata:
generate.kyverno.io/policy-name: zk-kafka-address
generate.kyverno.io/policy-namespace: ""
generate.kyverno.io/rule-name: k-kafka-address
generate.kyverno.io/trigger-apiversion: v1
generate.kyverno.io/trigger-version: v1
generate.kyverno.io/trigger-group: ""
generate.kyverno.io/trigger-kind: PodExecOptions
generate.kyverno.io/trigger-name: ""
generate.kyverno.io/trigger-namespace: test-generate-exec