mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
feat: add helm configuration for reporting in different rules (#11376)
* feat: add helm configuration for reporting in different rules (forgot signoff) Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: linter and tests Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * feat: rename reporting.imageVerification Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> --------- Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
fcb5cb1c1b
commit
ec546e6fb4
27 changed files with 268 additions and 106 deletions
|
@ -327,7 +327,11 @@ The chart values are organised per component.
|
||||||
| features.aggregateReports.enabled | bool | `true` | Enables the feature |
|
| features.aggregateReports.enabled | bool | `true` | Enables the feature |
|
||||||
| features.policyReports.enabled | bool | `true` | Enables the feature |
|
| features.policyReports.enabled | bool | `true` | Enables the feature |
|
||||||
| features.validatingAdmissionPolicyReports.enabled | bool | `false` | Enables the feature |
|
| features.validatingAdmissionPolicyReports.enabled | bool | `false` | Enables the feature |
|
||||||
| features.backgroundReports.enabled | bool | `true` | Enables the feature |
|
| features.reporting.validate | bool | `true` | Enables the feature |
|
||||||
|
| features.reporting.mutate | bool | `true` | Enables the feature |
|
||||||
|
| features.reporting.mutateExisting | bool | `true` | Enables the feature |
|
||||||
|
| features.reporting.imageVerify | bool | `true` | Enables the feature |
|
||||||
|
| features.reporting.generate | bool | `true` | Enables the feature |
|
||||||
| features.autoUpdateWebhooks.enabled | bool | `true` | Enables the feature |
|
| features.autoUpdateWebhooks.enabled | bool | `true` | Enables the feature |
|
||||||
| features.backgroundScan.enabled | bool | `true` | Enables the feature |
|
| features.backgroundScan.enabled | bool | `true` | Enables the feature |
|
||||||
| features.backgroundScan.backgroundScanWorkers | int | `2` | Number of background scan workers |
|
| features.backgroundScan.backgroundScanWorkers | int | `2` | Number of background scan workers |
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
{{- with .validatingAdmissionPolicyReports -}}
|
{{- with .validatingAdmissionPolicyReports -}}
|
||||||
{{- $flags = append $flags (print "--validatingAdmissionPolicyReports=" .enabled) -}}
|
{{- $flags = append $flags (print "--validatingAdmissionPolicyReports=" .enabled) -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- with .backgroundReports -}}
|
|
||||||
{{- $flags = append $flags (print "--backgroundReports=" .enabled) -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- with .autoUpdateWebhooks -}}
|
{{- with .autoUpdateWebhooks -}}
|
||||||
{{- $flags = append $flags (print "--autoUpdateWebhooks=" .enabled) -}}
|
{{- $flags = append $flags (print "--autoUpdateWebhooks=" .enabled) -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
@ -97,6 +94,25 @@
|
||||||
{{- $flags = append $flags (print "--tufRootRaw=" .) -}}
|
{{- $flags = append $flags (print "--tufRootRaw=" .) -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
{{- with .reporting -}}
|
||||||
|
{{- $reportingConfig := list -}}
|
||||||
|
{{- with .validate -}}
|
||||||
|
{{- $reportingConfig = append $reportingConfig "validate" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .mutate -}}
|
||||||
|
{{- $reportingConfig = append $reportingConfig "mutate" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .mutateExisting -}}
|
||||||
|
{{- $reportingConfig = append $reportingConfig "mutateExisting" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .imageVerify -}}
|
||||||
|
{{- $reportingConfig = append $reportingConfig "imageVerify" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .generate -}}
|
||||||
|
{{- $reportingConfig = append $reportingConfig "generate" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $flags = append $flags (print "--enableReporting=" (join "," $reportingConfig)) -}}
|
||||||
|
{{- end -}}
|
||||||
{{- with $flags -}}
|
{{- with $flags -}}
|
||||||
{{- toYaml . -}}
|
{{- toYaml . -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
|
@ -174,6 +174,7 @@ spec:
|
||||||
- --imagePullSecrets={{- join "," (concat (keys .Values.imagePullSecrets) .Values.existingImagePullSecrets) }}
|
- --imagePullSecrets={{- join "," (concat (keys .Values.imagePullSecrets) .Values.existingImagePullSecrets) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.admissionController.featuresOverride)
|
{{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.admissionController.featuresOverride)
|
||||||
|
"reporting"
|
||||||
"admissionReports"
|
"admissionReports"
|
||||||
"autoUpdateWebhooks"
|
"autoUpdateWebhooks"
|
||||||
"configMapCaching"
|
"configMapCaching"
|
||||||
|
|
|
@ -119,7 +119,7 @@ spec:
|
||||||
- --imagePullSecrets={{- join "," (concat (keys .Values.imagePullSecrets) .Values.existingImagePullSecrets) }}
|
- --imagePullSecrets={{- join "," (concat (keys .Values.imagePullSecrets) .Values.existingImagePullSecrets) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.backgroundController.featuresOverride)
|
{{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.backgroundController.featuresOverride)
|
||||||
"backgroundReports"
|
"reporting"
|
||||||
"configMapCaching"
|
"configMapCaching"
|
||||||
"deferredLoading"
|
"deferredLoading"
|
||||||
"globalContext"
|
"globalContext"
|
||||||
|
|
|
@ -119,6 +119,7 @@ spec:
|
||||||
- --imagePullSecrets={{- join "," (concat (keys .Values.imagePullSecrets) .Values.existingImagePullSecrets) }}
|
- --imagePullSecrets={{- join "," (concat (keys .Values.imagePullSecrets) .Values.existingImagePullSecrets) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.reportsController.featuresOverride)
|
{{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.reportsController.featuresOverride)
|
||||||
|
"reporting"
|
||||||
"admissionReports"
|
"admissionReports"
|
||||||
"aggregateReports"
|
"aggregateReports"
|
||||||
"policyReports"
|
"policyReports"
|
||||||
|
|
|
@ -636,9 +636,17 @@ features:
|
||||||
validatingAdmissionPolicyReports:
|
validatingAdmissionPolicyReports:
|
||||||
# -- Enables the feature
|
# -- Enables the feature
|
||||||
enabled: false
|
enabled: false
|
||||||
backgroundReports:
|
reporting:
|
||||||
# -- Enables the feature
|
# -- Enables the feature
|
||||||
enabled: true
|
validate: true
|
||||||
|
# -- Enables the feature
|
||||||
|
mutate: true
|
||||||
|
# -- Enables the feature
|
||||||
|
mutateExisting: true
|
||||||
|
# -- Enables the feature
|
||||||
|
imageVerify: true
|
||||||
|
# -- Enables the feature
|
||||||
|
generate: true
|
||||||
autoUpdateWebhooks:
|
autoUpdateWebhooks:
|
||||||
# -- Enables the feature
|
# -- Enables the feature
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/policy"
|
"github.com/kyverno/kyverno/pkg/policy"
|
||||||
"github.com/kyverno/kyverno/pkg/utils/generator"
|
"github.com/kyverno/kyverno/pkg/utils/generator"
|
||||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
apiserver "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
apiserver "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
kubeinformers "k8s.io/client-go/informers"
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
kyamlopenapi "sigs.k8s.io/kustomize/kyaml/openapi"
|
kyamlopenapi "sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
|
@ -55,7 +56,7 @@ func createrLeaderControllers(
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
backgroundScanInterval time.Duration,
|
backgroundScanInterval time.Duration,
|
||||||
urGenerator generator.UpdateRequestGenerator,
|
urGenerator generator.UpdateRequestGenerator,
|
||||||
backgroundReports bool,
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) ([]internal.Controller, error) {
|
) ([]internal.Controller, error) {
|
||||||
policyCtrl, err := policy.NewPolicyController(
|
policyCtrl, err := policy.NewPolicyController(
|
||||||
|
@ -88,7 +89,7 @@ func createrLeaderControllers(
|
||||||
eventGenerator,
|
eventGenerator,
|
||||||
configuration,
|
configuration,
|
||||||
jp,
|
jp,
|
||||||
backgroundReports,
|
reportsConfig,
|
||||||
reportsBreaker,
|
reportsBreaker,
|
||||||
)
|
)
|
||||||
return []internal.Controller{
|
return []internal.Controller{
|
||||||
|
@ -103,7 +104,6 @@ func main() {
|
||||||
maxQueuedEvents int
|
maxQueuedEvents int
|
||||||
omitEvents string
|
omitEvents string
|
||||||
maxAPICallResponseLength int64
|
maxAPICallResponseLength int64
|
||||||
backgroundReports bool
|
|
||||||
maxBackgroundReports int
|
maxBackgroundReports int
|
||||||
)
|
)
|
||||||
flagset := flag.NewFlagSet("updaterequest-controller", flag.ExitOnError)
|
flagset := flag.NewFlagSet("updaterequest-controller", flag.ExitOnError)
|
||||||
|
@ -112,7 +112,6 @@ func main() {
|
||||||
flagset.StringVar(&omitEvents, "omitEvents", "", "Set this flag to a comma sperated list of PolicyViolation, PolicyApplied, PolicyError, PolicySkipped to disable events, e.g. --omitEvents=PolicyApplied,PolicyViolation")
|
flagset.StringVar(&omitEvents, "omitEvents", "", "Set this flag to a comma sperated list of PolicyViolation, PolicyApplied, PolicyError, PolicySkipped to disable events, e.g. --omitEvents=PolicyApplied,PolicyViolation")
|
||||||
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 2*1000*1000, "Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended).")
|
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 2*1000*1000, "Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended).")
|
||||||
flagset.IntVar(&maxBackgroundReports, "maxBackgroundReports", 10000, "Maximum number of ephemeralreports created for the background policies.")
|
flagset.IntVar(&maxBackgroundReports, "maxBackgroundReports", 10000, "Maximum number of ephemeralreports created for the background policies.")
|
||||||
flagset.BoolVar(&backgroundReports, "backgroundReports", true, "Enables or disables reports for mutate existing and generate rules.")
|
|
||||||
|
|
||||||
// config
|
// config
|
||||||
appConfig := internal.NewConfiguration(
|
appConfig := internal.NewConfiguration(
|
||||||
|
@ -132,6 +131,7 @@ func main() {
|
||||||
internal.WithApiServerClient(),
|
internal.WithApiServerClient(),
|
||||||
internal.WithMetadataClient(),
|
internal.WithMetadataClient(),
|
||||||
internal.WithFlagSets(flagset),
|
internal.WithFlagSets(flagset),
|
||||||
|
internal.WithReporting(),
|
||||||
)
|
)
|
||||||
// parse flags
|
// parse flags
|
||||||
internal.ParseFlags(appConfig)
|
internal.ParseFlags(appConfig)
|
||||||
|
@ -252,7 +252,7 @@ func main() {
|
||||||
setup.Jp,
|
setup.Jp,
|
||||||
bgscanInterval,
|
bgscanInterval,
|
||||||
urGenerator,
|
urGenerator,
|
||||||
backgroundReports,
|
setup.ReportingConfiguration,
|
||||||
reportsBreaker,
|
reportsBreaker,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -22,6 +22,7 @@ type Configuration interface {
|
||||||
UsesMetadataClient() bool
|
UsesMetadataClient() bool
|
||||||
UsesKyvernoDynamicClient() bool
|
UsesKyvernoDynamicClient() bool
|
||||||
UsesEventsClient() bool
|
UsesEventsClient() bool
|
||||||
|
UsesReporting() bool
|
||||||
FlagSets() []*flag.FlagSet
|
FlagSets() []*flag.FlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +146,12 @@ func WithFlagSets(flagsets ...*flag.FlagSet) ConfigurationOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithReporting() ConfigurationOption {
|
||||||
|
return func(c *configuration) {
|
||||||
|
c.usesReporting = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type configuration struct {
|
type configuration struct {
|
||||||
usesMetrics bool
|
usesMetrics bool
|
||||||
usesTracing bool
|
usesTracing bool
|
||||||
|
@ -163,6 +170,7 @@ type configuration struct {
|
||||||
usesMetadataClient bool
|
usesMetadataClient bool
|
||||||
usesKyvernoDynamicClient bool
|
usesKyvernoDynamicClient bool
|
||||||
usesEventsClient bool
|
usesEventsClient bool
|
||||||
|
usesReporting bool
|
||||||
flagSets []*flag.FlagSet
|
flagSets []*flag.FlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +242,10 @@ func (c *configuration) UsesEventsClient() bool {
|
||||||
return c.usesEventsClient
|
return c.usesEventsClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *configuration) UsesReporting() bool {
|
||||||
|
return c.usesReporting
|
||||||
|
}
|
||||||
|
|
||||||
func (c *configuration) FlagSets() []*flag.FlagSet {
|
func (c *configuration) FlagSets() []*flag.FlagSet {
|
||||||
return c.flagSets
|
return c.flagSets
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ var (
|
||||||
imageVerifyCacheMaxSize int64
|
imageVerifyCacheMaxSize int64
|
||||||
// global context
|
// global context
|
||||||
enableGlobalContext bool
|
enableGlobalContext bool
|
||||||
|
// reporting
|
||||||
|
enableReporting string
|
||||||
)
|
)
|
||||||
|
|
||||||
func initLoggingFlags() {
|
func initLoggingFlags() {
|
||||||
|
@ -137,6 +139,10 @@ func initCleanupFlags() {
|
||||||
flag.StringVar(&cleanupServerPort, "cleanupServerPort", "9443", "kyverno cleanup server port, defaults to '9443'.")
|
flag.StringVar(&cleanupServerPort, "cleanupServerPort", "9443", "kyverno cleanup server port, defaults to '9443'.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initReportingFlags() {
|
||||||
|
flag.StringVar(&enableReporting, "enableReporting", "validate,mutate,mutateExisting,generate,imageVerify", "Comma separated list to enables reporting for different rule types. (validate,mutate,mutateExisting,generate,imageVerify)")
|
||||||
|
}
|
||||||
|
|
||||||
type options struct {
|
type options struct {
|
||||||
clientRateLimitQPS float64
|
clientRateLimitQPS float64
|
||||||
clientRateLimitBurst int
|
clientRateLimitBurst int
|
||||||
|
@ -220,6 +226,11 @@ func initFlags(config Configuration, opts ...Option) {
|
||||||
if config.UsesLeaderElection() {
|
if config.UsesLeaderElection() {
|
||||||
initLeaderElectionFlags()
|
initLeaderElectionFlags()
|
||||||
}
|
}
|
||||||
|
// reporting
|
||||||
|
if config.UsesReporting() {
|
||||||
|
initReportingFlags()
|
||||||
|
}
|
||||||
|
|
||||||
initCleanupFlags()
|
initCleanupFlags()
|
||||||
for _, flagset := range config.FlagSets() {
|
for _, flagset := range config.FlagSets() {
|
||||||
flagset.VisitAll(func(f *flag.Flag) {
|
flagset.VisitAll(func(f *flag.Flag) {
|
||||||
|
|
15
cmd/internal/reporting.go
Normal file
15
cmd/internal/reporting.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupReporting(logger logr.Logger) reportutils.ReportingConfiguration {
|
||||||
|
logger = logger.WithName("setup-reporting").WithValues("enableReporting", enableReporting)
|
||||||
|
cfg := reportutils.NewReportingConfig(strings.Split(enableReporting, ",")...)
|
||||||
|
logger.Info("setting up reporting...", "validate", cfg.ValidateReportsEnabled(), "mutate", cfg.MutateReportsEnabled(), "mutateExisiting", cfg.MutateExistingReportsEnabled(), "imageVerify", cfg.ImageVerificationReportsEnabled(), "generate", cfg.GenerateReportsEnabled())
|
||||||
|
return cfg
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/imageverifycache"
|
"github.com/kyverno/kyverno/pkg/imageverifycache"
|
||||||
"github.com/kyverno/kyverno/pkg/metrics"
|
"github.com/kyverno/kyverno/pkg/metrics"
|
||||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
eventsv1 "k8s.io/client-go/kubernetes/typed/events/v1"
|
eventsv1 "k8s.io/client-go/kubernetes/typed/events/v1"
|
||||||
corev1listers "k8s.io/client-go/listers/core/v1"
|
corev1listers "k8s.io/client-go/listers/core/v1"
|
||||||
)
|
)
|
||||||
|
@ -48,6 +49,7 @@ type SetupResult struct {
|
||||||
MetadataClient metadataclient.UpstreamInterface
|
MetadataClient metadataclient.UpstreamInterface
|
||||||
KyvernoDynamicClient dclient.Interface
|
KyvernoDynamicClient dclient.Interface
|
||||||
EventsClient eventsv1.EventsV1Interface
|
EventsClient eventsv1.EventsV1Interface
|
||||||
|
ReportingConfiguration reportutils.ReportingConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
func Setup(config Configuration, name string, skipResourceFilters bool) (context.Context, SetupResult, context.CancelFunc) {
|
func Setup(config Configuration, name string, skipResourceFilters bool) (context.Context, SetupResult, context.CancelFunc) {
|
||||||
|
@ -105,6 +107,10 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
|
||||||
if config.UsesMetadataClient() {
|
if config.UsesMetadataClient() {
|
||||||
metadataClient = createMetadataClient(logger, metadataclient.WithMetrics(metricsManager, metrics.MetadataClient), metadataclient.WithTracing())
|
metadataClient = createMetadataClient(logger, metadataclient.WithMetrics(metricsManager, metrics.MetadataClient), metadataclient.WithTracing())
|
||||||
}
|
}
|
||||||
|
var reportingConfig reportutils.ReportingConfiguration
|
||||||
|
if config.UsesReporting() {
|
||||||
|
reportingConfig = setupReporting(logger)
|
||||||
|
}
|
||||||
return ctx,
|
return ctx,
|
||||||
SetupResult{
|
SetupResult{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
|
@ -123,6 +129,7 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
|
||||||
MetadataClient: metadataClient,
|
MetadataClient: metadataClient,
|
||||||
KyvernoDynamicClient: dClient,
|
KyvernoDynamicClient: dClient,
|
||||||
EventsClient: eventsClient,
|
EventsClient: eventsClient,
|
||||||
|
ReportingConfiguration: reportingConfig,
|
||||||
},
|
},
|
||||||
shutdown(logger.WithName("shutdown"), sdownMaxProcs, sdownMetrics, sdownTracing, sdownSignals)
|
shutdown(logger.WithName("shutdown"), sdownMaxProcs, sdownMetrics, sdownTracing, sdownSignals)
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,6 +320,7 @@ func main() {
|
||||||
internal.WithApiServerClient(),
|
internal.WithApiServerClient(),
|
||||||
internal.WithMetadataClient(),
|
internal.WithMetadataClient(),
|
||||||
internal.WithFlagSets(flagset),
|
internal.WithFlagSets(flagset),
|
||||||
|
internal.WithReporting(),
|
||||||
)
|
)
|
||||||
// parse flags
|
// parse flags
|
||||||
internal.ParseFlags(appConfig)
|
internal.ParseFlags(appConfig)
|
||||||
|
@ -578,6 +579,7 @@ func main() {
|
||||||
setup.Jp,
|
setup.Jp,
|
||||||
maxAuditWorkers,
|
maxAuditWorkers,
|
||||||
maxAuditCapacity,
|
maxAuditCapacity,
|
||||||
|
setup.ReportingConfiguration,
|
||||||
reportsBreaker,
|
reportsBreaker,
|
||||||
)
|
)
|
||||||
exceptionHandlers := webhooksexception.NewHandlers(exception.ValidationOptions{
|
exceptionHandlers := webhooksexception.NewHandlers(exception.ValidationOptions{
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/leaderelection"
|
"github.com/kyverno/kyverno/pkg/leaderelection"
|
||||||
"github.com/kyverno/kyverno/pkg/logging"
|
"github.com/kyverno/kyverno/pkg/logging"
|
||||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
"github.com/kyverno/kyverno/pkg/validatingadmissionpolicy"
|
"github.com/kyverno/kyverno/pkg/validatingadmissionpolicy"
|
||||||
apiserver "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
apiserver "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
kubeinformers "k8s.io/client-go/informers"
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
|
@ -66,6 +67,7 @@ func createReportControllers(
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
eventGenerator event.Interface,
|
eventGenerator event.Interface,
|
||||||
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) ([]internal.Controller, func(context.Context) error) {
|
) ([]internal.Controller, func(context.Context) error) {
|
||||||
var ctrls []internal.Controller
|
var ctrls []internal.Controller
|
||||||
|
@ -126,6 +128,7 @@ func createReportControllers(
|
||||||
jp,
|
jp,
|
||||||
eventGenerator,
|
eventGenerator,
|
||||||
policyReports,
|
policyReports,
|
||||||
|
reportsConfig,
|
||||||
reportsBreaker,
|
reportsBreaker,
|
||||||
)
|
)
|
||||||
ctrls = append(ctrls, internal.NewController(
|
ctrls = append(ctrls, internal.NewController(
|
||||||
|
@ -149,6 +152,7 @@ func createrLeaderControllers(
|
||||||
eng engineapi.Engine,
|
eng engineapi.Engine,
|
||||||
backgroundScan bool,
|
backgroundScan bool,
|
||||||
admissionReports bool,
|
admissionReports bool,
|
||||||
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
aggregateReports bool,
|
aggregateReports bool,
|
||||||
policyReports bool,
|
policyReports bool,
|
||||||
validatingAdmissionPolicyReports bool,
|
validatingAdmissionPolicyReports bool,
|
||||||
|
@ -183,6 +187,7 @@ func createrLeaderControllers(
|
||||||
configuration,
|
configuration,
|
||||||
jp,
|
jp,
|
||||||
eventGenerator,
|
eventGenerator,
|
||||||
|
reportsConfig,
|
||||||
reportsBreaker,
|
reportsBreaker,
|
||||||
)
|
)
|
||||||
return reportControllers, warmup, nil
|
return reportControllers, warmup, nil
|
||||||
|
@ -238,6 +243,7 @@ func main() {
|
||||||
internal.WithEventsClient(),
|
internal.WithEventsClient(),
|
||||||
internal.WithApiServerClient(),
|
internal.WithApiServerClient(),
|
||||||
internal.WithFlagSets(flagset),
|
internal.WithFlagSets(flagset),
|
||||||
|
internal.WithReporting(),
|
||||||
)
|
)
|
||||||
// parse flags
|
// parse flags
|
||||||
internal.ParseFlags(
|
internal.ParseFlags(
|
||||||
|
@ -350,6 +356,7 @@ func main() {
|
||||||
engine,
|
engine,
|
||||||
backgroundScan,
|
backgroundScan,
|
||||||
admissionReports,
|
admissionReports,
|
||||||
|
setup.ReportingConfiguration,
|
||||||
aggregateReports,
|
aggregateReports,
|
||||||
policyReports,
|
policyReports,
|
||||||
validatingAdmissionPolicyReports,
|
validatingAdmissionPolicyReports,
|
||||||
|
|
|
@ -50737,6 +50737,7 @@ spec:
|
||||||
- --protectManagedResources=false
|
- --protectManagedResources=false
|
||||||
- --allowInsecureRegistry=false
|
- --allowInsecureRegistry=false
|
||||||
- --registryCredentialHelpers=default,google,amazon,azure,github
|
- --registryCredentialHelpers=default,google,amazon,azure,github
|
||||||
|
- --enableReporting=validate,mutate,mutateExisting,imageVerify,generate
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
@ -50881,7 +50882,6 @@ spec:
|
||||||
- --disableMetrics=false
|
- --disableMetrics=false
|
||||||
- --otelConfig=prometheus
|
- --otelConfig=prometheus
|
||||||
- --metricsPort=8000
|
- --metricsPort=8000
|
||||||
- --backgroundReports=true
|
|
||||||
- --enableConfigMapCaching=true
|
- --enableConfigMapCaching=true
|
||||||
- --enableDeferredLoading=true
|
- --enableDeferredLoading=true
|
||||||
- --maxAPICallResponseLength=2000000
|
- --maxAPICallResponseLength=2000000
|
||||||
|
@ -50889,6 +50889,7 @@ spec:
|
||||||
- --v=2
|
- --v=2
|
||||||
- --omitEvents=PolicyApplied,PolicySkipped
|
- --omitEvents=PolicyApplied,PolicySkipped
|
||||||
- --enablePolicyException=true
|
- --enablePolicyException=true
|
||||||
|
- --enableReporting=validate,mutate,mutateExisting,imageVerify,generate
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- name: KYVERNO_SERVICEACCOUNT_NAME
|
- name: KYVERNO_SERVICEACCOUNT_NAME
|
||||||
|
@ -51142,6 +51143,7 @@ spec:
|
||||||
- --enablePolicyException=true
|
- --enablePolicyException=true
|
||||||
- --allowInsecureRegistry=false
|
- --allowInsecureRegistry=false
|
||||||
- --registryCredentialHelpers=default,google,amazon,azure,github
|
- --registryCredentialHelpers=default,google,amazon,azure,github
|
||||||
|
- --enableReporting=validate,mutate,mutateExisting,imageVerify,generate
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- name: KYVERNO_SERVICEACCOUNT_NAME
|
- name: KYVERNO_SERVICEACCOUNT_NAME
|
||||||
|
|
|
@ -58,7 +58,7 @@ type GenerateController struct {
|
||||||
log logr.Logger
|
log logr.Logger
|
||||||
jp jmespath.Interface
|
jp jmespath.Interface
|
||||||
|
|
||||||
backgroundReports bool
|
reportsConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ func NewGenerateController(
|
||||||
eventGen event.Interface,
|
eventGen event.Interface,
|
||||||
log logr.Logger,
|
log logr.Logger,
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
backgroundReports bool,
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) *GenerateController {
|
) *GenerateController {
|
||||||
c := GenerateController{
|
c := GenerateController{
|
||||||
|
@ -92,7 +92,7 @@ func NewGenerateController(
|
||||||
eventGen: eventGen,
|
eventGen: eventGen,
|
||||||
log: log,
|
log: log,
|
||||||
jp: jp,
|
jp: jp,
|
||||||
backgroundReports: backgroundReports,
|
reportsConfig: reportsConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
return &c
|
return &c
|
||||||
|
@ -236,7 +236,7 @@ func (c *GenerateController) applyGenerate(trigger unstructured.Unstructured, ur
|
||||||
logger.V(4).Info(doesNotApply)
|
logger.V(4).Info(doesNotApply)
|
||||||
return nil, errors.New(doesNotApply)
|
return nil, errors.New(doesNotApply)
|
||||||
}
|
}
|
||||||
if c.needsReports(trigger, c.backgroundReports) {
|
if c.needsReports(trigger) {
|
||||||
if err := c.createReports(context.TODO(), policyContext.NewResource(), engineResponse); err != nil {
|
if err := c.createReports(context.TODO(), policyContext.NewResource(), engineResponse); err != nil {
|
||||||
c.log.Error(err, "failed to create report")
|
c.log.Error(err, "failed to create report")
|
||||||
}
|
}
|
||||||
|
@ -373,8 +373,8 @@ func (c *GenerateController) GetUnstrResource(genResourceSpec kyvernov1.Resource
|
||||||
return resource, nil
|
return resource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GenerateController) needsReports(trigger unstructured.Unstructured, backgroundReports bool) bool {
|
func (c *GenerateController) needsReports(trigger unstructured.Unstructured) bool {
|
||||||
createReport := backgroundReports
|
createReport := c.reportsConfig.GenerateReportsEnabled()
|
||||||
// check if the resource supports reporting
|
// check if the resource supports reporting
|
||||||
if !reportutils.IsGvkSupported(trigger.GroupVersionKind()) {
|
if !reportutils.IsGvkSupported(trigger.GroupVersionKind()) {
|
||||||
createReport = false
|
createReport = false
|
||||||
|
|
|
@ -47,7 +47,7 @@ type mutateExistingController struct {
|
||||||
log logr.Logger
|
log logr.Logger
|
||||||
jp jmespath.Interface
|
jp jmespath.Interface
|
||||||
|
|
||||||
backgroundReports bool
|
reportsConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func NewMutateExistingController(
|
||||||
eventGen event.Interface,
|
eventGen event.Interface,
|
||||||
log logr.Logger,
|
log logr.Logger,
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
backgroundReports bool,
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) *mutateExistingController {
|
) *mutateExistingController {
|
||||||
c := mutateExistingController{
|
c := mutateExistingController{
|
||||||
|
@ -79,7 +79,7 @@ func NewMutateExistingController(
|
||||||
eventGen: eventGen,
|
eventGen: eventGen,
|
||||||
log: log,
|
log: log,
|
||||||
jp: jp,
|
jp: jp,
|
||||||
backgroundReports: backgroundReports,
|
reportsConfig: reportsConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
return &c
|
return &c
|
||||||
|
@ -167,7 +167,7 @@ func (c *mutateExistingController) ProcessUR(ur *kyvernov2.UpdateRequest) error
|
||||||
}
|
}
|
||||||
|
|
||||||
er := c.engine.Mutate(context.TODO(), policyContext)
|
er := c.engine.Mutate(context.TODO(), policyContext)
|
||||||
if c.needsReports(trigger, c.backgroundReports) {
|
if c.needsReports(trigger) {
|
||||||
if err := c.createReports(context.TODO(), policyContext.NewResource(), er); err != nil {
|
if err := c.createReports(context.TODO(), policyContext.NewResource(), er); err != nil {
|
||||||
c.log.Error(err, "failed to create report")
|
c.log.Error(err, "failed to create report")
|
||||||
}
|
}
|
||||||
|
@ -258,8 +258,8 @@ func (c *mutateExistingController) report(err error, policy kyvernov1.PolicyInte
|
||||||
c.eventGen.Add(events...)
|
c.eventGen.Add(events...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *mutateExistingController) needsReports(trigger *unstructured.Unstructured, backgroundReports bool) bool {
|
func (c *mutateExistingController) needsReports(trigger *unstructured.Unstructured) bool {
|
||||||
createReport := backgroundReports
|
createReport := c.reportsConfig.MutateExistingReportsEnabled()
|
||||||
if trigger == nil {
|
if trigger == nil {
|
||||||
return createReport
|
return createReport
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||||
"github.com/kyverno/kyverno/pkg/event"
|
"github.com/kyverno/kyverno/pkg/event"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
@ -61,7 +62,7 @@ type controller struct {
|
||||||
eventGen event.Interface
|
eventGen event.Interface
|
||||||
configuration config.Configuration
|
configuration config.Configuration
|
||||||
jp jmespath.Interface
|
jp jmespath.Interface
|
||||||
backgroundReports bool
|
reportsConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ func NewController(
|
||||||
eventGen event.Interface,
|
eventGen event.Interface,
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
backgroundReports bool,
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) Controller {
|
) Controller {
|
||||||
urLister := urInformer.Lister().UpdateRequests(config.KyvernoNamespace())
|
urLister := urInformer.Lister().UpdateRequests(config.KyvernoNamespace())
|
||||||
|
@ -93,7 +94,7 @@ func NewController(
|
||||||
eventGen: eventGen,
|
eventGen: eventGen,
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
jp: jp,
|
jp: jp,
|
||||||
backgroundReports: backgroundReports,
|
reportsConfig: reportsConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
_, _ = urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
_, _ = urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
|
@ -227,10 +228,10 @@ func (c *controller) processUR(ur *kyvernov2.UpdateRequest) error {
|
||||||
statusControl := common.NewStatusControl(c.kyvernoClient, c.urLister)
|
statusControl := common.NewStatusControl(c.kyvernoClient, c.urLister)
|
||||||
switch ur.Spec.GetRequestType() {
|
switch ur.Spec.GetRequestType() {
|
||||||
case kyvernov2.Mutate:
|
case kyvernov2.Mutate:
|
||||||
ctrl := mutate.NewMutateExistingController(c.client, c.kyvernoClient, statusControl, c.engine, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.eventGen, logger, c.jp, c.backgroundReports, c.reportsBreaker)
|
ctrl := mutate.NewMutateExistingController(c.client, c.kyvernoClient, statusControl, c.engine, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.eventGen, logger, c.jp, c.reportsConfig, c.reportsBreaker)
|
||||||
return ctrl.ProcessUR(ur)
|
return ctrl.ProcessUR(ur)
|
||||||
case kyvernov2.Generate:
|
case kyvernov2.Generate:
|
||||||
ctrl := generate.NewGenerateController(c.client, c.kyvernoClient, statusControl, c.engine, c.cpolLister, c.polLister, c.urLister, c.nsLister, c.configuration, c.eventGen, logger, c.jp, c.backgroundReports, c.reportsBreaker)
|
ctrl := generate.NewGenerateController(c.client, c.kyvernoClient, statusControl, c.engine, c.cpolLister, c.polLister, c.urLister, c.nsLister, c.configuration, c.eventGen, logger, c.jp, c.reportsConfig, c.reportsBreaker)
|
||||||
return ctrl.ProcessUR(ur)
|
return ctrl.ProcessUR(ur)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -78,6 +78,7 @@ type controller struct {
|
||||||
jp jmespath.Interface
|
jp jmespath.Interface
|
||||||
eventGen event.Interface
|
eventGen event.Interface
|
||||||
policyReports bool
|
policyReports bool
|
||||||
|
reportsConfig reportutils.ReportingConfiguration
|
||||||
breaker breaker.Breaker
|
breaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +99,7 @@ func NewController(
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
eventGen event.Interface,
|
eventGen event.Interface,
|
||||||
policyReports bool,
|
policyReports bool,
|
||||||
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
breaker breaker.Breaker,
|
breaker breaker.Breaker,
|
||||||
) controllers.Controller {
|
) controllers.Controller {
|
||||||
ephrInformer := metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("ephemeralreports"))
|
ephrInformer := metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("ephemeralreports"))
|
||||||
|
@ -120,6 +122,7 @@ func NewController(
|
||||||
jp: jp,
|
jp: jp,
|
||||||
eventGen: eventGen,
|
eventGen: eventGen,
|
||||||
policyReports: policyReports,
|
policyReports: policyReports,
|
||||||
|
reportsConfig: reportsConfig,
|
||||||
breaker: breaker,
|
breaker: breaker,
|
||||||
}
|
}
|
||||||
if vapInformer != nil {
|
if vapInformer != nil {
|
||||||
|
@ -422,7 +425,7 @@ func (c *controller) reconcileReport(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if full || reevaluate || actual[reportutils.PolicyLabel(policy)] != policy.GetResourceVersion() {
|
if full || reevaluate || actual[reportutils.PolicyLabel(policy)] != policy.GetResourceVersion() {
|
||||||
scanner := utils.NewScanner(logger, c.engine, c.config, c.jp, c.client)
|
scanner := utils.NewScanner(logger, c.engine, c.config, c.jp, c.client, c.reportsConfig)
|
||||||
for _, result := range scanner.ScanResource(ctx, *target, nsLabels, bindings, policy) {
|
for _, result := range scanner.ScanResource(ctx, *target, nsLabels, bindings, policy) {
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return result.Error
|
return result.Error
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/engine"
|
"github.com/kyverno/kyverno/pkg/engine"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
"github.com/kyverno/kyverno/pkg/validatingadmissionpolicy"
|
"github.com/kyverno/kyverno/pkg/validatingadmissionpolicy"
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||||
|
@ -23,6 +24,7 @@ type scanner struct {
|
||||||
config config.Configuration
|
config config.Configuration
|
||||||
jp jmespath.Interface
|
jp jmespath.Interface
|
||||||
client dclient.Interface
|
client dclient.Interface
|
||||||
|
reportingConfig reportutils.ReportingConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScanResult struct {
|
type ScanResult struct {
|
||||||
|
@ -40,6 +42,7 @@ func NewScanner(
|
||||||
config config.Configuration,
|
config config.Configuration,
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
client dclient.Interface,
|
client dclient.Interface,
|
||||||
|
reportingConfig reportutils.ReportingConfiguration,
|
||||||
) Scanner {
|
) Scanner {
|
||||||
return &scanner{
|
return &scanner{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
@ -47,6 +50,7 @@ func NewScanner(
|
||||||
config: config,
|
config: config,
|
||||||
jp: jp,
|
jp: jp,
|
||||||
client: client,
|
client: client,
|
||||||
|
reportingConfig: reportingConfig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +63,15 @@ func (s *scanner) ScanResource(ctx context.Context, resource unstructured.Unstru
|
||||||
if policy.GetType() == engineapi.KyvernoPolicyType {
|
if policy.GetType() == engineapi.KyvernoPolicyType {
|
||||||
var err error
|
var err error
|
||||||
pol := policy.AsKyvernoPolicy()
|
pol := policy.AsKyvernoPolicy()
|
||||||
|
if s.reportingConfig.ValidateReportsEnabled() {
|
||||||
response, err = s.validateResource(ctx, resource, nsLabels, pol)
|
response, err = s.validateResource(ctx, resource, nsLabels, pol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, "failed to scan resource")
|
logger.Error(err, "failed to scan resource")
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
spec := pol.GetSpec()
|
spec := pol.GetSpec()
|
||||||
if spec.HasVerifyImages() && len(errors) == 0 {
|
if spec.HasVerifyImages() && len(errors) == 0 && s.reportingConfig.ImageVerificationReportsEnabled() {
|
||||||
if response != nil {
|
if response != nil {
|
||||||
// remove responses of verify image rules
|
// remove responses of verify image rules
|
||||||
ruleResponses := make([]engineapi.RuleResponse, 0, len(response.PolicyResponse.Rules))
|
ruleResponses := make([]engineapi.RuleResponse, 0, len(response.PolicyResponse.Rules))
|
||||||
|
|
41
pkg/utils/report/config.go
Normal file
41
pkg/utils/report/config.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import "k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
|
||||||
|
type reportingConfig struct {
|
||||||
|
helper sets.Set[string]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *reportingConfig) ValidateReportsEnabled() bool {
|
||||||
|
return r.helper.Has("validate")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *reportingConfig) MutateReportsEnabled() bool {
|
||||||
|
return r.helper.Has("mutate")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *reportingConfig) MutateExistingReportsEnabled() bool {
|
||||||
|
return r.helper.Has("mutateExisting")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *reportingConfig) ImageVerificationReportsEnabled() bool {
|
||||||
|
return r.helper.Has("imageVerify")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *reportingConfig) GenerateReportsEnabled() bool {
|
||||||
|
return r.helper.Has("generate")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReportingConfig(items ...string) ReportingConfiguration {
|
||||||
|
return &reportingConfig{
|
||||||
|
helper: sets.New(items...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportingConfiguration interface {
|
||||||
|
ValidateReportsEnabled() bool
|
||||||
|
MutateReportsEnabled() bool
|
||||||
|
MutateExistingReportsEnabled() bool
|
||||||
|
ImageVerificationReportsEnabled() bool
|
||||||
|
GenerateReportsEnabled() bool
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/metrics"
|
"github.com/kyverno/kyverno/pkg/metrics"
|
||||||
"github.com/kyverno/kyverno/pkg/policycache"
|
"github.com/kyverno/kyverno/pkg/policycache"
|
||||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
|
"github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
"github.com/kyverno/kyverno/pkg/webhooks/updaterequest"
|
"github.com/kyverno/kyverno/pkg/webhooks/updaterequest"
|
||||||
webhookutils "github.com/kyverno/kyverno/pkg/webhooks/utils"
|
webhookutils "github.com/kyverno/kyverno/pkg/webhooks/utils"
|
||||||
kubeinformers "k8s.io/client-go/informers"
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
|
@ -55,6 +56,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) *resour
|
||||||
eventGen: event.NewFake(),
|
eventGen: event.NewFake(),
|
||||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, jp),
|
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, jp),
|
||||||
auditPool: pond.New(8, 1000),
|
auditPool: pond.New(8, 1000),
|
||||||
|
reportingConfig: report.NewReportingConfig("validate", "mutate", "mutateExisiting", "generate", "imageVerify"),
|
||||||
engine: engine.NewEngine(
|
engine: engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
config.NewDefaultMetricsConfiguration(),
|
config.NewDefaultMetricsConfiguration(),
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||||
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
|
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
|
||||||
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
|
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
|
||||||
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
"github.com/kyverno/kyverno/pkg/webhooks"
|
"github.com/kyverno/kyverno/pkg/webhooks"
|
||||||
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
|
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
|
||||||
"github.com/kyverno/kyverno/pkg/webhooks/resource/imageverification"
|
"github.com/kyverno/kyverno/pkg/webhooks/resource/imageverification"
|
||||||
|
@ -65,6 +66,7 @@ type resourceHandlers struct {
|
||||||
backgroundServiceAccountName string
|
backgroundServiceAccountName string
|
||||||
reportsServiceAccountName string
|
reportsServiceAccountName string
|
||||||
auditPool *pond.WorkerPool
|
auditPool *pond.WorkerPool
|
||||||
|
reportingConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +89,7 @@ func NewHandlers(
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
maxAuditWorkers int,
|
maxAuditWorkers int,
|
||||||
maxAuditCapacity int,
|
maxAuditCapacity int,
|
||||||
|
reportingConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) webhooks.ResourceHandlers {
|
) webhooks.ResourceHandlers {
|
||||||
return &resourceHandlers{
|
return &resourceHandlers{
|
||||||
|
@ -107,6 +110,7 @@ func NewHandlers(
|
||||||
backgroundServiceAccountName: backgroundServiceAccountName,
|
backgroundServiceAccountName: backgroundServiceAccountName,
|
||||||
reportsServiceAccountName: reportsServiceAccountName,
|
reportsServiceAccountName: reportsServiceAccountName,
|
||||||
auditPool: pond.New(maxAuditWorkers, maxAuditCapacity, pond.Strategy(pond.Lazy())),
|
auditPool: pond.New(maxAuditWorkers, maxAuditCapacity, pond.Strategy(pond.Lazy())),
|
||||||
|
reportingConfig: reportingConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +142,7 @@ func (h *resourceHandlers) Validate(ctx context.Context, logger logr.Logger, req
|
||||||
h.metricsConfig,
|
h.metricsConfig,
|
||||||
h.configuration,
|
h.configuration,
|
||||||
h.nsLister,
|
h.nsLister,
|
||||||
|
h.reportingConfig,
|
||||||
h.reportsBreaker,
|
h.reportsBreaker,
|
||||||
)
|
)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
@ -200,7 +205,7 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
|
||||||
logger.Error(err, "failed to build policy context")
|
logger.Error(err, "failed to build policy context")
|
||||||
return admissionutils.Response(request.UID, err)
|
return admissionutils.Response(request.UID, err)
|
||||||
}
|
}
|
||||||
mh := mutation.NewMutationHandler(logger, h.kyvernoClient, h.engine, h.eventGen, h.nsLister, h.metricsConfig, h.admissionReports, h.reportsBreaker)
|
mh := mutation.NewMutationHandler(logger, h.kyvernoClient, h.engine, h.eventGen, h.nsLister, h.metricsConfig, h.admissionReports, h.reportingConfig, h.reportsBreaker)
|
||||||
patches, warnings, err := mh.HandleMutation(ctx, request, mutatePolicies, policyContext, startTime, h.configuration)
|
patches, warnings, err := mh.HandleMutation(ctx, request, mutatePolicies, policyContext, startTime, h.configuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, "mutation failed")
|
logger.Error(err, "mutation failed")
|
||||||
|
@ -222,6 +227,7 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
|
||||||
h.admissionReports,
|
h.admissionReports,
|
||||||
h.configuration,
|
h.configuration,
|
||||||
h.nsLister,
|
h.nsLister,
|
||||||
|
h.reportingConfig,
|
||||||
h.reportsBreaker,
|
h.reportsBreaker,
|
||||||
)
|
)
|
||||||
imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext)
|
imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext)
|
||||||
|
|
|
@ -40,6 +40,7 @@ type imageVerificationHandler struct {
|
||||||
admissionReports bool
|
admissionReports bool
|
||||||
cfg config.Configuration
|
cfg config.Configuration
|
||||||
nsLister corev1listers.NamespaceLister
|
nsLister corev1listers.NamespaceLister
|
||||||
|
reportConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +52,7 @@ func NewImageVerificationHandler(
|
||||||
admissionReports bool,
|
admissionReports bool,
|
||||||
cfg config.Configuration,
|
cfg config.Configuration,
|
||||||
nsLister corev1listers.NamespaceLister,
|
nsLister corev1listers.NamespaceLister,
|
||||||
|
reportConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) ImageVerificationHandler {
|
) ImageVerificationHandler {
|
||||||
return &imageVerificationHandler{
|
return &imageVerificationHandler{
|
||||||
|
@ -61,6 +63,7 @@ func NewImageVerificationHandler(
|
||||||
admissionReports: admissionReports,
|
admissionReports: admissionReports,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
nsLister: nsLister,
|
nsLister: nsLister,
|
||||||
|
reportConfig: reportConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,6 +164,9 @@ func (v *imageVerificationHandler) handleAudit(
|
||||||
engineResponses ...engineapi.EngineResponse,
|
engineResponses ...engineapi.EngineResponse,
|
||||||
) {
|
) {
|
||||||
createReport := v.admissionReports
|
createReport := v.admissionReports
|
||||||
|
if !v.reportConfig.ImageVerificationReportsEnabled() {
|
||||||
|
createReport = false
|
||||||
|
}
|
||||||
if admissionutils.IsDryRun(request) {
|
if admissionutils.IsDryRun(request) {
|
||||||
createReport = false
|
createReport = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ func NewMutationHandler(
|
||||||
nsLister corev1listers.NamespaceLister,
|
nsLister corev1listers.NamespaceLister,
|
||||||
metrics metrics.MetricsConfigManager,
|
metrics metrics.MetricsConfigManager,
|
||||||
admissionReports bool,
|
admissionReports bool,
|
||||||
|
reportsConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) MutationHandler {
|
) MutationHandler {
|
||||||
return &mutationHandler{
|
return &mutationHandler{
|
||||||
|
@ -54,6 +55,7 @@ func NewMutationHandler(
|
||||||
nsLister: nsLister,
|
nsLister: nsLister,
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
admissionReports: admissionReports,
|
admissionReports: admissionReports,
|
||||||
|
reportsConfig: reportsConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +68,7 @@ type mutationHandler struct {
|
||||||
nsLister corev1listers.NamespaceLister
|
nsLister corev1listers.NamespaceLister
|
||||||
metrics metrics.MetricsConfigManager
|
metrics metrics.MetricsConfigManager
|
||||||
admissionReports bool
|
admissionReports bool
|
||||||
|
reportsConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ func (v *mutationHandler) applyMutations(
|
||||||
v.eventGen.Add(events...)
|
v.eventGen.Add(events...)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if v.needsReports(request, policyContext.NewResource(), v.admissionReports) {
|
if v.needsReports(request, v.admissionReports) {
|
||||||
if err := v.createReports(context.TODO(), policyContext.NewResource(), request, engineResponses...); err != nil {
|
if err := v.createReports(context.TODO(), policyContext.NewResource(), request, engineResponses...); err != nil {
|
||||||
v.log.Error(err, "failed to create report")
|
v.log.Error(err, "failed to create report")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,17 @@ import (
|
||||||
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
|
||||||
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
|
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
|
||||||
admissionv1 "k8s.io/api/admission/v1"
|
admissionv1 "k8s.io/api/admission/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v *mutationHandler) needsReports(request handlers.AdmissionRequest, resource unstructured.Unstructured, admissionReport bool) bool {
|
func (v *mutationHandler) needsReports(request handlers.AdmissionRequest, admissionReport bool) bool {
|
||||||
createReport := admissionReport
|
createReport := admissionReport
|
||||||
if admissionutils.IsDryRun(request.AdmissionRequest) {
|
if admissionutils.IsDryRun(request.AdmissionRequest) {
|
||||||
createReport = false
|
createReport = false
|
||||||
}
|
}
|
||||||
|
if !v.reportsConfig.MutateReportsEnabled() {
|
||||||
|
createReport = false
|
||||||
|
}
|
||||||
// we don't need reports for deletions
|
// we don't need reports for deletions
|
||||||
if request.Operation == admissionv1.Delete {
|
if request.Operation == admissionv1.Delete {
|
||||||
createReport = false
|
createReport = false
|
||||||
|
|
|
@ -9,11 +9,14 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func needsReports(request handlers.AdmissionRequest, resource unstructured.Unstructured, admissionReport bool) bool {
|
func needsReports(request handlers.AdmissionRequest, resource unstructured.Unstructured, admissionReport bool, reportConfig reportutils.ReportingConfiguration) bool {
|
||||||
createReport := admissionReport
|
createReport := admissionReport
|
||||||
if admissionutils.IsDryRun(request.AdmissionRequest) {
|
if admissionutils.IsDryRun(request.AdmissionRequest) {
|
||||||
createReport = false
|
createReport = false
|
||||||
}
|
}
|
||||||
|
if !reportConfig.ValidateReportsEnabled() {
|
||||||
|
createReport = false
|
||||||
|
}
|
||||||
// we don't need reports for deletions
|
// we don't need reports for deletions
|
||||||
if request.Operation == admissionv1.Delete {
|
if request.Operation == admissionv1.Delete {
|
||||||
createReport = false
|
createReport = false
|
||||||
|
|
|
@ -46,6 +46,7 @@ func NewValidationHandler(
|
||||||
metrics metrics.MetricsConfigManager,
|
metrics metrics.MetricsConfigManager,
|
||||||
cfg config.Configuration,
|
cfg config.Configuration,
|
||||||
nsLister corev1listers.NamespaceLister,
|
nsLister corev1listers.NamespaceLister,
|
||||||
|
reportConfig reportutils.ReportingConfiguration,
|
||||||
reportsBreaker breaker.Breaker,
|
reportsBreaker breaker.Breaker,
|
||||||
) ValidationHandler {
|
) ValidationHandler {
|
||||||
return &validationHandler{
|
return &validationHandler{
|
||||||
|
@ -59,6 +60,7 @@ func NewValidationHandler(
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
nsLister: nsLister,
|
nsLister: nsLister,
|
||||||
|
reportConfig: reportConfig,
|
||||||
reportsBreaker: reportsBreaker,
|
reportsBreaker: reportsBreaker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +76,7 @@ type validationHandler struct {
|
||||||
metrics metrics.MetricsConfigManager
|
metrics metrics.MetricsConfigManager
|
||||||
cfg config.Configuration
|
cfg config.Configuration
|
||||||
nsLister corev1listers.NamespaceLister
|
nsLister corev1listers.NamespaceLister
|
||||||
|
reportConfig reportutils.ReportingConfiguration
|
||||||
reportsBreaker breaker.Breaker
|
reportsBreaker breaker.Breaker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +162,7 @@ func (v *validationHandler) HandleValidationEnforce(
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if needsReports(request, policyContext.NewResource(), v.admissionReports) {
|
if needsReports(request, policyContext.NewResource(), v.admissionReports, v.reportConfig) {
|
||||||
if err := v.createReports(context.TODO(), policyContext.NewResource(), request, engineResponses...); err != nil {
|
if err := v.createReports(context.TODO(), policyContext.NewResource(), request, engineResponses...); err != nil {
|
||||||
v.log.Error(err, "failed to create report")
|
v.log.Error(err, "failed to create report")
|
||||||
}
|
}
|
||||||
|
@ -188,7 +191,7 @@ func (v *validationHandler) HandleValidationAudit(
|
||||||
}
|
}
|
||||||
|
|
||||||
var responses []engineapi.EngineResponse
|
var responses []engineapi.EngineResponse
|
||||||
needsReport := needsReports(request, policyContext.NewResource(), v.admissionReports)
|
needsReport := needsReports(request, policyContext.NewResource(), v.admissionReports, v.reportConfig)
|
||||||
tracing.Span(
|
tracing.Span(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
"",
|
"",
|
||||||
|
|
Loading…
Add table
Reference in a new issue