From a710cccb7a9f03eeb737105674c8108780b42e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 5 Apr 2023 13:50:29 +0200 Subject: [PATCH] fix: replace background sa name in config by a flag (#6790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- charts/kyverno/README.md | 1 - .../admission-controller/deployment.yaml | 1 + .../kyverno/templates/config/configmap.yaml | 7 ---- charts/kyverno/values.yaml | 3 -- cmd/kyverno/main.go | 33 +++++++++-------- config/install-latest-testing.yaml | 2 +- pkg/config/config.go | 16 -------- pkg/webhooks/resource/handlers.go | 37 ++++++++++--------- pkg/webhooks/resource/updaterequest.go | 7 +--- 9 files changed, 42 insertions(+), 65 deletions(-) diff --git a/charts/kyverno/README.md b/charts/kyverno/README.md index 6f6d97aee9..81805768d4 100644 --- a/charts/kyverno/README.md +++ b/charts/kyverno/README.md @@ -204,7 +204,6 @@ The command removes all the Kubernetes components associated with the chart and | config.defaultRegistry | string | `"docker.io"` | The registry hostname used for the image mutation. | | config.excludeGroups | list | `[]` | Exclude groups | | config.excludeUsernames | list | `[]` | Exclude usernames | -| config.excludeBackgroundUsernames | list | `[]` | Exclude usernames for mutateExisting and generate policies | | config.generateSuccessEvents | bool | `false` | Generate success events. | | config.resourceFilters | list | See [values.yaml](values.yaml) | Resource types to be skipped by the Kyverno policy engine. Make sure to surround each entry in quotes so that it doesn't get parsed as a nested YAML list. These are joined together without spaces, run through `tpl`, and the result is set in the config map. | | config.webhooks | list | `[]` | Defines the `namespaceSelector` in the webhook configurations. Note that it takes a list of `namespaceSelector` and/or `objectSelector` in the JSON format, and only the first element will be forwarded to the webhook configurations. The Kyverno namespace is excluded if `excludeKyvernoNamespace` is `true` (default) | diff --git a/charts/kyverno/templates/admission-controller/deployment.yaml b/charts/kyverno/templates/admission-controller/deployment.yaml index 0247c09366..0a0fa685f4 100644 --- a/charts/kyverno/templates/admission-controller/deployment.yaml +++ b/charts/kyverno/templates/admission-controller/deployment.yaml @@ -119,6 +119,7 @@ spec: image: {{ include "kyverno.image" (dict "image" .Values.admissionController.container.image "defaultTag" .Chart.AppVersion) | quote }} imagePullPolicy: {{ .Values.admissionController.container.image.pullPolicy }} args: + - --backgroundServiceAccountName='system:serviceaccount:{{ include "kyverno.namespace" . }}:{{ include "kyverno.background-controller.serviceAccountName" . }}' - --servicePort={{ .Values.admissionController.service.port }} - --loggingFormat={{ .Values.admissionController.logging.format }} {{- if .Values.admissionController.tracing.enabled }} diff --git a/charts/kyverno/templates/config/configmap.yaml b/charts/kyverno/templates/config/configmap.yaml index 88c8c0a935..16dfbd3648 100644 --- a/charts/kyverno/templates/config/configmap.yaml +++ b/charts/kyverno/templates/config/configmap.yaml @@ -28,13 +28,6 @@ data: {{- with .Values.config.excludeClusterRoles }} excludeClusterRoles: {{ join "," . | quote }} {{- end -}} - {{- $backgroundUsernames := (printf "system:serviceaccount:%s:%s" (include "kyverno.namespace" .) (include "kyverno.background-controller.serviceAccountName" .)) }} - {{- if .Values.config.excludeBackgroundUsernames }} - {{- $backgroundUsernames = prepend .Values.config.excludeBackgroundUsernames $backgroundUsernames}} - excludeBackgroundUsernames: {{ join "," $backgroundUsernames | quote }} - {{- else }} - excludeBackgroundUsernames: {{ $backgroundUsernames }} - {{- end -}} {{- if .Values.config.resourceFilters }} resourceFilters: {{ include "kyverno.config.resourceFilters" . | quote }} {{- end -}} diff --git a/charts/kyverno/values.yaml b/charts/kyverno/values.yaml index 10c4d728f0..cf353de9cd 100644 --- a/charts/kyverno/values.yaml +++ b/charts/kyverno/values.yaml @@ -55,9 +55,6 @@ config: # -- Exclude usernames excludeUsernames: [] - # -- Exclude usernames for mutateExisting and generate policies - excludeBackgroundUsernames: [] - # -- Generate success events. generateSuccessEvents: false diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 2e086f8122..12670b53ba 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -216,21 +216,22 @@ func main() { var ( // TODO: this has been added to backward support command line arguments // will be removed in future and the configuration will be set only via configmaps - serverIP string - webhookTimeout int - genWorkers int - maxQueuedEvents int - autoUpdateWebhooks bool - imagePullSecrets string - imageSignatureRepository string - allowInsecureRegistry bool - webhookRegistrationTimeout time.Duration - admissionReports bool - dumpPayload bool - leaderElectionRetryPeriod time.Duration - enablePolicyException bool - exceptionNamespace string - servicePort int + serverIP string + webhookTimeout int + genWorkers int + maxQueuedEvents int + autoUpdateWebhooks bool + imagePullSecrets string + imageSignatureRepository string + allowInsecureRegistry bool + webhookRegistrationTimeout time.Duration + admissionReports bool + dumpPayload bool + leaderElectionRetryPeriod time.Duration + enablePolicyException bool + exceptionNamespace string + servicePort int + backgroundServiceAccountName string ) flagset := flag.NewFlagSet("kyverno", flag.ExitOnError) flagset.BoolVar(&dumpPayload, "dumpPayload", false, "Set this flag to activate/deactivate debug mode.") @@ -250,6 +251,7 @@ func main() { flagset.StringVar(&exceptionNamespace, "exceptionNamespace", "", "Configure the namespace to accept PolicyExceptions.") flagset.BoolVar(&enablePolicyException, "enablePolicyException", false, "Enable PolicyException feature.") flagset.IntVar(&servicePort, "servicePort", 443, "Port used by the Kyverno Service resource and for webhook configurations.") + flagset.StringVar(&backgroundServiceAccountName, "backgroundServiceAccountName", "", "Background service account name.") // config appConfig := internal.NewConfiguration( internal.WithProfiling(), @@ -518,6 +520,7 @@ func main() { eventGenerator, openApiManager, admissionReports, + backgroundServiceAccountName, ) exceptionHandlers := webhooksexception.NewHandlers(exception.ValidationOptions{ Enabled: enablePolicyException, diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml index 36740936bf..620c92a4c0 100644 --- a/config/install-latest-testing.yaml +++ b/config/install-latest-testing.yaml @@ -66,7 +66,6 @@ data: enableDefaultRegistryMutation: "true" defaultRegistry: "docker.io" generateSuccessEvents: "false" - excludeBackgroundUsernames: system:serviceaccount:kyverno:kyverno-background-controller resourceFilters: "[*,kyverno,*][Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][SelfSubjectAccessReview,*,*][Binding,*,*][ReplicaSet,*,*][AdmissionReport,*,*][ClusterAdmissionReport,*,*][BackgroundScanReport,*,*][ClusterBackgroundScanReport,*,*][ClusterRole,*,kyverno:admission-controller][ClusterRole,*,kyverno:admission-controller:core][ClusterRole,*,kyverno:admission-controller:additional][ClusterRole,*,kyverno:background-controller][ClusterRole,*,kyverno:background-controller:core][ClusterRole,*,kyverno:background-controller:additional][ClusterRole,*,kyverno:cleanup-controller][ClusterRole,*,kyverno:cleanup-controller:core][ClusterRole,*,kyverno:cleanup-controller:additional][ClusterRole,*,kyverno:reports-controller][ClusterRole,*,kyverno:reports-controller:core][ClusterRole,*,kyverno:reports-controller:additional][ClusterRoleBinding,*,kyverno:admission-controller][ClusterRoleBinding,*,kyverno:background-controller][ClusterRoleBinding,*,kyverno:cleanup-controller][ClusterRoleBinding,*,kyverno:reports-controller][ServiceAccount,kyverno,kyverno-admission-controller][ServiceAccount,kyverno,kyverno-background-controller][ServiceAccount,kyverno,kyverno-cleanup-controller][ServiceAccount,kyverno,kyverno-reports-controller][Role,kyverno,kyverno:admission-controller][Role,kyverno,kyverno:background-controller][Role,kyverno,kyverno:cleanup-controller][Role,kyverno,kyverno:reports-controller][RoleBinding,kyverno,kyverno:admission-controller][RoleBinding,kyverno,kyverno:background-controller][RoleBinding,kyverno,kyverno:cleanup-controller][RoleBinding,kyverno,kyverno:reports-controller][ConfigMap,kyverno,kyverno][ConfigMap,kyverno,kyverno-metrics][Deployment,kyverno,kyverno-admission-controller][Deployment,kyverno,kyverno-background-controller][Deployment,kyverno,kyverno-cleanup-controller][Deployment,kyverno,kyverno-reports-controller][Pod,kyverno,kyverno-admission-controller-*][Pod,kyverno,kyverno-background-controller-*][Pod,kyverno,kyverno-cleanup-controller-*][Pod,kyverno,kyverno-reports-controller-*][Job,kyverno,kyverno-hook-pre-delete][NetworkPolicy,kyverno,kyverno-admission-controller][NetworkPolicy,kyverno,kyverno-background-controller][NetworkPolicy,kyverno,kyverno-cleanup-controller][NetworkPolicy,kyverno,kyverno-reports-controller][PodDisruptionBudget,kyverno,kyverno-admission-controller][PodDisruptionBudget,kyverno,kyverno-background-controller][PodDisruptionBudget,kyverno,kyverno-cleanup-controller][PodDisruptionBudget,kyverno,kyverno-reports-controller][Service,kyverno,kyverno-svc][Service,kyverno,kyverno-svc-metrics][Service,kyverno,kyverno-background-controller-metrics][Service,kyverno,kyverno-cleanup-controller][Service,kyverno,kyverno-cleanup-controller-metrics][Service,kyverno,kyverno-reports-controller-metrics][ServiceMonitor,kyverno,kyverno-admission-controller][ServiceMonitor,kyverno,kyverno-background-controller][ServiceMonitor,kyverno,kyverno-cleanup-controller][ServiceMonitor,kyverno,kyverno-reports-controller][Secret,kyverno,kyverno-svc.kyverno.svc.*][Secret,kyverno,kyverno-cleanup-controller.kyverno.svc.*]" webhooks: '[{"namespaceSelector": {"matchExpressions": [{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["kyverno"]}]}}]' --- @@ -34610,6 +34609,7 @@ spec: image: "ghcr.io/kyverno/kyverno:latest" imagePullPolicy: IfNotPresent args: + - --backgroundServiceAccountName='system:serviceaccount:kyverno:kyverno-background-controller' - --servicePort=443 - --loggingFormat=text - --disableMetrics=false diff --git a/pkg/config/config.go b/pkg/config/config.go index 19216f8382..2294ea9957 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -147,8 +147,6 @@ type Configuration interface { GetExcludedRoles() []string // GetExcludedClusterRoles return excluded roles GetExcludedClusterRoles() []string - // GetExcludedBackgroundUsernames return exclude usernames for mutateExisting and generate policies - GetExcludedBackgroundUsernames() []string // GetGenerateSuccessEvents return if should generate success events GetGenerateSuccessEvents() bool // GetWebhooks returns the webhook configs @@ -168,7 +166,6 @@ type configuration struct { excludedUsernames []string excludedRoles []string excludedClusterRoles []string - excludeBackgroundUsernames []string filters []filter generateSuccessEvents bool webhooks []WebhookConfig @@ -249,12 +246,6 @@ func (cd *configuration) GetExcludedClusterRoles() []string { return cd.excludedClusterRoles } -func (cd *configuration) GetExcludedBackgroundUsernames() []string { - cd.mux.RLock() - defer cd.mux.RUnlock() - return cd.excludeBackgroundUsernames -} - func (cd *configuration) GetExcludedGroups() []string { cd.mux.RLock() defer cd.mux.RUnlock() @@ -356,13 +347,6 @@ func (cd *configuration) load(cm *corev1.ConfigMap) { } else { cd.excludedClusterRoles = parseStrings(excludedClusterRoles) } - // load excludeBackgroundUsernames - excludeBackgroundUsernames, ok := cm.Data["excludeBackgroundUsernames"] - if !ok { - logger.V(6).Info("configuration: No excludeBackgroundUsernames defined in ConfigMap") - } else { - cd.excludeBackgroundUsernames = parseStrings(excludeBackgroundUsernames) - } // load generateSuccessEvents generateSuccessEvents, ok := cm.Data["generateSuccessEvents"] if ok { diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go index b9e01f3b02..50bac956a4 100644 --- a/pkg/webhooks/resource/handlers.go +++ b/pkg/webhooks/resource/handlers.go @@ -59,7 +59,8 @@ type resourceHandlers struct { openApiManager openapi.ValidateInterface pcBuilder webhookutils.PolicyContextBuilder - admissionReports bool + admissionReports bool + backgroungServiceAccountName string } func NewHandlers( @@ -80,24 +81,26 @@ func NewHandlers( eventGen event.Interface, openApiManager openapi.ValidateInterface, admissionReports bool, + backgroungServiceAccountName string, ) webhooks.ResourceHandlers { return &resourceHandlers{ - engine: engine, - client: client, - kyvernoClient: kyvernoClient, - rclient: rclient, - configuration: configuration, - metricsConfig: metricsConfig, - pCache: pCache, - nsLister: nsLister, - urLister: urLister, - cpolLister: cpolInformer.Lister(), - polLister: polInformer.Lister(), - urGenerator: urGenerator, - eventGen: eventGen, - openApiManager: openApiManager, - pcBuilder: webhookutils.NewPolicyContextBuilder(configuration), - admissionReports: admissionReports, + engine: engine, + client: client, + kyvernoClient: kyvernoClient, + rclient: rclient, + configuration: configuration, + metricsConfig: metricsConfig, + pCache: pCache, + nsLister: nsLister, + urLister: urLister, + cpolLister: cpolInformer.Lister(), + polLister: polInformer.Lister(), + urGenerator: urGenerator, + eventGen: eventGen, + openApiManager: openApiManager, + pcBuilder: webhookutils.NewPolicyContextBuilder(configuration), + admissionReports: admissionReports, + backgroungServiceAccountName: backgroungServiceAccountName, } } diff --git a/pkg/webhooks/resource/updaterequest.go b/pkg/webhooks/resource/updaterequest.go index b49a8a491e..b8d732862f 100644 --- a/pkg/webhooks/resource/updaterequest.go +++ b/pkg/webhooks/resource/updaterequest.go @@ -11,17 +11,14 @@ import ( "github.com/kyverno/kyverno/pkg/engine" engineapi "github.com/kyverno/kyverno/pkg/engine/api" "github.com/kyverno/kyverno/pkg/event" - "github.com/kyverno/kyverno/pkg/utils/wildcard" "github.com/kyverno/kyverno/pkg/webhooks/resource/generation" admissionv1 "k8s.io/api/admission/v1" ) // handleBackgroundApplies applies generate and mutateExisting policies, and creates update requests for background reconcile func (h *resourceHandlers) handleBackgroundApplies(ctx context.Context, logger logr.Logger, request admissionv1.AdmissionRequest, policyContext *engine.PolicyContext, generatePolicies, mutatePolicies []kyvernov1.PolicyInterface, ts time.Time) { - for _, username := range h.configuration.GetExcludedBackgroundUsernames() { - if wildcard.Match(username, policyContext.AdmissionInfo().AdmissionUserInfo.Username) { - return - } + if h.backgroungServiceAccountName == policyContext.AdmissionInfo().AdmissionUserInfo.Username { + return } go h.handleMutateExisting(ctx, logger, request, mutatePolicies, policyContext, ts) h.handleGenerate(ctx, logger, request, generatePolicies, policyContext, ts)