make use of new error reporting in the dispatcher.
This commit is contained in:
		@@ -223,7 +223,7 @@ func (c *dispatcher) Dispatch(ctx context.Context, a admission.Attributes, o adm
 | 
				
			|||||||
					switch decision.Action {
 | 
										switch decision.Action {
 | 
				
			||||||
					case ActionAdmit:
 | 
										case ActionAdmit:
 | 
				
			||||||
						if decision.Evaluation == EvalError {
 | 
											if decision.Evaluation == EvalError {
 | 
				
			||||||
							celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.Elapsed, definition.Name, binding.Name)
 | 
												celmetrics.Metrics.ObserveAdmission(ctx, decision.Elapsed, definition.Name, binding.Name, ErrorType(&decision))
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					case ActionDeny:
 | 
										case ActionDeny:
 | 
				
			||||||
						for _, action := range binding.Spec.ValidationActions {
 | 
											for _, action := range binding.Spec.ValidationActions {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2024 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package validating
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						celmetrics "k8s.io/apiserver/pkg/admission/plugin/policy/validating/metrics"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ErrorType decodes the error to determine the error type
 | 
				
			||||||
 | 
					// that the metrics understand.
 | 
				
			||||||
 | 
					func ErrorType(decision *PolicyDecision) celmetrics.ValidationErrorType {
 | 
				
			||||||
 | 
						if decision.Evaluation == EvalAdmit {
 | 
				
			||||||
 | 
							return celmetrics.ValidationNoError
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if strings.HasPrefix(decision.Message, "compilation") {
 | 
				
			||||||
 | 
							return celmetrics.ValidationCompileError
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if strings.HasPrefix(decision.Message, "validation failed due to running out of cost budget") {
 | 
				
			||||||
 | 
							return celmetrics.ValidatingOutOfBudget
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return celmetrics.ValidatingInternalError
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2024 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apiservercel "k8s.io/apiserver/pkg/cel"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ErrorType decodes the error to determine the error type
 | 
				
			||||||
 | 
					// that the metrics understand.
 | 
				
			||||||
 | 
					func ErrorType(err error) ValidationErrorType {
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							return ValidationNoError
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if errors.Is(err, apiservercel.ErrCompilation) {
 | 
				
			||||||
 | 
							return ValidationCompileError
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if errors.Is(err, apiservercel.ErrOutOfBudget) {
 | 
				
			||||||
 | 
							return ValidatingOutOfBudget
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ValidatingInternalError
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -29,6 +29,22 @@ const (
 | 
				
			|||||||
	metricsSubsystem = "validating_admission_policy"
 | 
						metricsSubsystem = "validating_admission_policy"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ValidationErrorType defines different error types that happen to a validation expression
 | 
				
			||||||
 | 
					type ValidationErrorType string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// ValidationCompileError indicates that the expression fails to compile.
 | 
				
			||||||
 | 
						ValidationCompileError ValidationErrorType = "compile_error"
 | 
				
			||||||
 | 
						// ValidatingInternalError indicates that the expression fails due to internal
 | 
				
			||||||
 | 
						// errors that are out of the control of the user.
 | 
				
			||||||
 | 
						ValidatingInternalError ValidationErrorType = "internal_error"
 | 
				
			||||||
 | 
						// ValidatingOutOfBudget indicates that the expression fails due to running
 | 
				
			||||||
 | 
						// out of cost budget, or the budget cannot be obtained.
 | 
				
			||||||
 | 
						ValidatingOutOfBudget ValidationErrorType = "out_of_budget"
 | 
				
			||||||
 | 
						// ValidationNoError indicates that the expression returns without an error.
 | 
				
			||||||
 | 
						ValidationNoError ValidationErrorType = "no_error"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// Metrics provides access to validation admission metrics.
 | 
						// Metrics provides access to validation admission metrics.
 | 
				
			||||||
	Metrics = newValidationAdmissionMetrics()
 | 
						Metrics = newValidationAdmissionMetrics()
 | 
				
			||||||
@@ -81,8 +97,8 @@ func (m *ValidatingAdmissionPolicyMetrics) Reset() {
 | 
				
			|||||||
	m.policyLatency.Reset()
 | 
						m.policyLatency.Reset()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ObserveAdmissionWithError observes a policy validation error that was ignored due to failure policy.
 | 
					// ObserveAdmission observes a policy validation, with an optional error to indicate the error that may occur but ignored.
 | 
				
			||||||
func (m *ValidatingAdmissionPolicyMetrics) ObserveAdmissionWithError(ctx context.Context, elapsed time.Duration, policy, binding string) {
 | 
					func (m *ValidatingAdmissionPolicyMetrics) ObserveAdmission(ctx context.Context, elapsed time.Duration, policy, binding string, errorType ValidationErrorType) {
 | 
				
			||||||
	m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "allow").Inc()
 | 
						m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "allow").Inc()
 | 
				
			||||||
	m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "allow").Observe(elapsed.Seconds())
 | 
						m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "allow").Observe(elapsed.Seconds())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,7 @@ func TestNoUtils(t *testing.T) {
 | 
				
			|||||||
            apiserver_validating_admission_policy_check_total{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com"} 1
 | 
					            apiserver_validating_admission_policy_check_total{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com"} 1
 | 
				
			||||||
			`,
 | 
								`,
 | 
				
			||||||
			observer: func() {
 | 
								observer: func() {
 | 
				
			||||||
				Metrics.ObserveAdmissionWithError(context.TODO(), time.Duration(10)*time.Second, "policy.example.com", "binding.example.com")
 | 
									Metrics.ObserveAdmission(context.TODO(), time.Duration(10)*time.Second, "policy.example.com", "binding.example.com")
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user