From a09d2a77e5619a7b2aba4cd86e3e8fa9ace0da6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 28 Nov 2022 09:59:05 +0100 Subject: [PATCH] feat: add allowed label to admission metrics (#5478) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/metrics/admissionrequests/admissionRequests.go | 8 ++++---- .../admissionreviewduration/admissionReviewDuration.go | 8 ++++---- pkg/metrics/metrics.go | 10 ++++++---- pkg/webhooks/handlers/metrics.go | 7 ++++--- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pkg/metrics/admissionrequests/admissionRequests.go b/pkg/metrics/admissionrequests/admissionRequests.go index 44f35e22c784..9543598a97a4 100644 --- a/pkg/metrics/admissionrequests/admissionRequests.go +++ b/pkg/metrics/admissionrequests/admissionRequests.go @@ -9,7 +9,7 @@ import ( admissionv1 "k8s.io/api/admission/v1" ) -func registerAdmissionRequestsMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation) { +func registerAdmissionRequestsMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation, allowed bool) { 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)) @@ -19,10 +19,10 @@ func registerAdmissionRequestsMetric(m *metrics.MetricsConfig, resourceKind, res 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 } - m.RecordAdmissionRequests(resourceKind, resourceNamespace, resourceRequestOperation) + m.RecordAdmissionRequests(resourceKind, resourceNamespace, resourceRequestOperation, allowed) } -func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest) { +func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest, response *admissionv1.AdmissionResponse) { op := strings.ToLower(string(request.Operation)) - registerAdmissionRequestsMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op)) + registerAdmissionRequestsMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op), response.Allowed) } diff --git a/pkg/metrics/admissionreviewduration/admissionReviewDuration.go b/pkg/metrics/admissionreviewduration/admissionReviewDuration.go index ec00247ec2b1..ea33b2db4762 100644 --- a/pkg/metrics/admissionreviewduration/admissionReviewDuration.go +++ b/pkg/metrics/admissionreviewduration/admissionReviewDuration.go @@ -9,7 +9,7 @@ import ( admissionv1 "k8s.io/api/admission/v1" ) -func registerAdmissionReviewDurationMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation, admissionRequestLatency float64) { +func registerAdmissionReviewDurationMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation, admissionRequestLatency float64, allowed bool) { 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)) @@ -19,11 +19,11 @@ func registerAdmissionReviewDurationMetric(m *metrics.MetricsConfig, resourceKin 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 } - m.RecordAdmissionReviewDuration(resourceKind, resourceNamespace, string(resourceRequestOperation), admissionRequestLatency) + m.RecordAdmissionReviewDuration(resourceKind, resourceNamespace, string(resourceRequestOperation), admissionRequestLatency, allowed) } -func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest, latency int64) { +func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest, response *admissionv1.AdmissionResponse, 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) + registerAdmissionReviewDurationMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op), admissionReviewLatencyDurationInSeconds, response.Allowed) } diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index a5e3ac7444c0..57661feab867 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -50,9 +50,9 @@ type MetricsConfigManager interface { RecordPolicyResults(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause) RecordPolicyChanges(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, policyChangeType string) RecordPolicyRuleInfo(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, ruleName string, ruleType RuleType, status string, metricValue float64) - RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation) RecordPolicyExecutionDuration(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause, ruleExecutionLatency float64) - RecordAdmissionReviewDuration(resourceKind string, resourceNamespace string, resourceRequestOperation string, admissionRequestLatency float64) + RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, allowed bool) + RecordAdmissionReviewDuration(resourceKind string, resourceNamespace string, resourceRequestOperation string, admissionRequestLatency float64, allowed bool) RecordClientQueries(clientQueryOperation ClientQueryOperation, clientType ClientType, resourceKind string, resourceNamespace string) } @@ -275,13 +275,14 @@ func (m *MetricsConfig) RecordPolicyRuleInfo(policyValidationMode PolicyValidati m.policyRuleInfoMetric.Observe(ctx, metricValue, commonLabels...) } -func (m *MetricsConfig) RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation) { +func (m *MetricsConfig) RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, allowed bool) { ctx := context.Background() commonLabels := []attribute.KeyValue{ attribute.String("resource_kind", resourceKind), attribute.String("resource_namespace", resourceNamespace), attribute.String("resource_request_operation", string(resourceRequestOperation)), + attribute.Bool("request_allowed", allowed), } m.admissionRequestsMetric.Add(ctx, 1, commonLabels...) @@ -307,13 +308,14 @@ func (m *MetricsConfig) RecordPolicyExecutionDuration(policyValidationMode Polic m.policyExecutionDurationMetric.Record(ctx, ruleExecutionLatency, commonLabels...) } -func (m *MetricsConfig) RecordAdmissionReviewDuration(resourceKind string, resourceNamespace string, resourceRequestOperation string, admissionRequestLatency float64) { +func (m *MetricsConfig) RecordAdmissionReviewDuration(resourceKind string, resourceNamespace string, resourceRequestOperation string, admissionRequestLatency float64, allowed bool) { ctx := context.Background() commonLabels := []attribute.KeyValue{ attribute.String("resource_kind", resourceKind), attribute.String("resource_namespace", resourceNamespace), attribute.String("resource_request_operation", resourceRequestOperation), + attribute.Bool("request_allowed", allowed), } m.admissionReviewDurationMetric.Record(ctx, admissionRequestLatency, commonLabels...) diff --git a/pkg/webhooks/handlers/metrics.go b/pkg/webhooks/handlers/metrics.go index 5aa34eb0b807..59ff5d5173d9 100644 --- a/pkg/webhooks/handlers/metrics.go +++ b/pkg/webhooks/handlers/metrics.go @@ -17,8 +17,9 @@ func (inner AdmissionHandler) WithMetrics(metricsConfig *metrics.MetricsConfig) func (inner AdmissionHandler) withMetrics(metricsConfig *metrics.MetricsConfig) AdmissionHandler { return func(ctx context.Context, 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(ctx, logger, request, startTime) + response := inner(ctx, logger, request, startTime) + defer admissionReviewDuration.Process(metricsConfig, request, response, int64(time.Since(startTime))) + admissionRequests.Process(metricsConfig, request, response) + return response } }