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

fix: overwrite the managed-by label for target resources (#11267)

* feat: overwrite managed-by label on the target generated resources

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

* chore: add chainsaw test

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

* chore: update e2e test matrix

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

---------

Signed-off-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
shuting 2024-09-30 21:28:11 +08:00 committed by GitHub
parent b666b1665c
commit 1af0fc5244
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 162 additions and 18 deletions

View file

@ -1,14 +1,12 @@
package common
import (
"fmt"
"reflect"
"strings"
"github.com/kyverno/kyverno/api/kyverno"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
"github.com/kyverno/kyverno/pkg/logging"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
pkglabels "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
@ -63,20 +61,7 @@ func GenerateLabelsSet(policyKey string) pkglabels.Set {
}
func managedBy(labels map[string]string) {
// ManagedBy label
key := kyverno.LabelAppManagedBy
value := kyverno.ValueKyvernoApp
val, ok := labels[key]
if ok {
if val != value {
logging.V(2).Info(fmt.Sprintf("resource managed by %s, kyverno wont over-ride the label", val))
return
}
}
if !ok {
// add label
labels[key] = value
}
labels[kyverno.LabelAppManagedBy] = kyverno.ValueKyvernoApp
}
func PolicyInfo(labels map[string]string, policy kyvernov1.PolicyInterface, ruleName string) {

View file

@ -41,8 +41,8 @@
"^force-failure-policy-ignore$"
],
"generate": [
"^generate$/^clusterpolicy$/^cornercases$/^(clone-list-sync-same-trigger-source-delete-source|clone-list-sync-same-trigger-source-update-source|clone-role-and-rolebinding|clone-source-name-exceeds-63-characters|clone-sync-same-trigger-source-delete-source|clone-sync-same-trigger-source-update-source|cpol-clone-create-on-trigger-deletion|cpol-clone-delete-ownerreferences-across-namespaces|cpol-clone-delete-ownerreferences-across-namespaces-deprecated|cpol-clone-sync-create-source-after-policy|cpol-clone-sync-reinstall-policy|cpol-clone-sync-reinstall-policy-deprecated|cpol-clone-sync-single-source-multiple-triggers-targets|cpol-clone-sync-single-source-multiple-triggers-targets-deprecated|cpol-clone-sync-single-trigger-source-multiple-targets|cpol-data-create-on-trigger-deletion|cpol-data-sync-create-upon-generated-resource|cpol-data-sync-no-creation-upon-generated-resource|cpol-data-sync-remove-list-element|cpol-data-sync-to-nosync-delete-rule)\\[.*\\]$",
"^generate$/^clusterpolicy$/^cornercases$/^(cpol-data-sync-to-nosync-delete-rule-deprecated|cpol-data-trigger-not-present|data-role-and-rolebinding|generate-event-upon-edit|pod-restart-on-cm-update|pod-restart-on-cm-update-deprecated|trigger-resource-name-exceeds-63-characters)\\[.*\\]$",
"^generate$/^clusterpolicy$/^cornercases$/^(clone-list-sync-same-trigger-source-delete-source|clone-list-sync-same-trigger-source-update-source|clone-role-and-rolebinding|clone-source-managed-by-label-helm|clone-source-name-exceeds-63-characters|clone-sync-same-trigger-source-delete-source|clone-sync-same-trigger-source-update-source|cpol-clone-create-on-trigger-deletion|cpol-clone-delete-ownerreferences-across-namespaces|cpol-clone-delete-ownerreferences-across-namespaces-deprecated|cpol-clone-sync-create-source-after-policy|cpol-clone-sync-reinstall-policy|cpol-clone-sync-reinstall-policy-deprecated|cpol-clone-sync-single-source-multiple-triggers-targets|cpol-clone-sync-single-source-multiple-triggers-targets-deprecated|cpol-clone-sync-single-trigger-source-multiple-targets|cpol-data-create-on-trigger-deletion|cpol-data-sync-create-upon-generated-resource|cpol-data-sync-no-creation-upon-generated-resource|cpol-data-sync-remove-list-element)\\[.*\\]$",
"^generate$/^clusterpolicy$/^cornercases$/^(cpol-data-sync-to-nosync-delete-rule|cpol-data-sync-to-nosync-delete-rule-deprecated|cpol-data-trigger-not-present|data-role-and-rolebinding|generate-event-upon-edit|pod-restart-on-cm-update|pod-restart-on-cm-update-deprecated|trigger-resource-name-exceeds-63-characters)\\[.*\\]$",
"^generate$/^clusterpolicy$/^standard$/^clone$/^multiple$/^sync$/^(basic-create)\\[.*\\]$",
"^generate$/^clusterpolicy$/^standard$/^clone$/^nosync$/^(cpol-clone-nosync-create|cpol-clone-nosync-delete-downstream|cpol-clone-nosync-delete-policy|cpol-clone-nosync-delete-rule|cpol-clone-nosync-delete-source|cpol-clone-nosync-delete-trigger|cpol-clone-nosync-modify-downstream|cpol-clone-nosync-modify-source|cpol-clone-nosync-update-trigger-no-match)\\[.*\\]$",
"^generate$/^clusterpolicy$/^standard$/^clone$/^sync$/^(cpol-clone-list-sync-create|cpol-clone-list-sync-create-deprecated|cpol-clone-list-sync-delete-source|cpol-clone-list-sync-update-deprecated|cpol-clone-list-sync-update-source|cpol-clone-sync-create|cpol-clone-sync-delete-downstream|cpol-clone-sync-delete-policy|cpol-clone-sync-delete-rule|cpol-clone-sync-delete-source|cpol-clone-sync-delete-trigger|cpol-clone-sync-existing-update-trigger-no-precondition|cpol-clone-sync-existing-update-trigger-no-precondition-deprecated|cpol-clone-sync-modify-downstream|cpol-clone-sync-modify-downstream-apply|cpol-clone-sync-modify-source|cpol-clone-sync-no-existing-update-trigger-no-precondition|cpol-clone-sync-update-trigger-no-match)\\[.*\\]$",

View file

@ -0,0 +1,11 @@
## Description
This test ensures that the secret is cloned from a source resource has the label `app.kubernetes.io/managed-by: kyverno`.
## Expected Behavior
If the downstream resource is delete after source is deleted, the test passes. If it is not created, the test fails.
## Reference Issue(s)
https://github.com/kyverno/kyverno/issues/9718

View file

@ -0,0 +1,19 @@
apiVersion: v1
kind: Namespace
metadata:
name: platform
---
apiVersion: v1
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSI4NDQzMzM1OTc1MzYuZGtyLmVjci51cy13ZXN0LTIuYW1hem9uYXdzLmNvbSI6IHt9LAoJCSJnaGNyLmlvIjoge30sCgkJImt5dmVybm9ub3Rhcnl0ZXN0LmF6dXJlY3IuaW8iOiB7fSwKCQkicXVheS5pbyI6IHt9LAoJCSJyZWdpc3RyeS12Mi5uaXJtYXRhLmlvIjoge30sCgkJInJlZ2lzdHJ5LmNvbm5lY3QucmVkaGF0LmNvbSI6IHt9LAoJCSJyZWdpc3RyeS5yZWRoYXQuaW8iOiB7fSwKCQkic2Nhbi5jb25uZWN0LnJlZGhhdC5jb20iOiB7fQoJfSwKCSJjcmVkc1N0b3JlIjogImRlc2t0b3AiLAoJImN1cnJlbnRDb250ZXh0IjogImRlc2t0b3AtbGludXgiCn0=
kind: Secret
metadata:
annotations:
meta.helm.sh/release-name: bootstrap
meta.helm.sh/release-namespace: default
labels:
app.kubernetes.io/managed-by: Helm
generate.kyverno.io/clone-source: ""
name: harbor-external
namespace: platform
type: kubernetes.io/dockerconfigjson

View file

@ -0,0 +1,27 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: sync-image-pull-secrets
spec:
validationFailureAction: Audit
background: false
generateExisting: true
rules:
- name: sync-image-pull-secret-harbor-external
match:
any:
- resources:
kinds:
- Namespace
selector:
matchLabels:
sync-image-pull-secrets: "true"
generate:
apiVersion: v1
kind: Secret
name: harbor-external
namespace: "{{request.object.metadata.name}}"
synchronize: true
clone:
namespace: platform
name: harbor-external

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: sync-image-pull-secrets
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: Namespace
metadata:
annotations:
helm.sh/resource-policy: keep
linkerd.io/inject: enabled
meta.helm.sh/release-name: workload-namespaces
meta.helm.sh/release-namespace: default
labels:
app.kubernetes.io/managed-by: Helm
gen-vault-kv-store: enabled
helm.toolkit.fluxcd.io/name: workload-namespaces-sbx-usc1
helm.toolkit.fluxcd.io/namespace: default
kubernetes.io/metadata.name: my-app
name: my-app
namespaceKind: workloads
owner: team-ccs
sync-image-pull-secrets: "true"
vault-sidecar-injector: enabled
name: my-app

View file

@ -0,0 +1,10 @@
apiVersion: v1
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSI4NDQzMzM1OTc1MzYuZGtyLmVjci51cy13ZXN0LTIuYW1hem9uYXdzLmNvbSI6IHt9LAoJCSJnaGNyLmlvIjoge30sCgkJImt5dmVybm9ub3Rhcnl0ZXN0LmF6dXJlY3IuaW8iOiB7fSwKCQkicXVheS5pbyI6IHt9LAoJCSJyZWdpc3RyeS12Mi5uaXJtYXRhLmlvIjoge30sCgkJInJlZ2lzdHJ5LmNvbm5lY3QucmVkaGF0LmNvbSI6IHt9LAoJCSJyZWdpc3RyeS5yZWRoYXQuaW8iOiB7fSwKCQkic2Nhbi5jb25uZWN0LnJlZGhhdC5jb20iOiB7fQoJfSwKCSJjcmVkc1N0b3JlIjogImRlc2t0b3AiLAoJImN1cnJlbnRDb250ZXh0IjogImRlc2t0b3AtbGludXgiCn0=
kind: Secret
metadata:
labels:
app.kubernetes.io/managed-by: kyverno
name: harbor-external
namespace: my-app
type: kubernetes.io/dockerconfigjson

View file

@ -0,0 +1,8 @@
apiVersion: v1
data:
foo: YmFy
kind: Secret
metadata:
name: regcred
namespace: production
type: Opaque

View file

@ -0,0 +1,34 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: clone-source-name-exceeds-63-characters
spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:
file: chainsaw-step-01-apply-1-2.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
- name: step-03
try:
- delete:
ref:
apiVersion: v1
kind: Secret
name: harbor-external
namespace: platform
- name: step-04
try:
- error:
file: chainsaw-step-02-assert-1-1.yaml

View file

@ -0,0 +1,21 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-19hs91
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
- namespaces
verbs:
- get
- list
- watch
- create
- update
- delete