diff --git a/charts/kyverno/README.md b/charts/kyverno/README.md index 6733bea672..963b5db9f4 100644 --- a/charts/kyverno/README.md +++ b/charts/kyverno/README.md @@ -136,7 +136,7 @@ The command removes all the Kubernetes components associated with the chart and | initImage.repository | string | `"ghcr.io/kyverno/kyvernopre"` | Image repository | | initImage.tag | string | `nil` | Image tag If initImage.tag is missing, defaults to image.tag | | initImage.pullPolicy | string | `nil` | Image pull policy If initImage.pullPolicy is missing, defaults to image.pullPolicy | -| initContainer.extraArgs | list | `["--loggingFormat=text"]` | Extra arguments to give to the kyvernopre binary. | +| initContainer.extraArgs | list | `["--loggingFormat=text","--exceptionNamespace={{ include \"kyverno.namespace\" . }}"]` | Extra arguments to give to the kyvernopre binary. | | testImage.registry | string | `nil` | Image registry | | testImage.repository | string | `"busybox"` | Image repository | | testImage.tag | string | `nil` | Image tag Defaults to `latest` if omitted | diff --git a/charts/kyverno/values.yaml b/charts/kyverno/values.yaml index e6b091cfd1..97d310842c 100644 --- a/charts/kyverno/values.yaml +++ b/charts/kyverno/values.yaml @@ -65,6 +65,7 @@ initContainer: # -- Extra arguments to give to the kyvernopre binary. extraArgs: - --loggingFormat=text + - --exceptionNamespace={{ include "kyverno.namespace" . }} testImage: diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 102335cb5a..b5444100a2 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -34,6 +34,7 @@ import ( resourcereportcontroller "github.com/kyverno/kyverno/pkg/controllers/report/resource" webhookcontroller "github.com/kyverno/kyverno/pkg/controllers/webhook" "github.com/kyverno/kyverno/pkg/cosign" + "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context/resolvers" "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/leaderelection" @@ -172,6 +173,8 @@ func createReportControllers( backgroundScanInterval time.Duration, configuration config.Configuration, eventGenerator event.Interface, + enablePolicyException bool, + exceptionNamespace string, ) ([]internal.Controller, func(context.Context) error) { var ctrls []internal.Controller var warmups []func(context.Context) error @@ -215,6 +218,15 @@ func createReportControllers( )) } if backgroundScan { + var exceptionsLister engine.PolicyExceptionLister + if enablePolicyException { + lister := kyvernoV2Alpha1.PolicyExceptions().Lister() + if exceptionNamespace != "" { + exceptionsLister = lister.PolicyExceptions(exceptionNamespace) + } else { + exceptionsLister = lister + } + } ctrls = append(ctrls, internal.NewController( backgroundscancontroller.ControllerName, backgroundscancontroller.NewController( @@ -225,7 +237,7 @@ func createReportControllers( kyvernoV1.Policies(), kyvernoV1.ClusterPolicies(), kubeInformer.Core().V1().Namespaces(), - kyvernoV2Alpha1.PolicyExceptions(), + exceptionsLister, resourceReportController, configMapResolver, backgroundScanInterval, @@ -269,6 +281,8 @@ func createrLeaderControllers( runtime runtimeutils.Runtime, configMapResolver resolvers.ConfigmapResolver, backgroundScanInterval time.Duration, + enablePolicyException bool, + exceptionNamespace string, ) ([]internal.Controller, func(context.Context) error, error) { policyCtrl, err := policy.NewPolicyController( kyvernoClient, @@ -349,6 +363,8 @@ func createrLeaderControllers( backgroundScanInterval, configuration, eventGenerator, + enablePolicyException, + exceptionNamespace, ) return append( []internal.Controller{ @@ -383,6 +399,8 @@ func main() { dumpPayload bool leaderElectionRetryPeriod time.Duration backgroundScanInterval time.Duration + enablePolicyException bool + exceptionNamespace string ) flagset := flag.NewFlagSet("kyverno", flag.ExitOnError) flagset.BoolVar(&dumpPayload, "dumpPayload", false, "Set this flag to activate/deactivate debug mode.") @@ -403,6 +421,8 @@ func main() { flagset.IntVar(&backgroundScanWorkers, "backgroundScanWorkers", backgroundscancontroller.Workers, "Configure the number of background scan workers.") flagset.DurationVar(&leaderElectionRetryPeriod, "leaderElectionRetryPeriod", leaderelection.DefaultRetryPeriod, "Configure leader election retry period.") flagset.DurationVar(&backgroundScanInterval, "backgroundScanInterval", time.Hour, "Configure background scan interval.") + flagset.StringVar(&exceptionNamespace, "exceptionNamespace", "", "Configure the namespace to accept PolicyExceptions.") + flagset.BoolVar(&enablePolicyException, "enablePolicyException", false, "Enable PolicyException feature.") // config appConfig := internal.NewConfiguration( internal.WithProfiling(), @@ -586,6 +606,8 @@ func main() { runtime, configMapResolver, backgroundScanInterval, + enablePolicyException, + exceptionNamespace, ) if err != nil { logger.Error(err, "failed to create leader controllers") @@ -642,6 +664,15 @@ func main() { dClient, openApiManager, ) + var exceptionsLister engine.PolicyExceptionLister + if enablePolicyException { + lister := kyvernoInformer.Kyverno().V2alpha1().PolicyExceptions().Lister() + if exceptionNamespace != "" { + exceptionsLister = lister.PolicyExceptions(exceptionNamespace) + } else { + exceptionsLister = lister + } + } resourceHandlers := webhooksresource.NewHandlers( dClient, kyvernoClient, @@ -654,7 +685,7 @@ func main() { kubeInformer.Rbac().V1().RoleBindings().Lister(), kubeInformer.Rbac().V1().ClusterRoleBindings().Lister(), kyvernoInformer.Kyverno().V1beta1().UpdateRequests().Lister().UpdateRequests(config.KyvernoNamespace()), - kyvernoInformer.Kyverno().V2alpha1().PolicyExceptions().Lister(), + exceptionsLister, urgen, eventGenerator, openApiManager, diff --git a/cmd/reports-controller/main.go b/cmd/reports-controller/main.go index b1742ca883..643dbda8bc 100644 --- a/cmd/reports-controller/main.go +++ b/cmd/reports-controller/main.go @@ -132,7 +132,7 @@ func createReportControllers( kyvernoV1.Policies(), kyvernoV1.ClusterPolicies(), kubeInformer.Core().V1().Namespaces(), - kyvernoV2Alpha1.PolicyExceptions(), + kyvernoV2Alpha1.PolicyExceptions().Lister(), resourceReportController, configMapResolver, backgroundScanInterval, diff --git a/config/install.yaml b/config/install.yaml index 0e02b4d34f..f4d8c6ffb7 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -32325,6 +32325,7 @@ spec: imagePullPolicy: IfNotPresent args: - --loggingFormat=text + - --exceptionNamespace=kyverno resources: limits: cpu: 100m diff --git a/pkg/controllers/report/background/controller.go b/pkg/controllers/report/background/controller.go index 55e23ec995..b64ba65535 100644 --- a/pkg/controllers/report/background/controller.go +++ b/pkg/controllers/report/background/controller.go @@ -11,14 +11,13 @@ import ( policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" - kyvernov2alpha1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2alpha1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/controllers" "github.com/kyverno/kyverno/pkg/controllers/report/resource" "github.com/kyverno/kyverno/pkg/controllers/report/utils" + "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context/resolvers" "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/registryclient" @@ -57,7 +56,7 @@ type controller struct { bgscanrLister cache.GenericLister cbgscanrLister cache.GenericLister nsLister corev1listers.NamespaceLister - polexLister kyvernov2alpha1listers.PolicyExceptionLister + polexLister engine.PolicyExceptionLister // queue queue workqueue.RateLimitingInterface @@ -80,7 +79,7 @@ func NewController( polInformer kyvernov1informers.PolicyInformer, cpolInformer kyvernov1informers.ClusterPolicyInformer, nsInformer corev1informers.NamespaceInformer, - polexInformer kyvernov2alpha1informers.PolicyExceptionInformer, + polexLister engine.PolicyExceptionLister, metadataCache resource.MetadataCache, informerCacheResolvers resolvers.ConfigmapResolver, forceDelay time.Duration, @@ -99,7 +98,7 @@ func NewController( bgscanrLister: bgscanr.Lister(), cbgscanrLister: cbgscanr.Lister(), nsLister: nsInformer.Lister(), - polexLister: polexInformer.Lister(), + polexLister: polexLister, queue: queue, metadataCache: metadataCache, informerCacheResolvers: informerCacheResolvers, diff --git a/pkg/controllers/report/utils/scanner.go b/pkg/controllers/report/utils/scanner.go index 7183a91b75..7c7e19620f 100644 --- a/pkg/controllers/report/utils/scanner.go +++ b/pkg/controllers/report/utils/scanner.go @@ -5,7 +5,6 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/engine" @@ -22,7 +21,7 @@ type scanner struct { client dclient.Interface rclient registryclient.Client informerCacheResolvers resolvers.ConfigmapResolver - polexLister kyvernov2alpha1listers.PolicyExceptionLister + polexLister engine.PolicyExceptionLister excludeGroupRole []string config config.Configuration } @@ -41,7 +40,7 @@ func NewScanner( client dclient.Interface, rclient registryclient.Client, informerCacheResolvers resolvers.ConfigmapResolver, - polexLister kyvernov2alpha1listers.PolicyExceptionLister, + polexLister engine.PolicyExceptionLister, config config.Configuration, excludeGroupRole ...string, ) Scanner { diff --git a/pkg/engine/policyContext.go b/pkg/engine/policyContext.go index 5caa4fc3f8..9498f5ae12 100644 --- a/pkg/engine/policyContext.go +++ b/pkg/engine/policyContext.go @@ -4,7 +4,6 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" enginectx "github.com/kyverno/kyverno/pkg/engine/context" @@ -21,6 +20,12 @@ import ( // ExcludeFunc is a function used to determine if a resource is excluded type ExcludeFunc = func(kind, namespace, name string) bool +type PolicyExceptionLister interface { + // List lists all PolicyExceptions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*kyvernov2alpha1.PolicyException, err error) +} + // PolicyContext contains the contexts for engine to process type PolicyContext struct { // policy is the policy to be processed @@ -80,7 +85,7 @@ type PolicyContext struct { } // peLister list all policy exceptions - peLister kyvernov2alpha1listers.PolicyExceptionLister + peLister PolicyExceptionLister } // Getters @@ -222,7 +227,7 @@ func (c *PolicyContext) WithSubresourcesInPolicy(subresourcesInPolicy []struct { return copy } -func (c *PolicyContext) WithExceptions(peLister kyvernov2alpha1listers.PolicyExceptionLister) *PolicyContext { +func (c *PolicyContext) WithExceptions(peLister PolicyExceptionLister) *PolicyContext { copy := c.Copy() copy.peLister = peLister return copy @@ -249,7 +254,7 @@ func NewPolicyContextFromAdmissionRequest( configuration config.Configuration, client dclient.Interface, informerCacheResolver resolvers.ConfigmapResolver, - peLister kyvernov2alpha1listers.PolicyExceptionLister, + polexLister PolicyExceptionLister, ) (*PolicyContext, error) { ctx, err := newVariablesContext(request, &admissionInfo) if err != nil { @@ -273,7 +278,7 @@ func NewPolicyContextFromAdmissionRequest( WithInformerCacheResolver(informerCacheResolver). WithRequestResource(*requestResource). WithSubresource(request.SubResource). - WithExceptions(peLister) + WithExceptions(polexLister) return policyContext, nil } diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go index 51251ba60e..07ef85a73f 100644 --- a/pkg/webhooks/resource/handlers.go +++ b/pkg/webhooks/resource/handlers.go @@ -10,9 +10,9 @@ import ( kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" + "github.com/kyverno/kyverno/pkg/engine" enginectx "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/context/resolvers" "github.com/kyverno/kyverno/pkg/event" @@ -50,11 +50,11 @@ type handlers struct { pCache policycache.Cache // listers - nsLister corev1listers.NamespaceLister - rbLister rbacv1listers.RoleBindingLister - crbLister rbacv1listers.ClusterRoleBindingLister - urLister kyvernov1beta1listers.UpdateRequestNamespaceLister - peLister kyvernov2alpha1listers.PolicyExceptionLister + nsLister corev1listers.NamespaceLister + rbLister rbacv1listers.RoleBindingLister + crbLister rbacv1listers.ClusterRoleBindingLister + urLister kyvernov1beta1listers.UpdateRequestNamespaceLister + polexLister engine.PolicyExceptionLister urGenerator webhookgenerate.Generator eventGen event.Interface @@ -77,7 +77,7 @@ func NewHandlers( rbLister rbacv1listers.RoleBindingLister, crbLister rbacv1listers.ClusterRoleBindingLister, urLister kyvernov1beta1listers.UpdateRequestNamespaceLister, - peLister kyvernov2alpha1listers.PolicyExceptionLister, + polexLister engine.PolicyExceptionLister, urGenerator webhookgenerate.Generator, eventGen event.Interface, openApiManager openapi.ValidateInterface, @@ -94,11 +94,11 @@ func NewHandlers( rbLister: rbLister, crbLister: crbLister, urLister: urLister, - peLister: peLister, + polexLister: polexLister, urGenerator: urGenerator, eventGen: eventGen, openApiManager: openApiManager, - pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, client, rbLister, crbLister, informerCacheResolvers, peLister), + pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, client, rbLister, crbLister, informerCacheResolvers, polexLister), urUpdater: webhookutils.NewUpdateRequestUpdater(kyvernoClient, urLister), admissionReports: admissionReports, } diff --git a/pkg/webhooks/utils/policy_context_builder.go b/pkg/webhooks/utils/policy_context_builder.go index a0fd63be10..6737566f27 100644 --- a/pkg/webhooks/utils/policy_context_builder.go +++ b/pkg/webhooks/utils/policy_context_builder.go @@ -2,7 +2,6 @@ package utils import ( kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/engine" @@ -23,7 +22,7 @@ type policyContextBuilder struct { rbLister rbacv1listers.RoleBindingLister crbLister rbacv1listers.ClusterRoleBindingLister informerCacheResolvers resolvers.ConfigmapResolver - peLister kyvernov2alpha1listers.PolicyExceptionLister + polexLister engine.PolicyExceptionLister } func NewPolicyContextBuilder( @@ -32,7 +31,7 @@ func NewPolicyContextBuilder( rbLister rbacv1listers.RoleBindingLister, crbLister rbacv1listers.ClusterRoleBindingLister, informerCacheResolvers resolvers.ConfigmapResolver, - peLister kyvernov2alpha1listers.PolicyExceptionLister, + polexLister engine.PolicyExceptionLister, ) PolicyContextBuilder { return &policyContextBuilder{ configuration: configuration, @@ -40,7 +39,7 @@ func NewPolicyContextBuilder( rbLister: rbLister, crbLister: crbLister, informerCacheResolvers: informerCacheResolvers, - peLister: peLister, + polexLister: polexLister, } } @@ -54,5 +53,5 @@ func (b *policyContextBuilder) Build(request *admissionv1.AdmissionRequest) (*en userRequestInfo.Roles = roles userRequestInfo.ClusterRoles = clusterRoles } - return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, b.configuration, b.client, b.informerCacheResolvers, b.peLister) + return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, b.configuration, b.client, b.informerCacheResolvers, b.polexLister) } diff --git a/scripts/config/dev/kyverno.yaml b/scripts/config/dev/kyverno.yaml index 4150a247b2..ef4c0f7317 100644 --- a/scripts/config/dev/kyverno.yaml +++ b/scripts/config/dev/kyverno.yaml @@ -7,6 +7,7 @@ extraArgs: - --enableTracing - --tracingAddress=tempo.monitoring - --tracingPort=4317 + - --enablePolicyException serviceMonitor: enabled: true diff --git a/scripts/config/standard/kyverno.yaml b/scripts/config/standard/kyverno.yaml index 9cbbcab5b2..b9c670c4f3 100644 --- a/scripts/config/standard/kyverno.yaml +++ b/scripts/config/standard/kyverno.yaml @@ -4,6 +4,7 @@ initContainer: extraArgs: - --loggingFormat=json + - --enablePolicyException cleanupController: rbac: