From cc8f643767a9b8f355a0b87ffdc5a673a424af8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 9 Nov 2022 11:52:20 +0100 Subject: [PATCH] refactor: admission metrics (counter and latency) (#5245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: move all middlewares in handlers sub package Signed-off-by: Charles-Edouard Brétéché * refactor: admission metrics (counter and latency) Signed-off-by: Charles-Edouard Brétéché * builder Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché * cleanup Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- cmd/kyverno/main.go | 1 + .../admissionrequests/admissionRequests.go | 41 ++------ .../admissionReviewDuration.go | 44 ++------- pkg/webhooks/handlers/admission.go | 6 +- pkg/webhooks/handlers/dump.go | 9 +- pkg/webhooks/handlers/filter.go | 6 +- pkg/webhooks/handlers/metrics.go | 23 +++++ pkg/webhooks/handlers/protect.go | 9 +- .../resource/generation/generation.go | 12 --- pkg/webhooks/resource/mutation/mutation.go | 6 -- pkg/webhooks/resource/updaterequest.go | 13 +-- .../resource/validation/validation.go | 8 -- pkg/webhooks/server.go | 99 +++++++++++-------- pkg/webhooks/utils/metrics.go | 45 --------- 14 files changed, 127 insertions(+), 195 deletions(-) create mode 100644 pkg/webhooks/handlers/metrics.go diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 32318a5a41..46a129fa04 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -756,6 +756,7 @@ func main() { policyHandlers, resourceHandlers, configuration, + metricsConfig, webhooks.DebugModeOptions{ DumpPayload: dumpPayload, }, diff --git a/pkg/metrics/admissionrequests/admissionRequests.go b/pkg/metrics/admissionrequests/admissionRequests.go index 2e88051608..44f35e22c7 100644 --- a/pkg/metrics/admissionrequests/admissionRequests.go +++ b/pkg/metrics/admissionrequests/admissionRequests.go @@ -2,52 +2,27 @@ package admissionrequests import ( "fmt" + "strings" - "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" ) -func registerAdmissionRequestsMetric( - m *metrics.MetricsConfig, - resourceKind, resourceNamespace string, - resourceRequestOperation metrics.ResourceRequestOperation, -) error { +func registerAdmissionRequestsMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation) { includeNamespaces, excludeNamespaces := m.Config.GetIncludeNamespaces(), m.Config.GetExcludeNamespaces() if (resourceNamespace != "" && resourceNamespace != "-") && utils.ContainsString(excludeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_requests_total metric as the operation belongs to the namespace '%s' which is one of 'namespaces.exclude' %+v in values.yaml", resourceNamespace, excludeNamespaces)) - return nil + return } if (resourceNamespace != "" && resourceNamespace != "-") && len(includeNamespaces) > 0 && !utils.ContainsString(includeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_requests_total metric as the operation belongs to the namespace '%s' which is not one of 'namespaces.include' %+v in values.yaml", resourceNamespace, includeNamespaces)) - return nil + return } - m.RecordAdmissionRequests(resourceKind, resourceNamespace, resourceRequestOperation) - - return nil } -func ProcessEngineResponses(m *metrics.MetricsConfig, engineResponses []*response.EngineResponse, resourceRequestOperation metrics.ResourceRequestOperation) error { - if len(engineResponses) == 0 { - return nil - } - resourceNamespace, resourceKind := engineResponses[0].PolicyResponse.Resource.Namespace, engineResponses[0].PolicyResponse.Resource.Kind - validateRulesCount, mutateRulesCount, generateRulesCount := 0, 0, 0 - for _, e := range engineResponses { - for _, rule := range e.PolicyResponse.Rules { - switch rule.Type { - case "Validation": - validateRulesCount++ - case "Mutation": - mutateRulesCount++ - case "Generation": - generateRulesCount++ - } - } - } - if validateRulesCount == 0 && mutateRulesCount == 0 && generateRulesCount == 0 { - return nil - } - return registerAdmissionRequestsMetric(m, resourceKind, resourceNamespace, resourceRequestOperation) +func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest) { + op := strings.ToLower(string(request.Operation)) + registerAdmissionRequestsMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op)) } diff --git a/pkg/metrics/admissionreviewduration/admissionReviewDuration.go b/pkg/metrics/admissionreviewduration/admissionReviewDuration.go index 36f50e2ccd..ec00247ec2 100644 --- a/pkg/metrics/admissionreviewduration/admissionReviewDuration.go +++ b/pkg/metrics/admissionreviewduration/admissionReviewDuration.go @@ -2,54 +2,28 @@ package admissionreviewduration import ( "fmt" + "strings" - "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" ) -func registerAdmissionReviewDurationMetric( - m *metrics.MetricsConfig, - resourceKind, resourceNamespace string, - resourceRequestOperation metrics.ResourceRequestOperation, - admissionRequestLatency float64, -) error { +func registerAdmissionReviewDurationMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation, admissionRequestLatency float64) { includeNamespaces, excludeNamespaces := m.Config.GetIncludeNamespaces(), m.Config.GetExcludeNamespaces() if (resourceNamespace != "" && resourceNamespace != "-") && utils.ContainsString(excludeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_review_duration_seconds metric as the operation belongs to the namespace '%s' which is one of 'namespaces.exclude' %+v in values.yaml", resourceNamespace, excludeNamespaces)) - return nil + return } if (resourceNamespace != "" && resourceNamespace != "-") && len(includeNamespaces) > 0 && !utils.ContainsString(includeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_review_duration_seconds metric as the operation belongs to the namespace '%s' which is not one of 'namespaces.include' %+v in values.yaml", resourceNamespace, includeNamespaces)) - return nil + return } - m.RecordAdmissionReviewDuration(resourceKind, resourceNamespace, string(resourceRequestOperation), admissionRequestLatency) - - return nil } -func ProcessEngineResponses(m *metrics.MetricsConfig, engineResponses []*response.EngineResponse, admissionReviewLatencyDuration int64, resourceRequestOperation metrics.ResourceRequestOperation) error { - if len(engineResponses) == 0 { - return nil - } - resourceNamespace, resourceKind := engineResponses[0].PolicyResponse.Resource.Namespace, engineResponses[0].PolicyResponse.Resource.Kind - validateRulesCount, mutateRulesCount, generateRulesCount := 0, 0, 0 - for _, e := range engineResponses { - for _, rule := range e.PolicyResponse.Rules { - switch rule.Type { - case "Validation": - validateRulesCount++ - case "Mutation": - mutateRulesCount++ - case "Generation": - generateRulesCount++ - } - } - } - if validateRulesCount == 0 && mutateRulesCount == 0 && generateRulesCount == 0 { - return nil - } - admissionReviewLatencyDurationInSeconds := float64(admissionReviewLatencyDuration) / float64(1000*1000*1000) - return registerAdmissionReviewDurationMetric(m, resourceKind, resourceNamespace, resourceRequestOperation, admissionReviewLatencyDurationInSeconds) +func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest, latency int64) { + op := strings.ToLower(string(request.Operation)) + admissionReviewLatencyDurationInSeconds := float64(latency) / float64(1000*1000*1000) + registerAdmissionReviewDurationMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op), admissionReviewLatencyDurationInSeconds) } diff --git a/pkg/webhooks/handlers/admission.go b/pkg/webhooks/handlers/admission.go index 1ca1fca2c8..4b72b6b5c7 100644 --- a/pkg/webhooks/handlers/admission.go +++ b/pkg/webhooks/handlers/admission.go @@ -15,7 +15,11 @@ import ( type AdmissionHandler func(logr.Logger, *admissionv1.AdmissionRequest, time.Time) *admissionv1.AdmissionResponse -func Admission(logger logr.Logger, inner AdmissionHandler) http.HandlerFunc { +func (h AdmissionHandler) WithAdmission(logger logr.Logger) http.HandlerFunc { + return withAdmission(logger, h) +} + +func withAdmission(logger logr.Logger, inner AdmissionHandler) http.HandlerFunc { return func(writer http.ResponseWriter, request *http.Request) { ctx := request.Context() startTime := time.Now() diff --git a/pkg/webhooks/handlers/dump.go b/pkg/webhooks/handlers/dump.go index 1f3005564e..682f88bea5 100644 --- a/pkg/webhooks/handlers/dump.go +++ b/pkg/webhooks/handlers/dump.go @@ -93,7 +93,14 @@ func redactPayload(payload *admissionRequestPayload) (*admissionRequestPayload, return payload, nil } -func Dump(inner AdmissionHandler) AdmissionHandler { +func (h AdmissionHandler) WithDump(enabled bool) AdmissionHandler { + if !enabled { + return h + } + return withDump(h) +} + +func withDump(inner AdmissionHandler) AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { response := inner(logger, request, startTime) dumpPayload(logger, request, response) diff --git a/pkg/webhooks/handlers/filter.go b/pkg/webhooks/handlers/filter.go index 77f97b4c3f..24a70952f1 100644 --- a/pkg/webhooks/handlers/filter.go +++ b/pkg/webhooks/handlers/filter.go @@ -8,7 +8,11 @@ import ( admissionv1 "k8s.io/api/admission/v1" ) -func Filter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { +func (h AdmissionHandler) WithFilter(configuration config.Configuration) AdmissionHandler { + return withFilter(configuration, h) +} + +func withFilter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { if c.ToFilter(request.Kind.Kind, request.Namespace, request.Name) { return nil diff --git a/pkg/webhooks/handlers/metrics.go b/pkg/webhooks/handlers/metrics.go new file mode 100644 index 0000000000..8cd8d84890 --- /dev/null +++ b/pkg/webhooks/handlers/metrics.go @@ -0,0 +1,23 @@ +package handlers + +import ( + "time" + + "github.com/go-logr/logr" + "github.com/kyverno/kyverno/pkg/metrics" + admissionRequests "github.com/kyverno/kyverno/pkg/metrics/admissionrequests" + admissionReviewDuration "github.com/kyverno/kyverno/pkg/metrics/admissionreviewduration" + admissionv1 "k8s.io/api/admission/v1" +) + +func (h AdmissionHandler) WithMetrics(metricsConfig *metrics.MetricsConfig) AdmissionHandler { + return withMetrics(metricsConfig, h) +} + +func withMetrics(metricsConfig *metrics.MetricsConfig, inner AdmissionHandler) AdmissionHandler { + return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + defer admissionReviewDuration.Process(metricsConfig, request, int64(time.Since(startTime))) + admissionRequests.Process(metricsConfig, request) + return inner(logger, request, startTime) + } +} diff --git a/pkg/webhooks/handlers/protect.go b/pkg/webhooks/handlers/protect.go index 2c0b7aef23..51e63dd6a0 100644 --- a/pkg/webhooks/handlers/protect.go +++ b/pkg/webhooks/handlers/protect.go @@ -14,7 +14,14 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -func Protect(inner AdmissionHandler) AdmissionHandler { +func (h AdmissionHandler) WithProtection(enabled bool) AdmissionHandler { + if !enabled { + return h + } + return withProtection(h) +} + +func withProtection(inner AdmissionHandler) AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { newResource, oldResource, err := utils.ExtractResources(nil, request) if err != nil { diff --git a/pkg/webhooks/resource/generation/generation.go b/pkg/webhooks/resource/generation/generation.go index daa93ed429..90d37226a8 100644 --- a/pkg/webhooks/resource/generation/generation.go +++ b/pkg/webhooks/resource/generation/generation.go @@ -38,9 +38,6 @@ type GenerationHandler interface { []kyvernov1.PolicyInterface, *engine.PolicyContext, time.Time, - *chan int64, - *chan []*response.EngineResponse, - *chan []*response.EngineResponse, ) } @@ -84,9 +81,6 @@ func (h *generationHandler) Handle( policies []kyvernov1.PolicyInterface, policyContext *engine.PolicyContext, admissionRequestTimestamp time.Time, - latencySender *chan int64, - generateEngineResponsesSenderForAdmissionReviewDurationMetric *chan []*response.EngineResponse, - generateEngineResponsesSenderForAdmissionRequestsCountMetric *chan []*response.EngineResponse, ) { h.log.V(6).Info("update request") @@ -132,12 +126,6 @@ func (h *generationHandler) Handle( if request.Operation == admissionv1.Update { h.HandleUpdatesForGenerateRules(request, policies) } - - // sending the admission request latency to other goroutine (reporting the metrics) over the channel - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - *latencySender <- admissionReviewLatencyDuration - *generateEngineResponsesSenderForAdmissionReviewDurationMetric <- engineResponses - *generateEngineResponsesSenderForAdmissionRequestsCountMetric <- engineResponses } // HandleUpdatesForGenerateRules handles admission-requests for update diff --git a/pkg/webhooks/resource/mutation/mutation.go b/pkg/webhooks/resource/mutation/mutation.go index bebdc56257..ab812aaa2a 100644 --- a/pkg/webhooks/resource/mutation/mutation.go +++ b/pkg/webhooks/resource/mutation/mutation.go @@ -70,13 +70,7 @@ func (h *mutationHandler) HandleMutation( if err != nil { return nil, nil, err } - h.log.V(6).Info("", "generated patches", string(mutatePatches)) - - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - go webhookutils.RegisterAdmissionReviewDurationMetricMutate(h.log, metricsConfig, string(request.Operation), mutateEngineResponses, admissionReviewLatencyDuration) - go webhookutils.RegisterAdmissionRequestsMetricMutate(h.log, metricsConfig, string(request.Operation), mutateEngineResponses) - return mutatePatches, webhookutils.GetWarningMessages(mutateEngineResponses), nil } diff --git a/pkg/webhooks/resource/updaterequest.go b/pkg/webhooks/resource/updaterequest.go index 6e060ba167..0fab3b88ba 100644 --- a/pkg/webhooks/resource/updaterequest.go +++ b/pkg/webhooks/resource/updaterequest.go @@ -17,16 +17,9 @@ import ( // createUpdateRequests applies generate and mutateExisting policies, and creates update requests for background reconcile func (h *handlers) createUpdateRequests(logger logr.Logger, request *admissionv1.AdmissionRequest, policyContext *engine.PolicyContext, generatePolicies, mutatePolicies []kyvernov1.PolicyInterface, ts time.Time) { - admissionReviewCompletionLatencyChannel := make(chan int64, 1) - generateEngineResponsesSenderForAdmissionReviewDurationMetric := make(chan []*response.EngineResponse, 1) - generateEngineResponsesSenderForAdmissionRequestsCountMetric := make(chan []*response.EngineResponse, 1) - gh := generation.NewGenerationHandler(logger, h.client, h.kyvernoClient, h.nsLister, h.urLister, h.urGenerator, h.urUpdater, h.eventGen) go h.handleMutateExisting(logger, request, mutatePolicies, policyContext, ts) - go gh.Handle(h.metricsConfig, request, generatePolicies, policyContext, ts, &admissionReviewCompletionLatencyChannel, &generateEngineResponsesSenderForAdmissionReviewDurationMetric, &generateEngineResponsesSenderForAdmissionRequestsCountMetric) - - go webhookutils.RegisterAdmissionReviewDurationMetricGenerate(logger, h.metricsConfig, string(request.Operation), &admissionReviewCompletionLatencyChannel, &generateEngineResponsesSenderForAdmissionReviewDurationMetric) - go webhookutils.RegisterAdmissionRequestsMetricGenerate(logger, h.metricsConfig, string(request.Operation), &generateEngineResponsesSenderForAdmissionRequestsCountMetric) + go gh.Handle(h.metricsConfig, request, generatePolicies, policyContext, ts) } func (h *handlers) handleMutateExisting(logger logr.Logger, request *admissionv1.AdmissionRequest, policies []kyvernov1.PolicyInterface, policyContext *engine.PolicyContext, admissionRequestTimestamp time.Time) { @@ -75,8 +68,4 @@ func (h *handlers) handleMutateExisting(logger logr.Logger, request *admissionv1 h.eventGen.Add(events...) } } - - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - go webhookutils.RegisterAdmissionReviewDurationMetricMutate(logger, h.metricsConfig, string(request.Operation), engineResponses, admissionReviewLatencyDuration) - go webhookutils.RegisterAdmissionRequestsMetricMutate(logger, h.metricsConfig, string(request.Operation), engineResponses) } diff --git a/pkg/webhooks/resource/validation/validation.go b/pkg/webhooks/resource/validation/validation.go index 2518f007c0..6813c8a3e3 100644 --- a/pkg/webhooks/resource/validation/validation.go +++ b/pkg/webhooks/resource/validation/validation.go @@ -123,23 +123,15 @@ func (v *validationHandler) HandleValidation( if blocked { logger.V(4).Info("admission request blocked") - v.generateMetrics(request, admissionRequestTimestamp, engineResponses, metricsConfig, logger) return false, webhookutils.GetBlockedMessages(engineResponses), nil } - v.generateMetrics(request, admissionRequestTimestamp, engineResponses, metricsConfig, logger) go v.handleAudit(policyContext.NewResource, request, namespaceLabels, engineResponses...) warnings := webhookutils.GetWarningMessages(engineResponses) return true, "", warnings } -func (v *validationHandler) generateMetrics(request *admissionv1.AdmissionRequest, admissionRequestTimestamp time.Time, engineResponses []*response.EngineResponse, metricsConfig *metrics.MetricsConfig, logger logr.Logger) { - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - go webhookutils.RegisterAdmissionReviewDurationMetricValidate(logger, metricsConfig, string(request.Operation), engineResponses, admissionReviewLatencyDuration) - go webhookutils.RegisterAdmissionRequestsMetricValidate(logger, metricsConfig, string(request.Operation), engineResponses) -} - func (v *validationHandler) buildAuditResponses(resource unstructured.Unstructured, request *admissionv1.AdmissionRequest, namespaceLabels map[string]string) ([]*response.EngineResponse, error) { policies := v.pCache.GetPolicies(policycache.ValidateAudit, request.Kind.Kind, request.Namespace) policyContext, err := v.pcBuilder.Build(request, policies...) diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 2846b49f42..169182cba5 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -10,6 +10,7 @@ import ( "github.com/julienschmidt/httprouter" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/logging" + "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/toggle" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" runtimeutils "github.com/kyverno/kyverno/pkg/utils/runtime" @@ -66,6 +67,7 @@ func NewServer( policyHandlers PolicyHandlers, resourceHandlers ResourceHandlers, configuration config.Configuration, + metricsConfig *metrics.MetricsConfig, debugModeOpts DebugModeOptions, tlsProvider TlsProvider, mwcClient controllerutils.DeleteClient[*admissionregistrationv1.MutatingWebhookConfiguration], @@ -77,11 +79,32 @@ func NewServer( resourceLogger := logger.WithName("resource") policyLogger := logger.WithName("policy") verifyLogger := logger.WithName("verify") - registerWebhookHandlers(resourceLogger.WithName("mutate"), mux, config.MutatingWebhookServicePath, configuration, resourceHandlers.Mutate, debugModeOpts) - registerWebhookHandlers(resourceLogger.WithName("validate"), mux, config.ValidatingWebhookServicePath, configuration, resourceHandlers.Validate, debugModeOpts) - mux.HandlerFunc("POST", config.PolicyMutatingWebhookServicePath, admission(policyLogger.WithName("mutate"), filter(configuration, policyHandlers.Mutate), debugModeOpts)) - mux.HandlerFunc("POST", config.PolicyValidatingWebhookServicePath, admission(policyLogger.WithName("validate"), filter(configuration, policyHandlers.Validate), debugModeOpts)) - mux.HandlerFunc("POST", config.VerifyMutatingWebhookServicePath, admission(verifyLogger.WithName("mutate"), handlers.Verify(), DebugModeOptions{})) + registerWebhookHandlers(resourceLogger.WithName("mutate"), mux, config.MutatingWebhookServicePath, configuration, metricsConfig, resourceHandlers.Mutate, debugModeOpts) + registerWebhookHandlers(resourceLogger.WithName("validate"), mux, config.ValidatingWebhookServicePath, configuration, metricsConfig, resourceHandlers.Validate, debugModeOpts) + mux.HandlerFunc( + "POST", + config.PolicyMutatingWebhookServicePath, + handlers.AdmissionHandler(policyHandlers.Mutate). + WithFilter(configuration). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(policyLogger.WithName("mutate")), + ) + mux.HandlerFunc( + "POST", + config.PolicyValidatingWebhookServicePath, + handlers.AdmissionHandler(policyHandlers.Validate). + WithFilter(configuration). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(policyLogger.WithName("validate")), + ) + mux.HandlerFunc( + "POST", + config.VerifyMutatingWebhookServicePath, + handlers.Verify(). + WithAdmission(verifyLogger.WithName("mutate")), + ) mux.HandlerFunc("GET", config.LivenessServicePath, handlers.Probe(runtime.IsLive)) mux.HandlerFunc("GET", config.ReadinessServicePath, handlers.Probe(runtime.IsReady)) return &server{ @@ -170,53 +193,49 @@ func (s *server) cleanup(ctx context.Context) { close(s.cleanUp) } -func dump(inner handlers.AdmissionHandler, debugModeOpts DebugModeOptions) handlers.AdmissionHandler { - // debug mode not enabled, no need to add debug middleware - if !debugModeOpts.DumpPayload { - return inner - } - return handlers.Dump(inner) -} - -func protect(inner handlers.AdmissionHandler) handlers.AdmissionHandler { - if !toggle.ProtectManagedResources.Enabled() { - return inner - } - return handlers.Protect(inner) -} - -func filter(configuration config.Configuration, inner handlers.AdmissionHandler) handlers.AdmissionHandler { - return handlers.Filter(configuration, inner) -} - -func admission(logger logr.Logger, inner handlers.AdmissionHandler, debugModeOpts DebugModeOptions) http.HandlerFunc { - return handlers.Admission(logger, dump(protect(inner), debugModeOpts)) -} - func registerWebhookHandlers( logger logr.Logger, mux *httprouter.Router, basePath string, configuration config.Configuration, + metricsConfig *metrics.MetricsConfig, handlerFunc func(logr.Logger, *admissionv1.AdmissionRequest, string, time.Time) *admissionv1.AdmissionResponse, debugModeOpts DebugModeOptions, ) { - mux.HandlerFunc("POST", basePath, admission(logger, filter( - configuration, - func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + mux.HandlerFunc( + "POST", + basePath, + handlers.AdmissionHandler(func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { return handlerFunc(logger, request, "all", startTime) - }), debugModeOpts), + }). + WithFilter(configuration). + WithProtection(toggle.ProtectManagedResources.Enabled()). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(logger), ) - mux.HandlerFunc("POST", basePath+"/fail", admission(logger, filter( - configuration, - func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + mux.HandlerFunc( + "POST", + basePath+"/fail", + handlers.AdmissionHandler(func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { return handlerFunc(logger, request, "fail", startTime) - }), debugModeOpts), + }). + WithFilter(configuration). + WithProtection(toggle.ProtectManagedResources.Enabled()). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(logger), ) - mux.HandlerFunc("POST", basePath+"/ignore", admission(logger, filter( - configuration, - func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + mux.HandlerFunc( + "POST", + basePath+"/ignore", + handlers.AdmissionHandler(func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { return handlerFunc(logger, request, "ignore", startTime) - }), debugModeOpts), + }). + WithFilter(configuration). + WithProtection(toggle.ProtectManagedResources.Enabled()). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(logger), ) } diff --git a/pkg/webhooks/utils/metrics.go b/pkg/webhooks/utils/metrics.go index 9d2d36beb2..8f9fa65941 100644 --- a/pkg/webhooks/utils/metrics.go +++ b/pkg/webhooks/utils/metrics.go @@ -7,8 +7,6 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/metrics" - admissionRequests "github.com/kyverno/kyverno/pkg/metrics/admissionrequests" - admissionReviewDuration "github.com/kyverno/kyverno/pkg/metrics/admissionreviewduration" policyExecutionDuration "github.com/kyverno/kyverno/pkg/metrics/policyexecutionduration" policyResults "github.com/kyverno/kyverno/pkg/metrics/policyresults" ) @@ -25,49 +23,6 @@ func registerMetric(logger logr.Logger, m string, requestOperation string, r rep } } -// ADMISSION REVIEW - -func RegisterAdmissionReviewDurationMetricMutate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse, admissionReviewLatencyDuration int64) { - registerMetric(logger, "kyverno_admission_review_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionReviewDuration.ProcessEngineResponses(metricsConfig, engineResponses, admissionReviewLatencyDuration, op) - }) -} - -func RegisterAdmissionReviewDurationMetricGenerate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, latencyReceiver *chan int64, engineResponsesReceiver *chan []*response.EngineResponse) { - defer close(*latencyReceiver) - defer close(*engineResponsesReceiver) - registerMetric(logger, "kyverno_admission_review_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionReviewDuration.ProcessEngineResponses(metricsConfig, <-(*engineResponsesReceiver), <-(*latencyReceiver), op) - }) -} - -func RegisterAdmissionReviewDurationMetricValidate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse, admissionReviewLatencyDuration int64) { - registerMetric(logger, "kyverno_admission_review_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionReviewDuration.ProcessEngineResponses(metricsConfig, engineResponses, admissionReviewLatencyDuration, op) - }) -} - -// ADMISSION REQUEST - -func RegisterAdmissionRequestsMetricMutate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse) { - registerMetric(logger, "kyverno_admission_requests_total", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionRequests.ProcessEngineResponses(metricsConfig, engineResponses, op) - }) -} - -func RegisterAdmissionRequestsMetricGenerate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponsesReceiver *chan []*response.EngineResponse) { - defer close(*engineResponsesReceiver) - registerMetric(logger, "kyverno_admission_requests_total", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionRequests.ProcessEngineResponses(metricsConfig, <-(*engineResponsesReceiver), op) - }) -} - -func RegisterAdmissionRequestsMetricValidate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse) { - registerMetric(logger, "kyverno_admission_requests_total", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionRequests.ProcessEngineResponses(metricsConfig, engineResponses, op) - }) -} - // POLICY RESULTS func RegisterPolicyResultsMetricMutation(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {