From b0328aeda1ee9a788f22caf405b8e436d5b71398 Mon Sep 17 00:00:00 2001 From: "Radek Schekalla (SAP)" Date: Tue, 11 Nov 2025 14:35:13 +0100 Subject: [PATCH 1/3] feat: use default values for kyverno helm chart if activated via env var, otherwise use values from config On-behalf-of: Radek Schekalla (SAP) Signed-off-by: Radek Schekalla (SAP) --- go.mod | 2 +- .../components/kyverno_component.go | 70 +++++++++++++++++-- .../components/kyverno_component_test.go | 66 ++++++++++++++++- 3 files changed, 130 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 0ba6ab9..93c07cd 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.11.1 gotest.tools/v3 v3.5.2 + helm.sh/helm/v3 v3.19.0 k8s.io/api v0.34.1 k8s.io/apiextensions-apiserver v0.34.1 k8s.io/apimachinery v0.34.1 @@ -326,7 +327,6 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - helm.sh/helm/v3 v3.19.0 // indirect k8s.io/cli-runtime v0.34.1 // indirect k8s.io/component-base v0.34.1 // indirect k8s.io/kubectl v0.34.0 // indirect diff --git a/pkg/controlplane/components/kyverno_component.go b/pkg/controlplane/components/kyverno_component.go index 52544df..8845dc7 100644 --- a/pkg/controlplane/components/kyverno_component.go +++ b/pkg/controlplane/components/kyverno_component.go @@ -2,25 +2,30 @@ package components import ( "context" + "encoding/json" + "fmt" + "os" "strings" helmv2 "github.com/fluxcd/helm-controller/api/v2" sourcev1 "github.com/fluxcd/source-controller/api/v1" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/openmcp-project/control-plane-operator/api/v1beta1" "github.com/openmcp-project/control-plane-operator/pkg/juggler" "github.com/openmcp-project/control-plane-operator/pkg/juggler/fluxcd" "github.com/openmcp-project/control-plane-operator/pkg/juggler/hooks" "github.com/openmcp-project/control-plane-operator/pkg/utils/rcontext" + rbacv1 "k8s.io/api/rbac/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) const ( kyvernoRelease = "kyverno" kyvernoNamespace = "kyverno-system" ComponentNameKyverno = "Kyverno" + + EnvEnableKyvernoDefaultValues = "ENABLE_KYVERNO_DEFAULT_VALUES" ) var _ fluxcd.FluxComponent = &Kyverno{} @@ -173,6 +178,17 @@ func (k *Kyverno) applyDefaultChartSpec(rfn v1beta1.VersionResolverFn) { } func (k *Kyverno) BuildManifesto(ctx context.Context) (fluxcd.Manifesto, error) { + values := k.Config.Values + + // If default values are enabled, use them instead + if os.Getenv(EnvEnableKyvernoDefaultValues) == "true" { + defaultValues, err := k.getDefaultValues() + if err != nil { + return nil, fmt.Errorf("failed to get default Kyverno values: %w", err) + } + values = defaultValues + } + release := &helmv2.HelmRelease{ ObjectMeta: metav1.ObjectMeta{ Name: strings.ToLower(ComponentNameKyverno), @@ -193,7 +209,7 @@ func (k *Kyverno) BuildManifesto(ctx context.Context) (fluxcd.Manifesto, error) TargetNamespace: kyvernoNamespace, StorageNamespace: kyvernoNamespace, KubeConfig: rcontext.FluxKubeconfigRef(ctx), - Values: k.Config.Values, + Values: values, }, } @@ -201,3 +217,47 @@ func (k *Kyverno) BuildManifesto(ctx context.Context) (fluxcd.Manifesto, error) adapter.ApplyDefaults() return adapter, nil } + +func (k *Kyverno) getDefaultValues() (*apiextensionsv1.JSON, error) { + defaults := map[string]interface{}{ + "config": map[string]interface{}{ + "preserve": false, + "resourceFilters": []string{ + "[*/*,kyverno,*]", + "[*/*,istio-system,*]", + "[*/*,kyma-system,*]", + "[*/*,kube-system,*]", + "[*/*,kube-public,*]", + "[*/*,neo-core,*]", + }, + "updateRequestThreshold": 5000, + "excludeGroups": []string{ + "system:nodes", + }, + "webhooks": map[string]interface{}{ + "namespaceSelector": map[string]interface{}{ + "matchExpressions": []map[string]interface{}{ + { + "key": "kubernetes.io/metadata.name", + "operator": "NotIn", + "values": []string{ + "kube-system", + "kyverno", + "istio-system", + "kube-public", + "kyma-system", + "neo-core", + }, + }, + }, + }, + }, + }, + } + + raw, err := json.Marshal(defaults) + if err != nil { + return nil, fmt.Errorf("failed to marshal default values: %w", err) + } + return &apiextensionsv1.JSON{Raw: raw}, nil +} diff --git a/pkg/controlplane/components/kyverno_component_test.go b/pkg/controlplane/components/kyverno_component_test.go index 90c82ca..266b1fc 100644 --- a/pkg/controlplane/components/kyverno_component_test.go +++ b/pkg/controlplane/components/kyverno_component_test.go @@ -4,14 +4,15 @@ package components import ( "testing" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "github.com/openmcp-project/control-plane-operator/api/v1beta1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" ) func Test_Kyverno(t *testing.T) { testCases := []struct { desc string + osEnv string + osEnvVal string config *v1beta1.KyvernoConfig versionResolver v1beta1.VersionResolverFn validationFuncs []validationFunc @@ -63,10 +64,71 @@ func Test_Kyverno(t *testing.T) { ), }, }, + { + desc: "should use default values instad of values from config when enabled via env", + osEnv: EnvEnableKyvernoDefaultValues, + osEnvVal: "true", + config: &v1beta1.KyvernoConfig{ + Version: "1.2.3", + Values: &apiextensionsv1.JSON{Raw: []byte(`{"crds":{"install":true}}`)}, + }, + versionResolver: fakeVersionResolver(false), + validationFuncs: []validationFunc{ + hasName("Kyverno"), + isEnabled(true), + isAllowed(true), + hasPreUninstallHook(), + hasDependencies(0), + isTargetComponent( + hasNamespace("kyverno-system"), + ), + isFluxComponent( + returnsHelmRepo(), + returnsHelmRelease( + hasKubeconfigRef(), + hasHelmValue(false, "config", "preserve"), + hasHelmValue([]interface{}{ + "[*/*,kyverno,*]", + "[*/*,istio-system,*]", + "[*/*,kyma-system,*]", + "[*/*,kube-system,*]", + "[*/*,kube-public,*]", + "[*/*,neo-core,*]", + }, "config", "resourceFilters"), + hasHelmValue(5000, "config", "updateRequestThreshold"), + hasHelmValue([]interface{}{ + "system:nodes", + }, "config", "excludeGroups"), + hasHelmValue(map[string]interface{}{ + "matchExpressions": []interface{}{ + map[string]interface{}{ + "key": "kubernetes.io/metadata.name", + "operator": "NotIn", + "values": []interface{}{ + "kube-system", + "kyverno", + "istio-system", + "kube-public", + "kyma-system", + "neo-core", + }, + }, + }, + }, "config", "webhooks", "namespaceSelector"), + ), + ), + isPolicyRulesComponent( + hasPolicyRules(), + ), + }, + }, } for _, tC := range testCases { t.Run(tC.desc, func(t *testing.T) { ctx := newContext(nil, tC.versionResolver) + if tC.osEnv != "" && tC.osEnvVal != "" { + t.Setenv(tC.osEnv, tC.osEnvVal) + } c := &Kyverno{Config: tC.config} for _, vfn := range tC.validationFuncs { vfn(t, ctx, c) From 15e1f8fabc6dd3c9978c37c7a77d948396cdbb4d Mon Sep 17 00:00:00 2001 From: "Radek Schekalla (SAP)" Date: Tue, 11 Nov 2025 14:53:39 +0100 Subject: [PATCH 2/3] fix: run task generate On-behalf-of: Radek Schekalla (SAP) Signed-off-by: Radek Schekalla (SAP) --- go.mod | 2 +- pkg/controlplane/components/kyverno_component.go | 9 +++++---- pkg/controlplane/components/kyverno_component_test.go | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 93c07cd..0ba6ab9 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.11.1 gotest.tools/v3 v3.5.2 - helm.sh/helm/v3 v3.19.0 k8s.io/api v0.34.1 k8s.io/apiextensions-apiserver v0.34.1 k8s.io/apimachinery v0.34.1 @@ -327,6 +326,7 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect + helm.sh/helm/v3 v3.19.0 // indirect k8s.io/cli-runtime v0.34.1 // indirect k8s.io/component-base v0.34.1 // indirect k8s.io/kubectl v0.34.0 // indirect diff --git a/pkg/controlplane/components/kyverno_component.go b/pkg/controlplane/components/kyverno_component.go index 8845dc7..6b3fd5c 100644 --- a/pkg/controlplane/components/kyverno_component.go +++ b/pkg/controlplane/components/kyverno_component.go @@ -9,15 +9,16 @@ import ( helmv2 "github.com/fluxcd/helm-controller/api/v2" sourcev1 "github.com/fluxcd/source-controller/api/v1" + rbacv1 "k8s.io/api/rbac/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "github.com/openmcp-project/control-plane-operator/api/v1beta1" "github.com/openmcp-project/control-plane-operator/pkg/juggler" "github.com/openmcp-project/control-plane-operator/pkg/juggler/fluxcd" "github.com/openmcp-project/control-plane-operator/pkg/juggler/hooks" "github.com/openmcp-project/control-plane-operator/pkg/utils/rcontext" - rbacv1 "k8s.io/api/rbac/v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" ) const ( diff --git a/pkg/controlplane/components/kyverno_component_test.go b/pkg/controlplane/components/kyverno_component_test.go index 266b1fc..15d5ed3 100644 --- a/pkg/controlplane/components/kyverno_component_test.go +++ b/pkg/controlplane/components/kyverno_component_test.go @@ -4,8 +4,9 @@ package components import ( "testing" - "github.com/openmcp-project/control-plane-operator/api/v1beta1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + + "github.com/openmcp-project/control-plane-operator/api/v1beta1" ) func Test_Kyverno(t *testing.T) { From 73727f5862eb2d1a2238396c1a750d8467619691 Mon Sep 17 00:00:00 2001 From: "Radek Schekalla (SAP)" Date: Tue, 11 Nov 2025 15:11:52 +0100 Subject: [PATCH 3/3] enable defaults in tests via flag On-behalf-of: Radek Schekalla (SAP) Signed-off-by: Radek Schekalla (SAP) --- .../components/kyverno_component_test.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pkg/controlplane/components/kyverno_component_test.go b/pkg/controlplane/components/kyverno_component_test.go index 15d5ed3..d54c5d4 100644 --- a/pkg/controlplane/components/kyverno_component_test.go +++ b/pkg/controlplane/components/kyverno_component_test.go @@ -12,9 +12,8 @@ import ( func Test_Kyverno(t *testing.T) { testCases := []struct { desc string - osEnv string - osEnvVal string config *v1beta1.KyvernoConfig + enableDefaults bool versionResolver v1beta1.VersionResolverFn validationFuncs []validationFunc }{ @@ -66,9 +65,8 @@ func Test_Kyverno(t *testing.T) { }, }, { - desc: "should use default values instad of values from config when enabled via env", - osEnv: EnvEnableKyvernoDefaultValues, - osEnvVal: "true", + desc: "should use default values instad of values from config when enabled via env", + enableDefaults: true, config: &v1beta1.KyvernoConfig{ Version: "1.2.3", Values: &apiextensionsv1.JSON{Raw: []byte(`{"crds":{"install":true}}`)}, @@ -127,8 +125,8 @@ func Test_Kyverno(t *testing.T) { for _, tC := range testCases { t.Run(tC.desc, func(t *testing.T) { ctx := newContext(nil, tC.versionResolver) - if tC.osEnv != "" && tC.osEnvVal != "" { - t.Setenv(tC.osEnv, tC.osEnvVal) + if tC.enableDefaults { + t.Setenv(EnvEnableKyvernoDefaultValues, "true") } c := &Kyverno{Config: tC.config} for _, vfn := range tC.validationFuncs {