mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 00:07:50 +00:00
Add metrics integration.
This commit is contained in:
parent
c84e920a48
commit
99494e6777
@ -47,10 +47,10 @@ func newValidationAdmissionMetrics() *ValidatingAdmissionPolicyMetrics {
|
|||||||
Namespace: metricsNamespace,
|
Namespace: metricsNamespace,
|
||||||
Subsystem: metricsSubsystem,
|
Subsystem: metricsSubsystem,
|
||||||
Name: "check_total",
|
Name: "check_total",
|
||||||
Help: "Validation admission policy check total, labeled by policy and param resource, and further identified by binding, validation expression, enforcement action taken, and state.",
|
Help: "Validation admission policy check total, labeled by policy and further identified by binding, enforcement action taken, and state.",
|
||||||
StabilityLevel: metrics.ALPHA,
|
StabilityLevel: metrics.ALPHA,
|
||||||
},
|
},
|
||||||
[]string{"policy", "policy_binding", "validation_expression", "enforcement_action", "params", "state"},
|
[]string{"policy", "policy_binding", "enforcement_action", "state"},
|
||||||
)
|
)
|
||||||
definition := metrics.NewCounterVec(&metrics.CounterOpts{
|
definition := metrics.NewCounterVec(&metrics.CounterOpts{
|
||||||
Namespace: metricsNamespace,
|
Namespace: metricsNamespace,
|
||||||
@ -65,7 +65,7 @@ func newValidationAdmissionMetrics() *ValidatingAdmissionPolicyMetrics {
|
|||||||
Namespace: metricsNamespace,
|
Namespace: metricsNamespace,
|
||||||
Subsystem: metricsSubsystem,
|
Subsystem: metricsSubsystem,
|
||||||
Name: "check_duration_seconds",
|
Name: "check_duration_seconds",
|
||||||
Help: "Validation admission latency for individual validation expressions in seconds, labeled by policy and param resource, further including binding, state and enforcement action taken.",
|
Help: "Validation admission latency for individual validation expressions in seconds, labeled by policy and further including binding, state and enforcement action taken.",
|
||||||
// the bucket distribution here is based oo the benchmark suite at
|
// the bucket distribution here is based oo the benchmark suite at
|
||||||
// github.com/DangerOnTheRanger/cel-benchmark performed on 16-core Intel Xeon
|
// github.com/DangerOnTheRanger/cel-benchmark performed on 16-core Intel Xeon
|
||||||
// the lowest bucket was based around the 180ns/op figure for BenchmarkAccess,
|
// the lowest bucket was based around the 180ns/op figure for BenchmarkAccess,
|
||||||
@ -77,7 +77,7 @@ func newValidationAdmissionMetrics() *ValidatingAdmissionPolicyMetrics {
|
|||||||
Buckets: []float64{0.0000005, 0.001, 0.01, 0.1, 1.0},
|
Buckets: []float64{0.0000005, 0.001, 0.01, 0.1, 1.0},
|
||||||
StabilityLevel: metrics.ALPHA,
|
StabilityLevel: metrics.ALPHA,
|
||||||
},
|
},
|
||||||
[]string{"policy", "policy_binding", "validation_expression", "enforcement_action", "params", "state"},
|
[]string{"policy", "policy_binding", "enforcement_action", "state"},
|
||||||
)
|
)
|
||||||
|
|
||||||
legacyregistry.MustRegister(check)
|
legacyregistry.MustRegister(check)
|
||||||
@ -98,8 +98,14 @@ func (m *ValidatingAdmissionPolicyMetrics) ObserveDefinition(ctx context.Context
|
|||||||
m.policyDefinition.WithContext(ctx).WithLabelValues(state, enforcementAction).Inc()
|
m.policyDefinition.WithContext(ctx).WithLabelValues(state, enforcementAction).Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObserveCheck observes a policy validation check.
|
// ObserveAdmissionWithError observes a policy validation error that was ignored due to failure policy.
|
||||||
func (m *ValidatingAdmissionPolicyMetrics) ObserveCheck(ctx context.Context, elapsed time.Duration, policy, binding, expression, enforcementAction, params, state string) {
|
func (m *ValidatingAdmissionPolicyMetrics) ObserveAdmissionWithError(ctx context.Context, elapsed time.Duration, policy, binding, state string) {
|
||||||
m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, expression, enforcementAction, params, state).Inc()
|
m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "allow", state).Inc()
|
||||||
m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, expression, enforcementAction, params, state).Observe(elapsed.Seconds())
|
m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "allow", state).Observe(elapsed.Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObserveRejection observes a policy validation error that was at least one of the reasons for a deny.
|
||||||
|
func (m *ValidatingAdmissionPolicyMetrics) ObserveRejection(ctx context.Context, elapsed time.Duration, policy, binding, state string) {
|
||||||
|
m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "deny", state).Inc()
|
||||||
|
m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "deny", state).Observe(elapsed.Seconds())
|
||||||
}
|
}
|
||||||
|
@ -42,24 +42,45 @@ func TestNoUtils(t *testing.T) {
|
|||||||
observer metricsObserver
|
observer metricsObserver
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "observe policy check",
|
desc: "observe policy admission",
|
||||||
want: `
|
want: `
|
||||||
# HELP apiserver_validating_admission_policy_check_duration_seconds [ALPHA] Validation admission latency for individual validation expressions in seconds, labeled by policy and param resource, further including binding, state and enforcement action taken.
|
# HELP apiserver_validating_admission_policy_check_duration_seconds [ALPHA] Validation admission latency for individual validation expressions in seconds, labeled by policy and further including binding, state and enforcement action taken.
|
||||||
# TYPE apiserver_validating_admission_policy_check_duration_seconds histogram
|
# TYPE apiserver_validating_admission_policy_check_duration_seconds histogram
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true",le="0.0000005"} 0
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.0000005"} 0
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true",le="0.001"} 0
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.001"} 0
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true",le="0.01"} 0
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.01"} 0
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true",le="0.1"} 0
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.1"} 0
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true",le="1"} 0
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="1"} 0
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true",le="+Inf"} 1
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="+Inf"} 1
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_sum{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true"} 10
|
apiserver_validating_admission_policy_check_duration_seconds_sum{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active"} 10
|
||||||
apiserver_validating_admission_policy_check_duration_seconds_count{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true"} 1
|
apiserver_validating_admission_policy_check_duration_seconds_count{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active"} 1
|
||||||
# HELP apiserver_validating_admission_policy_check_total [ALPHA] Validation admission policy check total, labeled by policy and param resource, and further identified by binding, validation expression, enforcement action taken, and state.
|
# HELP apiserver_validating_admission_policy_check_total [ALPHA] Validation admission policy check total, labeled by policy and further identified by binding, enforcement action taken, and state.
|
||||||
# TYPE apiserver_validating_admission_policy_check_total counter
|
# TYPE apiserver_validating_admission_policy_check_total counter
|
||||||
apiserver_validating_admission_policy_check_total{enforcement_action="allow",params="params.example.com",policy="policy.example.com",policy_binding="binding.example.com",state="active",validation_expression="true"} 1
|
apiserver_validating_admission_policy_check_total{enforcement_action="allow",policy="policy.example.com",policy_binding="binding.example.com",state="active"} 1
|
||||||
`,
|
`,
|
||||||
observer: func() {
|
observer: func() {
|
||||||
Metrics.ObserveCheck(context.TODO(), time.Duration(10)*time.Second, "policy.example.com", "binding.example.com", "true", "allow", "params.example.com", "active")
|
Metrics.ObserveAdmissionWithError(context.TODO(), time.Duration(10)*time.Second, "policy.example.com", "binding.example.com", "active")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "observe policy rejection",
|
||||||
|
want: `
|
||||||
|
# HELP apiserver_validating_admission_policy_check_duration_seconds [ALPHA] Validation admission latency for individual validation expressions in seconds, labeled by policy and further including binding, state and enforcement action taken.
|
||||||
|
# TYPE apiserver_validating_admission_policy_check_duration_seconds histogram
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.0000005"} 0
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.001"} 0
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.01"} 0
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="0.1"} 0
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="1"} 0
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_bucket{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active",le="+Inf"} 1
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_sum{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active"} 10
|
||||||
|
apiserver_validating_admission_policy_check_duration_seconds_count{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active"} 1
|
||||||
|
# HELP apiserver_validating_admission_policy_check_total [ALPHA] Validation admission policy check total, labeled by policy and further identified by binding, enforcement action taken, and state.
|
||||||
|
# TYPE apiserver_validating_admission_policy_check_total counter
|
||||||
|
apiserver_validating_admission_policy_check_total{enforcement_action="deny",policy="policy.example.com",policy_binding="binding.example.com",state="active"} 1
|
||||||
|
`,
|
||||||
|
observer: func() {
|
||||||
|
Metrics.ObserveRejection(context.TODO(), time.Duration(10)*time.Second, "policy.example.com", "binding.example.com", "active")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -581,7 +581,7 @@ func (v testValidator) Validate(a admission.Attributes, o admission.ObjectInterf
|
|||||||
// Policy always denies
|
// Policy always denies
|
||||||
return []policyDecision{
|
return []policyDecision{
|
||||||
{
|
{
|
||||||
kind: deny,
|
action: actionDeny,
|
||||||
message: "Denied",
|
message: "Denied",
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
|
celmetrics "k8s.io/apiserver/pkg/admission/cel"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/cel/internal/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/cel/internal/generic"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
@ -227,7 +228,7 @@ func (c *celAdmissionController) Validate(
|
|||||||
}
|
}
|
||||||
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
||||||
policyDecision: policyDecision{
|
policyDecision: policyDecision{
|
||||||
kind: deny,
|
action: actionDeny,
|
||||||
message: message,
|
message: message,
|
||||||
},
|
},
|
||||||
definition: definition,
|
definition: definition,
|
||||||
@ -236,7 +237,7 @@ func (c *celAdmissionController) Validate(
|
|||||||
default:
|
default:
|
||||||
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
||||||
policyDecision: policyDecision{
|
policyDecision: policyDecision{
|
||||||
kind: deny,
|
action: actionDeny,
|
||||||
message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(),
|
message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(),
|
||||||
},
|
},
|
||||||
definition: definition,
|
definition: definition,
|
||||||
@ -353,18 +354,21 @@ func (c *celAdmissionController) Validate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, decision := range decisions {
|
for _, decision := range decisions {
|
||||||
switch decision.kind {
|
switch decision.action {
|
||||||
case admit:
|
case actionAdmit:
|
||||||
// TODO: add metrics for ignored error here
|
if decision.evaluation == evalError {
|
||||||
case deny:
|
celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.elapsed, definition.Name, binding.Name, "active")
|
||||||
|
}
|
||||||
|
case actionDeny:
|
||||||
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
||||||
definition: definition,
|
definition: definition,
|
||||||
binding: binding,
|
binding: binding,
|
||||||
policyDecision: decision,
|
policyDecision: decision,
|
||||||
})
|
})
|
||||||
|
celmetrics.Metrics.ObserveRejection(ctx, decision.elapsed, definition.Name, binding.Name, "active")
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unrecognized evaluation decision '%s' for ValidatingAdmissionPolicyBinding '%s' with ValidatingAdmissionPolicy '%s'",
|
return fmt.Errorf("unrecognized evaluation decision '%s' for ValidatingAdmissionPolicyBinding '%s' with ValidatingAdmissionPolicy '%s'",
|
||||||
decision.kind, binding.Name, definition.Name)
|
decision.action, binding.Name, definition.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -389,7 +393,6 @@ func (c *celAdmissionController) Validate(
|
|||||||
err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Message: message})
|
err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Message: message})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
celmetrics "k8s.io/apiserver/pkg/admission/cel"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/cel/internal/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/cel/internal/generic"
|
||||||
"k8s.io/client-go/dynamic/dynamicinformer"
|
"k8s.io/client-go/dynamic/dynamicinformer"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
@ -41,6 +42,8 @@ func (c *celAdmissionController) reconcilePolicyDefinition(namespace, name strin
|
|||||||
if !ok {
|
if !ok {
|
||||||
info = &definitionInfo{}
|
info = &definitionInfo{}
|
||||||
c.definitionInfo[nn] = info
|
c.definitionInfo[nn] = info
|
||||||
|
// TODO(DangerOnTheRanger): add support for "warn" being a valid enforcementAction
|
||||||
|
celmetrics.Metrics.ObserveDefinition(context.TODO(), "active", "deny")
|
||||||
}
|
}
|
||||||
|
|
||||||
var paramSource *v1alpha1.ParamKind
|
var paramSource *v1alpha1.ParamKind
|
||||||
|
@ -18,22 +18,33 @@ package cel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"k8s.io/api/admissionregistration/v1alpha1"
|
"k8s.io/api/admissionregistration/v1alpha1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type policyDecisionKind string
|
type policyDecisionAction string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
admit policyDecisionKind = "admit"
|
actionAdmit policyDecisionAction = "admit"
|
||||||
deny policyDecisionKind = "deny"
|
actionDeny policyDecisionAction = "deny"
|
||||||
|
)
|
||||||
|
|
||||||
|
type policyDecisionEvaluation string
|
||||||
|
|
||||||
|
const (
|
||||||
|
evalAdmit policyDecisionEvaluation = "admit"
|
||||||
|
evalError policyDecisionEvaluation = "error"
|
||||||
|
evalDeny policyDecisionEvaluation = "deny"
|
||||||
)
|
)
|
||||||
|
|
||||||
type policyDecision struct {
|
type policyDecision struct {
|
||||||
kind policyDecisionKind
|
action policyDecisionAction
|
||||||
message string
|
evaluation policyDecisionEvaluation
|
||||||
reason metav1.StatusReason
|
message string
|
||||||
|
reason metav1.StatusReason
|
||||||
|
elapsed time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type policyDecisionWithMetadata struct {
|
type policyDecisionWithMetadata struct {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
celtypes "github.com/google/cel-go/common/types"
|
celtypes "github.com/google/cel-go/common/types"
|
||||||
"github.com/google/cel-go/interpreter"
|
"github.com/google/cel-go/interpreter"
|
||||||
@ -156,11 +157,11 @@ func objectToResolveVal(r runtime.Object) (interface{}, error) {
|
|||||||
return v.Object, nil
|
return v.Object, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func policyDecisionKindForError(f v1alpha1.FailurePolicyType) policyDecisionKind {
|
func policyDecisionActionForError(f v1alpha1.FailurePolicyType) policyDecisionAction {
|
||||||
if f == v1alpha1.Ignore {
|
if f == v1alpha1.Ignore {
|
||||||
return admit
|
return actionAdmit
|
||||||
}
|
}
|
||||||
return deny
|
return actionDeny
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates all cel expressions in Validator and returns a PolicyDecision for each CEL expression or returns an error.
|
// Validate validates all cel expressions in Validator and returns a PolicyDecision for each CEL expression or returns an error.
|
||||||
@ -213,21 +214,27 @@ func (v *CELValidator) Validate(a admission.Attributes, o admission.ObjectInterf
|
|||||||
var policyDecision = &decisions[i]
|
var policyDecision = &decisions[i]
|
||||||
|
|
||||||
if compilationResult.Error != nil {
|
if compilationResult.Error != nil {
|
||||||
policyDecision.kind = policyDecisionKindForError(f)
|
policyDecision.action = policyDecisionActionForError(f)
|
||||||
|
policyDecision.evaluation = evalError
|
||||||
policyDecision.message = fmt.Sprintf("compilation error: %v", compilationResult.Error)
|
policyDecision.message = fmt.Sprintf("compilation error: %v", compilationResult.Error)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if compilationResult.Program == nil {
|
if compilationResult.Program == nil {
|
||||||
policyDecision.kind = policyDecisionKindForError(f)
|
policyDecision.action = policyDecisionActionForError(f)
|
||||||
|
policyDecision.evaluation = evalError
|
||||||
policyDecision.message = "unexpected internal error compiling expression"
|
policyDecision.message = "unexpected internal error compiling expression"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
t1 := time.Now()
|
||||||
evalResult, _, err := compilationResult.Program.Eval(va)
|
evalResult, _, err := compilationResult.Program.Eval(va)
|
||||||
|
elapsed := time.Since(t1)
|
||||||
|
policyDecision.elapsed = elapsed
|
||||||
if err != nil {
|
if err != nil {
|
||||||
policyDecision.kind = policyDecisionKindForError(f)
|
policyDecision.action = policyDecisionActionForError(f)
|
||||||
|
policyDecision.evaluation = evalError
|
||||||
policyDecision.message = fmt.Sprintf("expression '%v' resulted in error: %v", v.policy.Spec.Validations[i].Expression, err)
|
policyDecision.message = fmt.Sprintf("expression '%v' resulted in error: %v", v.policy.Spec.Validations[i].Expression, err)
|
||||||
} else if evalResult != celtypes.True {
|
} else if evalResult != celtypes.True {
|
||||||
policyDecision.kind = deny
|
policyDecision.action = actionDeny
|
||||||
if validation.Reason == nil {
|
if validation.Reason == nil {
|
||||||
policyDecision.reason = metav1.StatusReasonInvalid
|
policyDecision.reason = metav1.StatusReasonInvalid
|
||||||
} else {
|
} else {
|
||||||
@ -240,7 +247,8 @@ func (v *CELValidator) Validate(a admission.Attributes, o admission.ObjectInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
policyDecision.kind = admit
|
policyDecision.action = actionAdmit
|
||||||
|
policyDecision.evaluation = evalAdmit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +219,8 @@ func getValidPolicy(validations []v1alpha1.Validation, params *v1alpha1.ParamKin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generatedDecision(k policyDecisionKind, m string, r metav1.StatusReason) policyDecision {
|
func generatedDecision(k policyDecisionAction, m string, r metav1.StatusReason) policyDecision {
|
||||||
return policyDecision{kind: k, message: m, reason: r}
|
return policyDecision{action: k, message: m, reason: r}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidate(t *testing.T) {
|
func TestValidate(t *testing.T) {
|
||||||
@ -281,7 +281,7 @@ func TestValidate(t *testing.T) {
|
|||||||
}, nil, nil),
|
}, nil, nil),
|
||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -293,7 +293,7 @@ func TestValidate(t *testing.T) {
|
|||||||
}, nil, nil),
|
}, nil, nil),
|
||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -308,8 +308,8 @@ func TestValidate(t *testing.T) {
|
|||||||
}, nil, nil),
|
}, nil, nil),
|
||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -319,7 +319,7 @@ func TestValidate(t *testing.T) {
|
|||||||
}, nil, nil),
|
}, nil, nil),
|
||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -330,7 +330,7 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -348,7 +348,7 @@ func TestValidate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
|
generatedDecision(actionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -364,8 +364,8 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
generatedDecision(deny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
|
generatedDecision(actionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -381,8 +381,8 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "failed expression: oldObject != null", metav1.StatusReasonInvalid),
|
generatedDecision(actionDeny, "failed expression: oldObject != null", metav1.StatusReasonInvalid),
|
||||||
generatedDecision(deny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
|
generatedDecision(actionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -398,8 +398,8 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, true),
|
attributes: newValidAttribute(nil, true),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -413,7 +413,7 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, true),
|
attributes: newValidAttribute(nil, true),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "failed expression: oldObject == null", metav1.StatusReasonForbidden),
|
generatedDecision(actionDeny, "failed expression: oldObject == null", metav1.StatusReasonForbidden),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -428,7 +428,7 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, true),
|
attributes: newValidAttribute(nil, true),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "old object should be present", metav1.StatusReasonForbidden),
|
generatedDecision(actionDeny, "old object should be present", metav1.StatusReasonForbidden),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -441,7 +441,7 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, true),
|
attributes: newValidAttribute(nil, true),
|
||||||
params: configMapParams,
|
params: configMapParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "resulted in error", ""),
|
generatedDecision(actionDeny, "resulted in error", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -454,7 +454,7 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
params: crdParams,
|
params: crdParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -470,8 +470,8 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
params: crdParams,
|
params: crdParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "compilation error: compilation failed: ERROR: <input>:1:6: Syntax error:", ""),
|
generatedDecision(actionDeny, "compilation error: compilation failed: ERROR: <input>:1:6: Syntax error:", ""),
|
||||||
generatedDecision(deny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
|
generatedDecision(actionDeny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -487,8 +487,8 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(nil, false),
|
attributes: newValidAttribute(nil, false),
|
||||||
params: crdParams,
|
params: crdParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "compilation error: compilation failed: ERROR:", ""),
|
generatedDecision(actionAdmit, "compilation error: compilation failed: ERROR:", ""),
|
||||||
generatedDecision(deny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
|
generatedDecision(actionDeny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -501,7 +501,7 @@ func TestValidate(t *testing.T) {
|
|||||||
attributes: newValidAttribute(&podObject, false),
|
attributes: newValidAttribute(&podObject, false),
|
||||||
params: crdParams,
|
params: crdParams,
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -518,7 +518,7 @@ func TestValidate(t *testing.T) {
|
|||||||
// if paramRef is unset on a binding
|
// if paramRef is unset on a binding
|
||||||
params: runtime.Object(nilUnstructured),
|
params: runtime.Object(nilUnstructured),
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(deny, "params as required", metav1.StatusReasonForbidden),
|
generatedDecision(actionDeny, "params as required", metav1.StatusReasonForbidden),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -534,7 +534,7 @@ func TestValidate(t *testing.T) {
|
|||||||
// if paramRef is unset on a binding
|
// if paramRef is unset on a binding
|
||||||
params: runtime.Object(nilUnstructured),
|
params: runtime.Object(nilUnstructured),
|
||||||
policyDecisions: []policyDecision{
|
policyDecisions: []policyDecision{
|
||||||
generatedDecision(admit, "", ""),
|
generatedDecision(actionAdmit, "", ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -556,8 +556,8 @@ func TestValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.Equal(t, len(policyResults), len(tc.policyDecisions))
|
require.Equal(t, len(policyResults), len(tc.policyDecisions))
|
||||||
for i, policyDecision := range tc.policyDecisions {
|
for i, policyDecision := range tc.policyDecisions {
|
||||||
if policyDecision.kind != policyResults[i].kind {
|
if policyDecision.action != policyResults[i].action {
|
||||||
t.Errorf("Expected policy decision kind '%v' but got '%v'", policyDecision.kind, policyResults[i].kind)
|
t.Errorf("Expected policy decision kind '%v' but got '%v'", policyDecision.action, policyResults[i].action)
|
||||||
}
|
}
|
||||||
if !strings.Contains(policyResults[i].message, policyDecision.message) {
|
if !strings.Contains(policyResults[i].message, policyDecision.message) {
|
||||||
t.Errorf("Expected policy decision message contains '%v' but got '%v'", policyDecision.message, policyResults[i].message)
|
t.Errorf("Expected policy decision message contains '%v' but got '%v'", policyDecision.message, policyResults[i].message)
|
||||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -1432,6 +1432,7 @@ k8s.io/apimachinery/third_party/forked/golang/reflect
|
|||||||
# k8s.io/apiserver v0.0.0 => ./staging/src/k8s.io/apiserver
|
# k8s.io/apiserver v0.0.0 => ./staging/src/k8s.io/apiserver
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
k8s.io/apiserver/pkg/admission
|
k8s.io/apiserver/pkg/admission
|
||||||
|
k8s.io/apiserver/pkg/admission/cel
|
||||||
k8s.io/apiserver/pkg/admission/configuration
|
k8s.io/apiserver/pkg/admission/configuration
|
||||||
k8s.io/apiserver/pkg/admission/initializer
|
k8s.io/apiserver/pkg/admission/initializer
|
||||||
k8s.io/apiserver/pkg/admission/metrics
|
k8s.io/apiserver/pkg/admission/metrics
|
||||||
|
Loading…
Reference in New Issue
Block a user