From 8acb8c3e383fca3155fb8334800daa9632350b68 Mon Sep 17 00:00:00 2001 From: Riko Kudo Date: Thu, 17 Nov 2022 17:17:45 +0900 Subject: [PATCH] fixed dryrun option to handle changes caused by mutating policy (#4899) * fixed dryrun option to handle changes caused by mutating policy Signed-off-by: Riko Kudo * add a check to avoid using kyverno namespace for dryrun Signed-off-by: Riko Kudo * add a check to avoid using kyverno namespace for dryrun Signed-off-by: Riko Kudo Signed-off-by: Riko Kudo Co-authored-by: shuting Co-authored-by: Jim Bugwadia --- .../{dryrun_rbac.yaml => dryrun_config.yaml} | 16 ++++++++++++++-- pkg/config/config.go | 6 ++++++ pkg/engine/k8smanifest.go | 17 ++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) rename config/dryrun/{dryrun_rbac.yaml => dryrun_config.yaml} (79%) diff --git a/config/dryrun/dryrun_rbac.yaml b/config/dryrun/dryrun_config.yaml similarity index 79% rename from config/dryrun/dryrun_rbac.yaml rename to config/dryrun/dryrun_config.yaml index 90e8eb9164..82e3dceb88 100644 --- a/config/dryrun/dryrun_rbac.yaml +++ b/config/dryrun/dryrun_config.yaml @@ -1,3 +1,15 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app: kyverno + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + app.kubernetes.io/version: latest + name: kyverno-dryrun +--- # Additional permission is required to enable DryRun. # If using DryRun to validate yaml, please deploy this Role/RoleBinding. # If validating custom resources with DryRun, please add the resources to the role. @@ -5,7 +17,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: manifest-verify-dry-run - namespace: kyverno + namespace: kyverno-dryrun rules: - apiGroups: - rbac.authorization.k8s.io @@ -64,7 +76,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: manifest-verify-dry-run - namespace: kyverno + namespace: kyverno-dryrun roleRef: apiGroup: rbac.authorization.k8s.io kind: Role diff --git a/pkg/config/config.go b/pkg/config/config.go index 5a1e76a5e2..79c43e0b5d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -73,12 +73,18 @@ var ( kyvernoConfigMapName = osutils.GetEnvWithFallback("INIT_CONFIG", "kyverno") // defaultExcludeGroupRole ... defaultExcludeGroupRole []string = []string{"system:serviceaccounts:kube-system", "system:nodes", "system:kube-scheduler"} + // kyvernoDryRunNamespace is the namespace for DryRun option of YAML verification + kyvernoDryrunNamespace = osutils.GetEnvWithFallback("KYVERNO_DRYRUN_NAMESPACE", "kyverno-dryrun") ) func KyvernoNamespace() string { return kyvernoNamespace } +func KyvernoDryRunNamespace() string { + return kyvernoDryrunNamespace +} + func KyvernoServiceAccountName() string { return kyvernoServiceAccountName } diff --git a/pkg/engine/k8smanifest.go b/pkg/engine/k8smanifest.go index 1ca703f5e6..0ba4d1f5d1 100644 --- a/pkg/engine/k8smanifest.go +++ b/pkg/engine/k8smanifest.go @@ -101,7 +101,7 @@ func verifyManifest(policyContext *PolicyContext, verifyRule kyvernov1.Manifests if verifyRule.DryRunOption.Namespace != "" { vo.DryRunNamespace = verifyRule.DryRunOption.Namespace } else { - vo.DryRunNamespace = config.KyvernoNamespace() + vo.DryRunNamespace = config.KyvernoDryRunNamespace() } if !vo.DisableDryRun { // check if kyverno can 'create' dryrun resource @@ -114,6 +114,12 @@ func verifyManifest(policyContext *PolicyContext, verifyRule kyvernov1.Manifests logger.V(1).Info("kyverno does not have permissions to 'create' resource. disabled DryRun option.", "dryrun namespace", vo.DryRunNamespace, "kind", adreq.Kind.Kind) vo.DisableDryRun = true } + // check if kyverno namespace is not used for dryrun + ok = checkDryRunNamespace(vo.DryRunNamespace) + if !ok { + logger.V(1).Info("an inappropriate dryrun namespace is set; set a namespace other than kyverno.", "dryrun namespace", vo.DryRunNamespace) + vo.DisableDryRun = true + } } // can be overridden per Attestor @@ -399,3 +405,12 @@ func checkDryRunPermission(dclient dclient.Interface, kind, namespace string) (b } return ok, nil } + +func checkDryRunNamespace(namespace string) bool { + // should not use kyverno namespace for dryrun + if namespace != config.KyvernoNamespace() { + return true + } else { + return false + } +}