1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-15 12:17:56 +00:00

feat: add --backgroundReports flag to disable mutateexisting and generate reporting (#11361)

Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com>
This commit is contained in:
Vishal Choudhary 2024-10-09 16:13:59 +05:30 committed by GitHub
parent 8d21e89625
commit 21fd92e3e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 75 additions and 52 deletions

View file

@ -327,6 +327,7 @@ 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.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 |

View file

@ -25,6 +25,9 @@
{{- 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,4 +100,4 @@
{{- with $flags -}} {{- with $flags -}}
{{- toYaml . -}} {{- toYaml . -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}

View file

@ -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.backgroundController.featuresOverride) {{- include "kyverno.features.flags" (pick (mergeOverwrite .Values.features .Values.backgroundController.featuresOverride)
"backgroundReports"
"configMapCaching" "configMapCaching"
"deferredLoading" "deferredLoading"
"globalContext" "globalContext"

View file

@ -636,6 +636,9 @@ features:
validatingAdmissionPolicyReports: validatingAdmissionPolicyReports:
# -- Enables the feature # -- Enables the feature
enabled: false enabled: false
backgroundReports:
# -- Enables the feature
enabled: true
autoUpdateWebhooks: autoUpdateWebhooks:
# -- Enables the feature # -- Enables the feature
enabled: true enabled: true

View file

@ -55,6 +55,7 @@ func createrLeaderControllers(
jp jmespath.Interface, jp jmespath.Interface,
backgroundScanInterval time.Duration, backgroundScanInterval time.Duration,
urGenerator generator.UpdateRequestGenerator, urGenerator generator.UpdateRequestGenerator,
backgroundReports bool,
reportsBreaker breaker.Breaker, reportsBreaker breaker.Breaker,
) ([]internal.Controller, error) { ) ([]internal.Controller, error) {
policyCtrl, err := policy.NewPolicyController( policyCtrl, err := policy.NewPolicyController(
@ -87,6 +88,7 @@ func createrLeaderControllers(
eventGenerator, eventGenerator,
configuration, configuration,
jp, jp,
backgroundReports,
reportsBreaker, reportsBreaker,
) )
return []internal.Controller{ return []internal.Controller{
@ -101,6 +103,7 @@ 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)
@ -108,6 +111,7 @@ func main() {
flagset.IntVar(&maxQueuedEvents, "maxQueuedEvents", 1000, "Maximum events to be queued.") flagset.IntVar(&maxQueuedEvents, "maxQueuedEvents", 1000, "Maximum events to be queued.")
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.BoolVar(&backgroundReports, "backgroundReports", true, "Enables or disables reports for mutate existing and generate rules.")
flagset.IntVar(&maxBackgroundReports, "maxBackgroundReports", 10000, "Maximum number of background reports before we stop creating new ones") flagset.IntVar(&maxBackgroundReports, "maxBackgroundReports", 10000, "Maximum number of background reports before we stop creating new ones")
// config // config
appConfig := internal.NewConfiguration( appConfig := internal.NewConfiguration(
@ -247,6 +251,7 @@ func main() {
setup.Jp, setup.Jp,
bgscanInterval, bgscanInterval,
urGenerator, urGenerator,
backgroundReports,
reportsBreaker, reportsBreaker,
) )
if err != nil { if err != nil {

View file

@ -50881,6 +50881,7 @@ 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

View file

@ -58,7 +58,8 @@ type GenerateController struct {
log logr.Logger log logr.Logger
jp jmespath.Interface jp jmespath.Interface
reportsBreaker breaker.Breaker backgroundReports bool
reportsBreaker breaker.Breaker
} }
// NewGenerateController returns an instance of the Generate-Request Controller // NewGenerateController returns an instance of the Generate-Request Controller
@ -75,22 +76,24 @@ func NewGenerateController(
eventGen event.Interface, eventGen event.Interface,
log logr.Logger, log logr.Logger,
jp jmespath.Interface, jp jmespath.Interface,
backgroundReports bool,
reportsBreaker breaker.Breaker, reportsBreaker breaker.Breaker,
) *GenerateController { ) *GenerateController {
c := GenerateController{ c := GenerateController{
client: client, client: client,
kyvernoClient: kyvernoClient, kyvernoClient: kyvernoClient,
statusControl: statusControl, statusControl: statusControl,
engine: engine, engine: engine,
policyLister: policyLister, policyLister: policyLister,
npolicyLister: npolicyLister, npolicyLister: npolicyLister,
urLister: urLister, urLister: urLister,
nsLister: nsLister, nsLister: nsLister,
configuration: dynamicConfig, configuration: dynamicConfig,
eventGen: eventGen, eventGen: eventGen,
log: log, log: log,
jp: jp, jp: jp,
reportsBreaker: reportsBreaker, backgroundReports: backgroundReports,
reportsBreaker: reportsBreaker,
} }
return &c return &c
} }
@ -233,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) { if c.needsReports(trigger, c.backgroundReports) {
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")
} }
@ -370,8 +373,8 @@ func (c *GenerateController) GetUnstrResource(genResourceSpec kyvernov1.Resource
return resource, nil return resource, nil
} }
func (c *GenerateController) needsReports(trigger unstructured.Unstructured) bool { func (c *GenerateController) needsReports(trigger unstructured.Unstructured, backgroundReports bool) bool {
createReport := true createReport := backgroundReports
// 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

View file

@ -47,7 +47,8 @@ type mutateExistingController struct {
log logr.Logger log logr.Logger
jp jmespath.Interface jp jmespath.Interface
reportsBreaker breaker.Breaker backgroundReports bool
reportsBreaker breaker.Breaker
} }
// NewMutateExistingController returns an instance of the MutateExistingController // NewMutateExistingController returns an instance of the MutateExistingController
@ -63,21 +64,23 @@ func NewMutateExistingController(
eventGen event.Interface, eventGen event.Interface,
log logr.Logger, log logr.Logger,
jp jmespath.Interface, jp jmespath.Interface,
backgroundReports bool,
reportsBreaker breaker.Breaker, reportsBreaker breaker.Breaker,
) *mutateExistingController { ) *mutateExistingController {
c := mutateExistingController{ c := mutateExistingController{
client: client, client: client,
kyvernoClient: kyvernoClient, kyvernoClient: kyvernoClient,
statusControl: statusControl, statusControl: statusControl,
engine: engine, engine: engine,
policyLister: policyLister, policyLister: policyLister,
npolicyLister: npolicyLister, npolicyLister: npolicyLister,
nsLister: nsLister, nsLister: nsLister,
configuration: dynamicConfig, configuration: dynamicConfig,
eventGen: eventGen, eventGen: eventGen,
log: log, log: log,
jp: jp, jp: jp,
reportsBreaker: reportsBreaker, backgroundReports: backgroundReports,
reportsBreaker: reportsBreaker,
} }
return &c return &c
} }
@ -164,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) { if c.needsReports(trigger, c.backgroundReports) {
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")
} }
@ -255,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) bool { func (c *mutateExistingController) needsReports(trigger *unstructured.Unstructured, backgroundReports bool) bool {
createReport := true createReport := backgroundReports
if trigger == nil { if trigger == nil {
return createReport return createReport
} }

View file

@ -58,10 +58,11 @@ type controller struct {
// queue // queue
queue workqueue.TypedRateLimitingInterface[any] queue workqueue.TypedRateLimitingInterface[any]
eventGen event.Interface eventGen event.Interface
configuration config.Configuration configuration config.Configuration
jp jmespath.Interface jp jmespath.Interface
reportsBreaker breaker.Breaker backgroundReports bool
reportsBreaker breaker.Breaker
} }
// NewController returns an instance of the Generate-Request Controller // NewController returns an instance of the Generate-Request Controller
@ -76,22 +77,24 @@ func NewController(
eventGen event.Interface, eventGen event.Interface,
configuration config.Configuration, configuration config.Configuration,
jp jmespath.Interface, jp jmespath.Interface,
backgroundReports bool,
reportsBreaker breaker.Breaker, reportsBreaker breaker.Breaker,
) Controller { ) Controller {
urLister := urInformer.Lister().UpdateRequests(config.KyvernoNamespace()) urLister := urInformer.Lister().UpdateRequests(config.KyvernoNamespace())
c := controller{ c := controller{
client: client, client: client,
kyvernoClient: kyvernoClient, kyvernoClient: kyvernoClient,
engine: engine, engine: engine,
cpolLister: cpolInformer.Lister(), cpolLister: cpolInformer.Lister(),
polLister: polInformer.Lister(), polLister: polInformer.Lister(),
urLister: urLister, urLister: urLister,
nsLister: namespaceInformer.Lister(), nsLister: namespaceInformer.Lister(),
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any](), "background"), queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any](), "background"),
eventGen: eventGen, eventGen: eventGen,
configuration: configuration, configuration: configuration,
jp: jp, jp: jp,
reportsBreaker: reportsBreaker, backgroundReports: backgroundReports,
reportsBreaker: reportsBreaker,
} }
_, _ = urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ _, _ = urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: c.addUR, AddFunc: c.addUR,
@ -224,10 +227,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.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.backgroundReports, 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.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.backgroundReports, c.reportsBreaker)
return ctrl.ProcessUR(ur) return ctrl.ProcessUR(ur)
} }
return nil return nil