From a923924714020f9f7d7dc51441338d0ebe8d5675 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Fri, 2 Jun 2023 19:27:41 +0200 Subject: [PATCH 01/19] Add new structure to handle kube-linter conf --- pkg/controller/configmap_watcher.go | 54 +++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/pkg/controller/configmap_watcher.go b/pkg/controller/configmap_watcher.go index 3cfea499..f1d7e902 100644 --- a/pkg/controller/configmap_watcher.go +++ b/pkg/controller/configmap_watcher.go @@ -3,9 +3,11 @@ package controller import ( "context" "fmt" - "strings" "time" + "golang.stackrox.io/kube-linter/pkg/config" + "gopkg.in/yaml.v3" + apicorev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/informers" @@ -14,13 +16,28 @@ import ( "k8s.io/client-go/tools/cache" ) +// this structure mirrors Kube-Linter configuration structure +// it is used to unmarshall ConfigMap data +// doc: https://pkg.go.dev/golang.stackrox.io/kube-linter/pkg/config#Config +type KubeLinterChecks struct { + Checks struct { + AddAllBuiltIn bool `yaml:"addAllBuiltIn,omitempty"` + DoNotAutoAddDefaults bool `yaml:"doNotAutoAddDefaults,omitempty"` + Exclude []string `yaml:"exclude,omitempty"` + Include []string `yaml:"include,omitempty"` + IgnorePaths []string `yaml:"ignorePaths,omitempty"` + } `yaml:"checks"` +} + type ConfigMapWatcher struct { clientset kubernetes.Interface - ch chan struct{} // TODO - TBD configmap struct + checks KubeLinterChecks + ch chan config.Config } var configMapName = "deployment-validation-operator-config" var configMapNamespace = "deployment-validation-operator" +var configMapDataAccess = "deployment-validation-operator-config.yaml" // NewConfigMapWatcher returns a watcher that can be used both: // basic: with GetStaticDisabledChecks method, it returns an existent ConfigMap data's disabled check @@ -36,16 +53,24 @@ func NewConfigMapWatcher(cfg *rest.Config) (ConfigMapWatcher, error) { }, nil } -// GetStaticDisabledChecks returns an existent ConfigMap data's disabled checks, if they exist -func (cmw *ConfigMapWatcher) GetStaticDisabledChecks(ctx context.Context) ([]string, error) { +// GetStaticKubelinterConfig returns the ConfigMap's checks configuration +func (cmw *ConfigMapWatcher) GetStaticKubelinterConfig(ctx context.Context) (config.Config, error) { + var cfg config.Config + cm, err := cmw.clientset.CoreV1(). ConfigMaps(configMapNamespace).Get(ctx, configMapName, v1.GetOptions{}) if err != nil { - return []string{}, fmt.Errorf("gathering starting configmap: %w", err) + return cfg, fmt.Errorf("gathering starting configmap: %w", err) + } + + errYaml := yaml.Unmarshal([]byte(cm.Data[configMapDataAccess]), &cmw.checks) + if errYaml != nil { + return cfg, fmt.Errorf("unmarshalling configmap data: %w", err) } - // TODO - Fix dummy return based on data being check1,check2,check3... - return strings.Split(cm.Data["disabled-checks"], ","), nil + cfg.Checks = config.ChecksConfig(cmw.checks.Checks) + + return cfg, nil } // StartInformer will update the channel structure with new configuration data from ConfigMap update event @@ -63,8 +88,17 @@ func (cmw *ConfigMapWatcher) StartInformer(ctx context.Context) error { fmt.Printf("oldCm: %v\n", oldCm) fmt.Printf("ConfigMap updated: %s/%s\n", newCm.Namespace, newCm.Name) - // TODO - Validate new configmap - cmw.ch <- struct{}{} + var cfg config.Config + + err := yaml.Unmarshal([]byte(newCm.Data[configMapDataAccess]), &cmw.checks) + if err != nil { + fmt.Printf("Error: unmarshalling configmap data: %s", err.Error()) + return + } + + cfg.Checks = config.ChecksConfig(cmw.checks.Checks) + + cmw.ch <- cfg }, }) @@ -74,6 +108,6 @@ func (cmw *ConfigMapWatcher) StartInformer(ctx context.Context) error { } // ConfigChanged receives push notifications when the configuration is updated -func (cmw *ConfigMapWatcher) ConfigChanged() <-chan struct{} { +func (cmw *ConfigMapWatcher) ConfigChanged() <-chan config.Config { return cmw.ch } From 26cddc34e711954914b3c6d479db924a6efaa95e Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Fri, 2 Jun 2023 19:29:19 +0200 Subject: [PATCH 02/19] Add new access to use custom configmap --- main.go | 37 +++++++++++++++++++++++----- pkg/validations/validation_engine.go | 14 +++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index dce83e60..46ec9929 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "errors" "fmt" "os" @@ -9,9 +10,6 @@ import ( "strings" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - apis "github.com/app-sre/deployment-validation-operator/api" dvconfig "github.com/app-sre/deployment-validation-operator/config" "github.com/app-sre/deployment-validation-operator/internal/options" @@ -19,13 +17,15 @@ import ( dvo_prom "github.com/app-sre/deployment-validation-operator/pkg/prometheus" "github.com/app-sre/deployment-validation-operator/pkg/validations" "github.com/app-sre/deployment-validation-operator/version" - "github.com/prometheus/client_golang/prometheus" - "github.com/go-logr/logr" osappsv1 "github.com/openshift/api/apps/v1" + "github.com/prometheus/client_golang/prometheus" + kubelinterCfg "golang.stackrox.io/kube-linter/pkg/config" k8sruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/discovery" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/healthz" @@ -146,7 +146,16 @@ func setupManager(log logr.Logger, opts options.Options) (manager.Manager, error log.Info("Initializing Validation Engine") - if err := validations.InitializeValidationEngine(opts.ConfigFile, reg); err != nil { + // Try to retrieve custom configuration from existing ConfigMap + if kbcfg, err := getCustomConfig(cfg); err != nil { + log.Info("Gather Kube-Linter configuration from ConfigMap") + + if err := validations.InitializeValidationEngineFromConfig(*kbcfg, reg); err != nil { + return nil, fmt.Errorf("initializing validation engine: %w", err) + } + + // or Initialize VE from default + } else if err := validations.InitializeValidationEngine(opts.ConfigFile, reg); err != nil { return nil, fmt.Errorf("initializing validation engine: %w", err) } @@ -235,3 +244,19 @@ func kubeClientQPS() (float32, error) { qps = float32(val) return qps, err } + +// getCustomConfig returns a custom Kube-Linter configuration +// it retrieves data from a ConfigMap if there is any valid +func getCustomConfig(cfg *rest.Config) (*kubelinterCfg.Config, error) { + cmw, err := controller.NewConfigMapWatcher(cfg) + if err != nil { + return nil, fmt.Errorf("getting kube-linter checks configuration from configmap: %w", err) + } + + klCfg, err := cmw.GetStaticKubelinterConfig(context.Background()) + if err != nil { + return nil, fmt.Errorf("getting custom configuration (configmap): %w", err) + } + + return &klCfg, nil +} diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index 631284d8..8b022159 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -178,6 +178,20 @@ func InitializeValidationEngine(configPath string, reg PrometheusRegistry) error return err } +// TODO -> Doc +func InitializeValidationEngineFromConfig(cfg config.Config, reg PrometheusRegistry) error { + ve := validationEngine{ + config: cfg, + } + + err := ve.InitRegistry(reg) + if err == nil { + engine = ve + } + + return err +} + func (ve *validationEngine) GetCheckByName(name string) (config.Check, error) { check, ok := ve.registeredChecks[name] if !ok { From 03ddc2c7204911b39632e37507053263d19d1b8e Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Fri, 2 Jun 2023 19:29:42 +0200 Subject: [PATCH 03/19] Minor refactor --- pkg/controller/configmap_watcher_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controller/configmap_watcher_test.go b/pkg/controller/configmap_watcher_test.go index b6ac77bb..72b87654 100644 --- a/pkg/controller/configmap_watcher_test.go +++ b/pkg/controller/configmap_watcher_test.go @@ -23,7 +23,7 @@ func TestStaticConfigMapWatcher(t *testing.T) { } // When - test, err := mock.GetStaticDisabledChecks(context.Background()) + test, err := mock.GetStaticKubelinterConfig(context.Background()) // Assert assert.NoError(t, err) From 8fc9e1d3a0e9c878dfcbe0c265cef03b84a798b1 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Mon, 5 Jun 2023 19:05:58 +0200 Subject: [PATCH 04/19] Refactor unit tests to table --- pkg/controller/configmap_watcher_test.go | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/pkg/controller/configmap_watcher_test.go b/pkg/controller/configmap_watcher_test.go index 72b87654..22ded7b2 100644 --- a/pkg/controller/configmap_watcher_test.go +++ b/pkg/controller/configmap_watcher_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "golang.stackrox.io/kube-linter/pkg/config" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -12,20 +13,59 @@ import ( ) func TestStaticConfigMapWatcher(t *testing.T) { - // Given - cm := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{Namespace: configMapNamespace, Name: configMapName}, - Data: map[string]string{"disabled-checks": "check,check2"}, - } - client := kubefake.NewSimpleClientset([]runtime.Object{cm}...) - mock := ConfigMapWatcher{ - clientset: client, + testCases := []struct { + name string + data string + checks config.ChecksConfig + }{ + { + name: "kube-linter 'doNotAutoAddDefaults' is gathered from configuration", + data: "checks:\n doNotAutoAddDefaults: true", + checks: config.ChecksConfig{ + DoNotAutoAddDefaults: true, + }, + }, + { + name: "kube-linter 'addAllBuiltIn' is gathered from configuration", + data: "checks:\n addAllBuiltIn: true", + checks: config.ChecksConfig{ + AddAllBuiltIn: true, + }, + }, + { + name: "kube-linter 'exclude' is gathered from configuration", + data: "checks:\n exclude: [\"check1\", \"check2\"]", + checks: config.ChecksConfig{ + Exclude: []string{"check1", "check2"}, + }, + }, + { + name: "kube-linter 'include' is gathered from configuration", + data: "checks:\n include: [\"check1\", \"check2\"]", + checks: config.ChecksConfig{ + Include: []string{"check1", "check2"}, + }, + }, } - // When - test, err := mock.GetStaticKubelinterConfig(context.Background()) + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + // Given + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Namespace: configMapNamespace, Name: configMapName}, + Data: map[string]string{ + "deployment-validation-operator-config.yaml": testCase.data, + }, + } + client := kubefake.NewSimpleClientset([]runtime.Object{cm}...) + mock := ConfigMapWatcher{clientset: client} + + // When + test, err := mock.GetStaticKubelinterConfig(context.Background()) - // Assert - assert.NoError(t, err) - assert.Equal(t, []string{"check", "check2"}, test) + // Assert + assert.NoError(t, err) + assert.Equal(t, testCase.checks, test.Checks) + }) + } } From 7453525da60d440b758f51937d83ca1dbdd4e456 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Mon, 5 Jun 2023 19:15:54 +0200 Subject: [PATCH 05/19] Refactor yaml unmarshalling and Config casting --- pkg/controller/configmap_watcher.go | 31 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/pkg/controller/configmap_watcher.go b/pkg/controller/configmap_watcher.go index f1d7e902..03ce466a 100644 --- a/pkg/controller/configmap_watcher.go +++ b/pkg/controller/configmap_watcher.go @@ -63,14 +63,7 @@ func (cmw *ConfigMapWatcher) GetStaticKubelinterConfig(ctx context.Context) (con return cfg, fmt.Errorf("gathering starting configmap: %w", err) } - errYaml := yaml.Unmarshal([]byte(cm.Data[configMapDataAccess]), &cmw.checks) - if errYaml != nil { - return cfg, fmt.Errorf("unmarshalling configmap data: %w", err) - } - - cfg.Checks = config.ChecksConfig(cmw.checks.Checks) - - return cfg, nil + return cmw.getKubeLinterConfig(cm.Data[configMapDataAccess]) } // StartInformer will update the channel structure with new configuration data from ConfigMap update event @@ -82,22 +75,16 @@ func (cmw *ConfigMapWatcher) StartInformer(ctx context.Context) error { informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ // nolint:errcheck UpdateFunc: func(oldObj, newObj interface{}) { - oldCm := oldObj.(*apicorev1.ConfigMap) newCm := newObj.(*apicorev1.ConfigMap) - fmt.Printf("oldCm: %v\n", oldCm) fmt.Printf("ConfigMap updated: %s/%s\n", newCm.Namespace, newCm.Name) - var cfg config.Config - - err := yaml.Unmarshal([]byte(newCm.Data[configMapDataAccess]), &cmw.checks) + cfg, err := cmw.getKubeLinterConfig(newCm.Data[configMapDataAccess]) if err != nil { fmt.Printf("Error: unmarshalling configmap data: %s", err.Error()) return } - cfg.Checks = config.ChecksConfig(cmw.checks.Checks) - cmw.ch <- cfg }, }) @@ -111,3 +98,17 @@ func (cmw *ConfigMapWatcher) StartInformer(ctx context.Context) error { func (cmw *ConfigMapWatcher) ConfigChanged() <-chan config.Config { return cmw.ch } + +// TODO -> doc +func (cmw *ConfigMapWatcher) getKubeLinterConfig(data string) (config.Config, error) { + var cfg config.Config + + err := yaml.Unmarshal([]byte(data), &cmw.checks) + if err != nil { + return cfg, fmt.Errorf("unmarshalling configmap data: %w", err) + } + + cfg.Checks = config.ChecksConfig(cmw.checks.Checks) + + return cfg, nil +} From 898731612e5ff3c04e2b35a1ab8688de6a289400 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 7 Jun 2023 19:05:34 +0200 Subject: [PATCH 06/19] Update missing documentation --- pkg/controller/configmap_watcher.go | 7 ++++--- pkg/validations/validation_engine.go | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/controller/configmap_watcher.go b/pkg/controller/configmap_watcher.go index 03ce466a..5b6131d1 100644 --- a/pkg/controller/configmap_watcher.go +++ b/pkg/controller/configmap_watcher.go @@ -17,7 +17,7 @@ import ( ) // this structure mirrors Kube-Linter configuration structure -// it is used to unmarshall ConfigMap data +// it is used as a bridge to unmarshall ConfigMap data // doc: https://pkg.go.dev/golang.stackrox.io/kube-linter/pkg/config#Config type KubeLinterChecks struct { Checks struct { @@ -35,7 +35,7 @@ type ConfigMapWatcher struct { ch chan config.Config } -var configMapName = "deployment-validation-operator-config" +var configMapName = "deployment-validation-operator-custom-config" var configMapNamespace = "deployment-validation-operator" var configMapDataAccess = "deployment-validation-operator-config.yaml" @@ -99,7 +99,8 @@ func (cmw *ConfigMapWatcher) ConfigChanged() <-chan config.Config { return cmw.ch } -// TODO -> doc +// getKubeLinterConfig returns a valid Kube-linter Config structure +// based on the checks received by the string func (cmw *ConfigMapWatcher) getKubeLinterConfig(data string) (config.Config, error) { var cfg config.Config diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index 8b022159..da64466b 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -178,7 +178,8 @@ func InitializeValidationEngine(configPath string, reg PrometheusRegistry) error return err } -// TODO -> Doc +// InitializeValidationEngineFromConfig initialize the validation engine with a custom Config. +// It keeps compatibility with the current default initialization func InitializeValidationEngineFromConfig(cfg config.Config, reg PrometheusRegistry) error { ve := validationEngine{ config: cfg, From 38ba35ef117d515f3beaf387ac79a60385745ec4 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 7 Jun 2023 19:06:02 +0200 Subject: [PATCH 07/19] Update yaml default disabled checks --- config.example.yaml | 8 ++++++++ deploy/openshift/configmap.yaml | 2 ++ deploy/openshift/deployment-validation-operator-olm.yaml | 2 ++ hack/olm-registry/olm-artifacts-template.yaml | 2 ++ 4 files changed, 14 insertions(+) diff --git a/config.example.yaml b/config.example.yaml index 14ffa309..4d568d26 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -6,3 +6,11 @@ checks: # explicitly opt-out of checks that are not relevant using Exclude. # Takes precedence over doNotAutoAddDefaults, if both are set. addAllBuiltIn: true + + # exclude will remove a set of checks from the validations. + # It is used when addAllBuiltIn is set to true. + exclude: ["check1", "check2"] + + # include will add a set of checks to the validations. + # It is used when addAllBuiltIn is set to false. + include: ["check1", "check2"] \ No newline at end of file diff --git a/deploy/openshift/configmap.yaml b/deploy/openshift/configmap.yaml index 945aa2c8..de68cda5 100644 --- a/deploy/openshift/configmap.yaml +++ b/deploy/openshift/configmap.yaml @@ -15,3 +15,5 @@ data: # explicitly opt-out of checks that are not relevant using Exclude. # Takes precedence over doNotAutoAddDefaults, if both are set. addAllBuiltIn: true + + exclude: ["access-to-create-pods", "access-to-secrets", "cluster-admin-role-binding", "default-service-account", "deprecated-service-account-field", "docker-sock", "drop-net-raw-capability", "env-var-secret", "exposed-services", "latest-tag", "mismatching-selector", "no-extensions-v1beta", "no-liveness-probe", "no-read-only-root-fs", "no-readiness-probe", "no-rolling-update-strategy", "privileged-ports", "read-secret-from-env-var", "required-annotation-email", "required-label-owner", "sensitive-host-mounts", "ssh-port", "unsafe-proc-mount", "use-namespace", "wildcard-in-rules", "writable-host-mount"] \ No newline at end of file diff --git a/deploy/openshift/deployment-validation-operator-olm.yaml b/deploy/openshift/deployment-validation-operator-olm.yaml index cd1b73c1..74ddfcb3 100644 --- a/deploy/openshift/deployment-validation-operator-olm.yaml +++ b/deploy/openshift/deployment-validation-operator-olm.yaml @@ -50,6 +50,8 @@ objects: # explicitly opt-out of checks that are not relevant using Exclude. # Takes precedence over doNotAutoAddDefaults, if both are set. addAllBuiltIn: true + + exclude: ["access-to-create-pods", "access-to-secrets", "cluster-admin-role-binding", "default-service-account", "deprecated-service-account-field", "docker-sock", "drop-net-raw-capability", "env-var-secret", "exposed-services", "latest-tag", "mismatching-selector", "no-extensions-v1beta", "no-liveness-probe", "no-read-only-root-fs", "no-readiness-probe", "no-rolling-update-strategy", "privileged-ports", "read-secret-from-env-var", "required-annotation-email", "required-label-owner", "sensitive-host-mounts", "ssh-port", "unsafe-proc-mount", "use-namespace", "wildcard-in-rules", "writable-host-mount"] - apiVersion: v1 kind: Service metadata: diff --git a/hack/olm-registry/olm-artifacts-template.yaml b/hack/olm-registry/olm-artifacts-template.yaml index 5ef48d3e..47af7c3b 100644 --- a/hack/olm-registry/olm-artifacts-template.yaml +++ b/hack/olm-registry/olm-artifacts-template.yaml @@ -150,3 +150,5 @@ objects: # explicitly opt-out of checks that are not relevant using Exclude. # Takes precedence over doNotAutoAddDefaults, if both are set. addAllBuiltIn: true + + exclude: ["access-to-create-pods", "access-to-secrets", "cluster-admin-role-binding", "default-service-account", "deprecated-service-account-field", "docker-sock", "drop-net-raw-capability", "env-var-secret", "exposed-services", "latest-tag", "mismatching-selector", "no-extensions-v1beta", "no-liveness-probe", "no-read-only-root-fs", "no-readiness-probe", "no-rolling-update-strategy", "privileged-ports", "read-secret-from-env-var", "required-annotation-email", "required-label-owner", "sensitive-host-mounts", "ssh-port", "unsafe-proc-mount", "use-namespace", "wildcard-in-rules", "writable-host-mount"] From b3e047c367a792de7bcee34126ea9c58b4289157 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 7 Jun 2023 19:10:31 +0200 Subject: [PATCH 08/19] Remove unused hardcode for disabled checks --- pkg/validations/base_test.go | 3 +- pkg/validations/validation_engine.go | 53 +--------------------------- 2 files changed, 2 insertions(+), 54 deletions(-) diff --git a/pkg/validations/base_test.go b/pkg/validations/base_test.go index 698c594b..b79dfdf5 100644 --- a/pkg/validations/base_test.go +++ b/pkg/validations/base_test.go @@ -225,12 +225,11 @@ func TestIncompatibleChecksAreDisabled(t *testing.T) { } badChecks := getIncompatibleChecks() - disabledChecks := getDisabledChecks() allKubeLinterChecks, err := getAllBuiltInKubeLinterChecks() if err != nil { t.Fatalf("Got unexpected error while getting all checks built-into kube-linter: %v", err) } - expectedNumChecks := (len(allKubeLinterChecks) - len(badChecks)) - len(disabledChecks) + expectedNumChecks := (len(allKubeLinterChecks) - len(badChecks)) enabledChecks := engine.EnabledChecks() if len(enabledChecks) != expectedNumChecks { diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index da64466b..95857fe7 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -76,7 +76,7 @@ type PrometheusRegistry interface { func (ve *validationEngine) InitRegistry(promReg PrometheusRegistry) error { disableIncompatibleChecks(&ve.config) - disableChecks(&ve.config) + //disableChecks(&ve.config) registry := checkregistry.New() if err := builtinchecks.LoadInto(registry); err != nil { @@ -221,54 +221,3 @@ func getIncompatibleChecks() []string { "non-isolated-pod", } } - -// disableChecks will forcibly update a kube-linter config -// to disable checks that do not have supporting openshift documentation -func disableChecks(c *config.Config) { - c.Checks.Exclude = append(c.Checks.Exclude, getDisabledChecks()...) -} - -// getDisabledChecks returns an array of kube-linter check names that are disabled for DVO -// These checks are disabled as they do not have supporting Openshift documentation -// 38 checks... 47 checks according to kube-linter website -func getDisabledChecks() []string { - return []string{ - "access-to-create-pods", - "access-to-secrets", - "cluster-admin-role-binding", - "default-service-account", - "deprecated-service-account-field", - "docker-sock", - "drop-net-raw-capability", - "env-var-secret", - "exposed-services", - // "host-ipc", - // "host-network", - // "host-pid", - "latest-tag", - // "minimum-three-replicas", - "mismatching-selector", - // "no-anti-affinity", - "no-extensions-v1beta", - "no-liveness-probe", - "no-read-only-root-fs", - "no-readiness-probe", - "no-rolling-update-strategy", - // "privilege-escalation-container", - // "privileged-container", - "privileged-ports", - "read-secret-from-env-var", - "required-annotation-email", - "required-label-owner", - // "run-as-non-root", - "sensitive-host-mounts", - "ssh-port", - "unsafe-proc-mount", - // "unsafe-sysctls", - // "unset-cpu-requirements", - // "unset-memory-requirements", - "use-namespace", - "wildcard-in-rules", - "writable-host-mount", - } -} From 8d7ff43b07e23974610f553e6c930aa67ef7cd09 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 7 Jun 2023 19:32:00 +0200 Subject: [PATCH 09/19] Fix copy-paste conditional --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 46ec9929..bc016aa5 100644 --- a/main.go +++ b/main.go @@ -147,7 +147,7 @@ func setupManager(log logr.Logger, opts options.Options) (manager.Manager, error log.Info("Initializing Validation Engine") // Try to retrieve custom configuration from existing ConfigMap - if kbcfg, err := getCustomConfig(cfg); err != nil { + if kbcfg, err := getCustomConfig(cfg); err == nil { log.Info("Gather Kube-Linter configuration from ConfigMap") if err := validations.InitializeValidationEngineFromConfig(*kbcfg, reg); err != nil { From 8e1656ca1d281c4b4c74252d75880d47ecd72705 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Thu, 8 Jun 2023 17:17:02 +0200 Subject: [PATCH 10/19] Cleanup --- .gitignore | 3 +++ pkg/validations/validation_engine.go | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d0a8dc79..db6e730c 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ build/_output/* # go vendor + +# local dev default configmap +config/deployment-validation-operator-config.yaml \ No newline at end of file diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index 95857fe7..95f58b45 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -76,7 +76,6 @@ type PrometheusRegistry interface { func (ve *validationEngine) InitRegistry(promReg PrometheusRegistry) error { disableIncompatibleChecks(&ve.config) - //disableChecks(&ve.config) registry := checkregistry.New() if err := builtinchecks.LoadInto(registry); err != nil { From 4e5e588703a343cbe636bc07b3ffaf32ebfd48a7 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Mon, 12 Jun 2023 17:53:17 +0200 Subject: [PATCH 11/19] Fix error return styling --- pkg/validations/validation_engine.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index 95f58b45..e0bfc1db 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -165,16 +165,19 @@ func InitializeValidationEngine(configPath string, reg PrometheusRegistry) error ve := validationEngine{} err := ve.LoadConfig(configPath) - if err == nil { - err = ve.InitRegistry(reg) + if err != nil { + return err } - // Only replace the exisiting engine if no errors occurred - if err == nil { - engine = ve + err = ve.InitRegistry(reg) + if err != nil { + return err } - return err + // Only replace the exisiting engine if no errors occurred + engine = ve + + return nil } // InitializeValidationEngineFromConfig initialize the validation engine with a custom Config. @@ -185,11 +188,13 @@ func InitializeValidationEngineFromConfig(cfg config.Config, reg PrometheusRegis } err := ve.InitRegistry(reg) - if err == nil { - engine = ve + if err != nil { + return err } - return err + engine = ve + + return nil } func (ve *validationEngine) GetCheckByName(name string) (config.Check, error) { From 706ce15736bb10be6e4571f1b20e0756996cc9e8 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Tue, 13 Jun 2023 09:46:36 +0200 Subject: [PATCH 12/19] Rollback Valiidation engine initialization --- main.go | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/main.go b/main.go index bc016aa5..dce83e60 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "errors" "fmt" "os" @@ -10,6 +9,9 @@ import ( "strings" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/client-go/rest" + apis "github.com/app-sre/deployment-validation-operator/api" dvconfig "github.com/app-sre/deployment-validation-operator/config" "github.com/app-sre/deployment-validation-operator/internal/options" @@ -17,15 +19,13 @@ import ( dvo_prom "github.com/app-sre/deployment-validation-operator/pkg/prometheus" "github.com/app-sre/deployment-validation-operator/pkg/validations" "github.com/app-sre/deployment-validation-operator/version" + "github.com/prometheus/client_golang/prometheus" + "github.com/go-logr/logr" osappsv1 "github.com/openshift/api/apps/v1" - "github.com/prometheus/client_golang/prometheus" - kubelinterCfg "golang.stackrox.io/kube-linter/pkg/config" k8sruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/discovery" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/healthz" @@ -146,16 +146,7 @@ func setupManager(log logr.Logger, opts options.Options) (manager.Manager, error log.Info("Initializing Validation Engine") - // Try to retrieve custom configuration from existing ConfigMap - if kbcfg, err := getCustomConfig(cfg); err == nil { - log.Info("Gather Kube-Linter configuration from ConfigMap") - - if err := validations.InitializeValidationEngineFromConfig(*kbcfg, reg); err != nil { - return nil, fmt.Errorf("initializing validation engine: %w", err) - } - - // or Initialize VE from default - } else if err := validations.InitializeValidationEngine(opts.ConfigFile, reg); err != nil { + if err := validations.InitializeValidationEngine(opts.ConfigFile, reg); err != nil { return nil, fmt.Errorf("initializing validation engine: %w", err) } @@ -244,19 +235,3 @@ func kubeClientQPS() (float32, error) { qps = float32(val) return qps, err } - -// getCustomConfig returns a custom Kube-Linter configuration -// it retrieves data from a ConfigMap if there is any valid -func getCustomConfig(cfg *rest.Config) (*kubelinterCfg.Config, error) { - cmw, err := controller.NewConfigMapWatcher(cfg) - if err != nil { - return nil, fmt.Errorf("getting kube-linter checks configuration from configmap: %w", err) - } - - klCfg, err := cmw.GetStaticKubelinterConfig(context.Background()) - if err != nil { - return nil, fmt.Errorf("getting custom configuration (configmap): %w", err) - } - - return &klCfg, nil -} From 9123988fd2341be75340829e02537ac5eb19418c Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Tue, 13 Jun 2023 09:53:11 +0200 Subject: [PATCH 13/19] Rollback Validation engine initialization --- pkg/validations/validation_engine.go | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index e0bfc1db..16608e31 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -180,23 +180,6 @@ func InitializeValidationEngine(configPath string, reg PrometheusRegistry) error return nil } -// InitializeValidationEngineFromConfig initialize the validation engine with a custom Config. -// It keeps compatibility with the current default initialization -func InitializeValidationEngineFromConfig(cfg config.Config, reg PrometheusRegistry) error { - ve := validationEngine{ - config: cfg, - } - - err := ve.InitRegistry(reg) - if err != nil { - return err - } - - engine = ve - - return nil -} - func (ve *validationEngine) GetCheckByName(name string) (config.Check, error) { check, ok := ve.registeredChecks[name] if !ok { From 40113ba7e4b58c69c9a57a3f1a3400fb27c148a7 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Tue, 13 Jun 2023 10:17:16 +0200 Subject: [PATCH 14/19] Fix loglines style --- pkg/controller/configmap_watcher.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/controller/configmap_watcher.go b/pkg/controller/configmap_watcher.go index 5b6131d1..b8a1669c 100644 --- a/pkg/controller/configmap_watcher.go +++ b/pkg/controller/configmap_watcher.go @@ -14,6 +14,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/log" ) // this structure mirrors Kube-Linter configuration structure @@ -35,7 +36,7 @@ type ConfigMapWatcher struct { ch chan config.Config } -var configMapName = "deployment-validation-operator-custom-config" +var configMapName = "deployment-validation-operator-config" var configMapNamespace = "deployment-validation-operator" var configMapDataAccess = "deployment-validation-operator-config.yaml" @@ -55,12 +56,10 @@ func NewConfigMapWatcher(cfg *rest.Config) (ConfigMapWatcher, error) { // GetStaticKubelinterConfig returns the ConfigMap's checks configuration func (cmw *ConfigMapWatcher) GetStaticKubelinterConfig(ctx context.Context) (config.Config, error) { - var cfg config.Config - cm, err := cmw.clientset.CoreV1(). ConfigMaps(configMapNamespace).Get(ctx, configMapName, v1.GetOptions{}) if err != nil { - return cfg, fmt.Errorf("gathering starting configmap: %w", err) + return config.Config{}, fmt.Errorf("getting initial configuration: %w", err) } return cmw.getKubeLinterConfig(cm.Data[configMapDataAccess]) @@ -77,11 +76,12 @@ func (cmw *ConfigMapWatcher) StartInformer(ctx context.Context) error { UpdateFunc: func(oldObj, newObj interface{}) { newCm := newObj.(*apicorev1.ConfigMap) - fmt.Printf("ConfigMap updated: %s/%s\n", newCm.Namespace, newCm.Name) + logger := log.Log.WithName("ConfigMapWatcher") + logger.Info("ConfigMap has been updated") cfg, err := cmw.getKubeLinterConfig(newCm.Data[configMapDataAccess]) if err != nil { - fmt.Printf("Error: unmarshalling configmap data: %s", err.Error()) + logger.Error(err, "ConfigMap data format") return } From 145dade112b3f9a0c0165331ceba6a90f9ccbc7b Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Tue, 13 Jun 2023 19:12:50 +0200 Subject: [PATCH 15/19] Add logger to configmapwatcher --- pkg/controller/configmap_watcher.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/controller/configmap_watcher.go b/pkg/controller/configmap_watcher.go index b8a1669c..31b574ab 100644 --- a/pkg/controller/configmap_watcher.go +++ b/pkg/controller/configmap_watcher.go @@ -8,6 +8,7 @@ import ( "golang.stackrox.io/kube-linter/pkg/config" "gopkg.in/yaml.v3" + "github.com/go-logr/logr" apicorev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/informers" @@ -34,6 +35,7 @@ type ConfigMapWatcher struct { clientset kubernetes.Interface checks KubeLinterChecks ch chan config.Config + logger logr.Logger } var configMapName = "deployment-validation-operator-config" @@ -51,6 +53,7 @@ func NewConfigMapWatcher(cfg *rest.Config) (ConfigMapWatcher, error) { return ConfigMapWatcher{ clientset: clientset, + logger: log.Log.WithName("ConfigMapWatcher"), }, nil } @@ -76,12 +79,11 @@ func (cmw *ConfigMapWatcher) StartInformer(ctx context.Context) error { UpdateFunc: func(oldObj, newObj interface{}) { newCm := newObj.(*apicorev1.ConfigMap) - logger := log.Log.WithName("ConfigMapWatcher") - logger.Info("ConfigMap has been updated") + cmw.logger.Info("ConfigMap has been updated") cfg, err := cmw.getKubeLinterConfig(newCm.Data[configMapDataAccess]) if err != nil { - logger.Error(err, "ConfigMap data format") + cmw.logger.Error(err, "ConfigMap data format") return } From f5cad092673289420e9a843013a36b53dedf1442 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 14 Jun 2023 11:58:10 +0200 Subject: [PATCH 16/19] Update documentation --- README.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ecdc824d..0d40237e 100644 --- a/README.md +++ b/README.md @@ -99,29 +99,24 @@ The metrics generated by DVO can be scraped by anything that understands prometh oc process --local NAMESPACE='some-namespace' -f deploy/openshift/network-policies.yaml | oc create -f - ``` -## Enabling Checks +## Configuring Checks -In the validation engine file is a function called getDisabledChecks(). Comment out the check you would like to have available to the user base of DVO and push the change. +DVO performs validation checks using kube-linter. The checks configuration is mirrored to the one for the kube-linter project. More information on configuration options can be found [here](https://github.com/stackrox/kube-linter/blob/main/docs/configuring-kubelinter.md), and a list of available checks can be found [here](https://github.com/stackrox/kube-linter/blob/main/docs/generated/checks.md). -``` -Location of file -../pkg/validations/validation_engine.go -``` - -Documentation of currently allowed checks can be found [here](./docs/checks.md) +To configure DVO with a different set of checks, create a ConfigMap in the cluster with the new checks configuration. An example of a configuration ConfigMap can be found [here](./deploy/openshift/configmap.yaml). -## Disabling Checks +**constraint**: Currently, the configuration isn't continuously monitored and is only checked at startup. If a new set of checks is configured in a ConfigMap, the pod running DVO will need to be rebooted. -In the current state of DVO, all validation checks are performed with [kube-linter](https://github.com/stackrox/kube-linter). +### Enabling checks -kube-linter supports functionality for [ignoring violations for a particular kubernetes object](https://github.com/stackrox/kube-linter/blob/main/docs/configuring-kubelinter.md#ignoring-violations-for-specific-cases). This functionality is also supported through DVO. +To enable all checks, set the `addAllBuiltIn` property to `true`. If you only want to enable individual checks, include them as a collection in the `include` property and leave `addAllBuiltIn` with a value of `false`. +The `include` property can work together with `doNotAutoAddDefaults` set to `true` in a whitelisting way. Only the checks collection passed in `include` will be executed. -In the validation engine file is a function called getDisabledChecks(). Comment the check you would like to have disabled to the user base of DVO and push the change. +### Disabling checks -``` -Location of file -../pkg/validations/validation_engine.go -``` +To disable all checks, set the `doNotAutoAddDefaults` property to `true`. If you only want to disable individual checks, include them as a collection in the `exclude` property and leave `doNotAutoAddDefaults` with a value of `false` +The `exclude` property takes precedence over the `include` property. If a particular check is in both collections, it will be excluded by default. +The `exclude` property can work in conjunction with `addAllBuiltIn` set to `true` in a blacklisting fashion. All checks will be triggered and only the checks passed in `exclude` will be ignored. ## Tests From 33280a7078f5f542df6083398ecab3c274400ec7 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 14 Jun 2023 12:20:54 +0200 Subject: [PATCH 17/19] Revert "Remove unused hardcode for disabled checks" This reverts commit b3e047c367a792de7bcee34126ea9c58b4289157. --- pkg/validations/base_test.go | 3 +- pkg/validations/validation_engine.go | 52 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/pkg/validations/base_test.go b/pkg/validations/base_test.go index b79dfdf5..698c594b 100644 --- a/pkg/validations/base_test.go +++ b/pkg/validations/base_test.go @@ -225,11 +225,12 @@ func TestIncompatibleChecksAreDisabled(t *testing.T) { } badChecks := getIncompatibleChecks() + disabledChecks := getDisabledChecks() allKubeLinterChecks, err := getAllBuiltInKubeLinterChecks() if err != nil { t.Fatalf("Got unexpected error while getting all checks built-into kube-linter: %v", err) } - expectedNumChecks := (len(allKubeLinterChecks) - len(badChecks)) + expectedNumChecks := (len(allKubeLinterChecks) - len(badChecks)) - len(disabledChecks) enabledChecks := engine.EnabledChecks() if len(enabledChecks) != expectedNumChecks { diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index 16608e31..abdacb17 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -76,6 +76,7 @@ type PrometheusRegistry interface { func (ve *validationEngine) InitRegistry(promReg PrometheusRegistry) error { disableIncompatibleChecks(&ve.config) + disableChecks(&ve.config) registry := checkregistry.New() if err := builtinchecks.LoadInto(registry); err != nil { @@ -208,3 +209,54 @@ func getIncompatibleChecks() []string { "non-isolated-pod", } } + +// disableChecks will forcibly update a kube-linter config +// to disable checks that do not have supporting openshift documentation +func disableChecks(c *config.Config) { + c.Checks.Exclude = append(c.Checks.Exclude, getDisabledChecks()...) +} + +// getDisabledChecks returns an array of kube-linter check names that are disabled for DVO +// These checks are disabled as they do not have supporting Openshift documentation +// 38 checks... 47 checks according to kube-linter website +func getDisabledChecks() []string { + return []string{ + "access-to-create-pods", + "access-to-secrets", + "cluster-admin-role-binding", + "default-service-account", + "deprecated-service-account-field", + "docker-sock", + "drop-net-raw-capability", + "env-var-secret", + "exposed-services", + // "host-ipc", + // "host-network", + // "host-pid", + "latest-tag", + // "minimum-three-replicas", + "mismatching-selector", + // "no-anti-affinity", + "no-extensions-v1beta", + "no-liveness-probe", + "no-read-only-root-fs", + "no-readiness-probe", + "no-rolling-update-strategy", + // "privilege-escalation-container", + // "privileged-container", + "privileged-ports", + "read-secret-from-env-var", + "required-annotation-email", + "required-label-owner", + // "run-as-non-root", + "sensitive-host-mounts", + "ssh-port", + "unsafe-proc-mount", + // "unsafe-sysctls", + // "unset-cpu-requirements", + // "unset-memory-requirements", + "use-namespace", + "wildcard-in-rules", + "writable-host-mount", + } +} From b9ce584f7d461c6d68d1bc52f38912f2cab5e188 Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 14 Jun 2023 12:28:22 +0200 Subject: [PATCH 18/19] Add default configuration if no configmap is detected --- README.md | 3 +++ pkg/validations/validation_engine.go | 28 +++++++--------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 0d40237e..a1540da3 100644 --- a/README.md +++ b/README.md @@ -110,12 +110,15 @@ To configure DVO with a different set of checks, create a ConfigMap in the clust ### Enabling checks To enable all checks, set the `addAllBuiltIn` property to `true`. If you only want to enable individual checks, include them as a collection in the `include` property and leave `addAllBuiltIn` with a value of `false`. + The `include` property can work together with `doNotAutoAddDefaults` set to `true` in a whitelisting way. Only the checks collection passed in `include` will be executed. ### Disabling checks To disable all checks, set the `doNotAutoAddDefaults` property to `true`. If you only want to disable individual checks, include them as a collection in the `exclude` property and leave `doNotAutoAddDefaults` with a value of `false` + The `exclude` property takes precedence over the `include` property. If a particular check is in both collections, it will be excluded by default. + The `exclude` property can work in conjunction with `addAllBuiltIn` set to `true` in a blacklisting fashion. All checks will be triggered and only the checks passed in `exclude` will be ignored. ## Tests diff --git a/pkg/validations/validation_engine.go b/pkg/validations/validation_engine.go index abdacb17..780c6ccc 100644 --- a/pkg/validations/validation_engine.go +++ b/pkg/validations/validation_engine.go @@ -52,13 +52,17 @@ func fileExists(filename string) bool { } func (ve *validationEngine) LoadConfig(path string) error { - v := viper.New() - if !fileExists(path) { log.Info(fmt.Sprintf("config file %s does not exist. Use default configuration", path)) - path = "" + // legacy disabled checks + ve.config.Checks.Exclude = getDisabledChecks() + ve.config.Checks.AddAllBuiltIn = true + + return nil } + v := viper.New() + // Load Configuration config, err := config.Load(v, path) if err != nil { @@ -76,7 +80,6 @@ type PrometheusRegistry interface { func (ve *validationEngine) InitRegistry(promReg PrometheusRegistry) error { disableIncompatibleChecks(&ve.config) - disableChecks(&ve.config) registry := checkregistry.New() if err := builtinchecks.LoadInto(registry); err != nil { @@ -210,12 +213,6 @@ func getIncompatibleChecks() []string { } } -// disableChecks will forcibly update a kube-linter config -// to disable checks that do not have supporting openshift documentation -func disableChecks(c *config.Config) { - c.Checks.Exclude = append(c.Checks.Exclude, getDisabledChecks()...) -} - // getDisabledChecks returns an array of kube-linter check names that are disabled for DVO // These checks are disabled as they do not have supporting Openshift documentation // 38 checks... 47 checks according to kube-linter website @@ -230,31 +227,20 @@ func getDisabledChecks() []string { "drop-net-raw-capability", "env-var-secret", "exposed-services", - // "host-ipc", - // "host-network", - // "host-pid", "latest-tag", - // "minimum-three-replicas", "mismatching-selector", - // "no-anti-affinity", "no-extensions-v1beta", "no-liveness-probe", "no-read-only-root-fs", "no-readiness-probe", "no-rolling-update-strategy", - // "privilege-escalation-container", - // "privileged-container", "privileged-ports", "read-secret-from-env-var", "required-annotation-email", "required-label-owner", - // "run-as-non-root", "sensitive-host-mounts", "ssh-port", "unsafe-proc-mount", - // "unsafe-sysctls", - // "unset-cpu-requirements", - // "unset-memory-requirements", "use-namespace", "wildcard-in-rules", "writable-host-mount", From 88b7b6c7ad849b0d0ae681619b95e5290a4268aa Mon Sep 17 00:00:00 2001 From: Isaac Jimeno Date: Wed, 14 Jun 2023 12:35:01 +0200 Subject: [PATCH 19/19] Fix base tests after change revert --- pkg/validations/base_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/validations/base_test.go b/pkg/validations/base_test.go index 698c594b..b79dfdf5 100644 --- a/pkg/validations/base_test.go +++ b/pkg/validations/base_test.go @@ -225,12 +225,11 @@ func TestIncompatibleChecksAreDisabled(t *testing.T) { } badChecks := getIncompatibleChecks() - disabledChecks := getDisabledChecks() allKubeLinterChecks, err := getAllBuiltInKubeLinterChecks() if err != nil { t.Fatalf("Got unexpected error while getting all checks built-into kube-linter: %v", err) } - expectedNumChecks := (len(allKubeLinterChecks) - len(badChecks)) - len(disabledChecks) + expectedNumChecks := (len(allKubeLinterChecks) - len(badChecks)) enabledChecks := engine.EnabledChecks() if len(enabledChecks) != expectedNumChecks {