diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go
index 7edb06f5f3b..438b408e3e8 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission_test.go
@@ -37,6 +37,7 @@ import (
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic"
+ whgeneric "k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
"k8s.io/apiserver/pkg/features"
dynamicfake "k8s.io/client-go/dynamic/fake"
"k8s.io/client-go/informers"
@@ -173,11 +174,11 @@ func (f *fakeCompiler) DefinitionMatches(a admission.Attributes, o admission.Obj
namespace: namespace,
}
if fun, ok := f.DefinitionMatchFuncs[key]; ok {
- return fun(definition, a), schema.GroupVersionKind{}, nil
+ return fun(definition, a), a.GetKind(), nil
}
// Default is match everything
- return f.DefaultMatch, schema.GroupVersionKind{}, nil
+ return f.DefaultMatch, a.GetKind(), nil
}
// Matches says whether this policy definition matches the provided admission
@@ -656,21 +657,21 @@ func TestBasicPolicyDefinitionFailure(t *testing.T) {
require.ErrorContains(t, err, `Denied`)
}
-type validatorFunc func(a admission.Attributes, o admission.ObjectInterfaces, params runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error)
+type validatorFunc func(versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error)
-func (f validatorFunc) Validate(a admission.Attributes, o admission.ObjectInterfaces, params runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) {
- return f(a, o, params, matchKind)
+func (f validatorFunc) Validate(versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error) {
+ return f(versionedAttr, versionedParams)
}
type testValidator struct {
}
-func (v testValidator) Validate(a admission.Attributes, o admission.ObjectInterfaces, params runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) {
+func (v testValidator) Validate(versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error) {
// Policy always denies
- return []policyDecision{
+ return []PolicyDecision{
{
- action: actionDeny,
- message: "Denied",
+ Action: ActionDeny,
+ Message: "Denied",
},
}, nil
}
@@ -1142,11 +1143,11 @@ func TestMultiplePoliciesSharedParamType(t *testing.T) {
compiler.RegisterDefinition(&policy1, func(vap *v1alpha1.ValidatingAdmissionPolicy) Validator {
compiles1.Add(1)
- return validatorFunc(func(a admission.Attributes, o admission.ObjectInterfaces, params runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) {
+ return validatorFunc(func(versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error) {
evaluations1.Add(1)
- return []policyDecision{
+ return []PolicyDecision{
{
- action: actionAdmit,
+ Action: ActionAdmit,
},
}, nil
})
@@ -1155,12 +1156,12 @@ func TestMultiplePoliciesSharedParamType(t *testing.T) {
compiler.RegisterDefinition(&policy2, func(vap *v1alpha1.ValidatingAdmissionPolicy) Validator {
compiles2.Add(1)
- return validatorFunc(func(a admission.Attributes, o admission.ObjectInterfaces, params runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) {
+ return validatorFunc(func(versionedAttr *whgeneric.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error) {
evaluations2.Add(1)
- return []policyDecision{
+ return []PolicyDecision{
{
- action: actionDeny,
- message: "Policy2Denied",
+ Action: ActionDeny,
+ Message: "Policy2Denied",
},
}, nil
})
@@ -1256,22 +1257,22 @@ func TestNativeTypeParam(t *testing.T) {
compiler.RegisterDefinition(&nativeTypeParamPolicy, func(vap *v1alpha1.ValidatingAdmissionPolicy) Validator {
compiles.Add(1)
- return validatorFunc(func(a admission.Attributes, o admission.ObjectInterfaces, params runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) {
+ return validatorFunc(func(versionedAttr *whgeneric.VersionedAttributes, params runtime.Object) ([]PolicyDecision, error) {
evaluations.Add(1)
// show that the passed params was a ConfigMap native type
if _, ok := params.(*v1.ConfigMap); ok {
- return []policyDecision{
+ return []PolicyDecision{
{
- action: actionDeny,
- message: "correct type",
+ Action: ActionDeny,
+ Message: "correct type",
},
}, nil
}
- return []policyDecision{
+ return []PolicyDecision{
{
- action: actionDeny,
- message: "Incorrect param type",
+ Action: ActionDeny,
+ Message: "Incorrect param type",
},
}, nil
})
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go
index 795dbad5b9c..dfb3dda21a5 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go
@@ -37,6 +37,7 @@ import (
"k8s.io/apiserver/pkg/admission"
celmetrics "k8s.io/apiserver/pkg/admission/cel"
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic"
+ whgeneric "k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
@@ -190,21 +191,21 @@ func (c *celAdmissionController) Validate(
message = fmt.Errorf("failed to configure binding: %w", err).Error()
}
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
- policyDecision: policyDecision{
- action: actionDeny,
- message: message,
+ PolicyDecision: PolicyDecision{
+ Action: ActionDeny,
+ Message: message,
},
- definition: definition,
- binding: binding,
+ Definition: definition,
+ Binding: binding,
})
default:
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
- policyDecision: policyDecision{
- action: actionDeny,
- message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(),
+ PolicyDecision: PolicyDecision{
+ Action: ActionDeny,
+ Message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(),
},
- definition: definition,
- binding: binding,
+ Definition: definition,
+ Binding: binding,
})
}
}
@@ -243,6 +244,12 @@ func (c *celAdmissionController) Validate(
var param runtime.Object
+ // versionedAttributes will be set to non-nil inside of the loop, but
+ // is scoped outside of the param loop so we only convert once. We defer
+ // conversion so that it is only performed when we know a policy matches,
+ // saving the cost of converting non-matching requests.
+ var versionedAttr *whgeneric.VersionedAttributes
+
// If definition has paramKind, paramRef is required in binding.
// If definition has no paramKind, paramRef set in binding will be ignored.
paramKind := definition.Spec.ParamKind
@@ -293,7 +300,17 @@ func (c *celAdmissionController) Validate(
}
}
- decisions, err := bindingInfo.validator.Validate(a, o, param, matchKind)
+ if versionedAttr == nil {
+ va, err := whgeneric.NewVersionedAttributes(a, matchKind, o)
+ if err != nil {
+ wrappedErr := fmt.Errorf("failed to convert object version: %w", err)
+ addConfigError(wrappedErr, definition, binding)
+ continue
+ }
+ versionedAttr = va
+ }
+
+ decisions, err := bindingInfo.validator.Validate(versionedAttr, param)
if err != nil {
// runtime error. Apply failure policy
wrappedError := fmt.Errorf("failed to evaluate CEL expression: %w", err)
@@ -302,21 +319,21 @@ func (c *celAdmissionController) Validate(
}
for _, decision := range decisions {
- switch decision.action {
- case actionAdmit:
- if decision.evaluation == evalError {
- celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.elapsed, definition.Name, binding.Name, "active")
+ switch decision.Action {
+ case ActionAdmit:
+ if decision.Evaluation == EvalError {
+ celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.Elapsed, definition.Name, binding.Name, "active")
}
- case actionDeny:
+ case ActionDeny:
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
- definition: definition,
- binding: binding,
- policyDecision: decision,
+ Definition: definition,
+ Binding: binding,
+ PolicyDecision: decision,
})
- celmetrics.Metrics.ObserveRejection(ctx, decision.elapsed, definition.Name, binding.Name, "active")
+ celmetrics.Metrics.ObserveRejection(ctx, decision.Elapsed, definition.Name, binding.Name, "active")
default:
return fmt.Errorf("unrecognized evaluation decision '%s' for ValidatingAdmissionPolicyBinding '%s' with ValidatingAdmissionPolicy '%s'",
- decision.action, binding.Name, definition.Name)
+ decision.Action, binding.Name, definition.Name)
}
}
}
@@ -326,18 +343,18 @@ func (c *celAdmissionController) Validate(
// TODO: refactor admission.NewForbidden so the name extraction is reusable but the code/reason is customizable
var message string
deniedDecision := deniedDecisions[0]
- if deniedDecision.binding != nil {
- message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' with binding '%s' denied request: %s", deniedDecision.definition.Name, deniedDecision.binding.Name, deniedDecision.message)
+ if deniedDecision.Binding != nil {
+ message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' with binding '%s' denied request: %s", deniedDecision.Definition.Name, deniedDecision.Binding.Name, deniedDecision.Message)
} else {
- message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' denied request: %s", deniedDecision.definition.Name, deniedDecision.message)
+ message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' denied request: %s", deniedDecision.Definition.Name, deniedDecision.Message)
}
err := admission.NewForbidden(a, errors.New(message)).(*k8serrors.StatusError)
- reason := deniedDecision.reason
+ reason := deniedDecision.Reason
if len(reason) == 0 {
reason = metav1.StatusReasonInvalid
}
err.ErrStatus.Reason = reason
- err.ErrStatus.Code = reasonToCode(reason)
+ err.ErrStatus.Code = ReasonToCode(reason)
err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Message: message})
return err
}
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go
index 217d6bfc47c..7cb33b3724e 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go
@@ -21,13 +21,14 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission"
+ "k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
)
-// Validator defines the func used to validate the cel expressions
-// matchKind provides the GroupVersionKind that the object should be
-// validated by CEL expressions as.
+// Validator defines the func used to validate an object against the validator's rules.
+// It expects the inbound object to already have been converted to the version expected
+// by the underlying CEL code (which is indicated by the match criteria of a policy definition).
type Validator interface {
- Validate(a admission.Attributes, o admission.ObjectInterfaces, versionedParams runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error)
+ Validate(versionedAttr *generic.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error)
}
// ValidatorCompiler is Dependency Injected into the PolicyDefinition's `Compile`
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go
index 1018743705b..b13a2ab74a1 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go
@@ -24,36 +24,36 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-type policyDecisionAction string
+type PolicyDecisionAction string
const (
- actionAdmit policyDecisionAction = "admit"
- actionDeny policyDecisionAction = "deny"
+ ActionAdmit PolicyDecisionAction = "admit"
+ ActionDeny PolicyDecisionAction = "deny"
)
-type policyDecisionEvaluation string
+type PolicyDecisionEvaluation string
const (
- evalAdmit policyDecisionEvaluation = "admit"
- evalError policyDecisionEvaluation = "error"
- evalDeny policyDecisionEvaluation = "deny"
+ EvalAdmit PolicyDecisionEvaluation = "admit"
+ EvalError PolicyDecisionEvaluation = "error"
+ EvalDeny PolicyDecisionEvaluation = "deny"
)
-type policyDecision struct {
- action policyDecisionAction
- evaluation policyDecisionEvaluation
- message string
- reason metav1.StatusReason
- elapsed time.Duration
+type PolicyDecision struct {
+ Action PolicyDecisionAction
+ Evaluation PolicyDecisionEvaluation
+ Message string
+ Reason metav1.StatusReason
+ Elapsed time.Duration
}
type policyDecisionWithMetadata struct {
- policyDecision
- definition *v1alpha1.ValidatingAdmissionPolicy
- binding *v1alpha1.ValidatingAdmissionPolicyBinding
+ PolicyDecision
+ Definition *v1alpha1.ValidatingAdmissionPolicy
+ Binding *v1alpha1.ValidatingAdmissionPolicyBinding
}
-func reasonToCode(r metav1.StatusReason) int32 {
+func ReasonToCode(r metav1.StatusReason) int32 {
switch r {
case metav1.StatusReasonForbidden:
return http.StatusForbidden
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go
index 033d2e48e15..f4e84408d2b 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go
@@ -157,26 +157,22 @@ func objectToResolveVal(r runtime.Object) (interface{}, error) {
return v.Object, nil
}
-func policyDecisionActionForError(f v1alpha1.FailurePolicyType) policyDecisionAction {
+func policyDecisionActionForError(f v1alpha1.FailurePolicyType) PolicyDecisionAction {
if f == v1alpha1.Ignore {
- return actionAdmit
+ return ActionAdmit
}
- return actionDeny
+ return ActionDeny
}
// Validate validates all cel expressions in Validator and returns a PolicyDecision for each CEL expression or returns an error.
// An error will be returned if failed to convert the object/oldObject/params/request to unstructured.
// Each PolicyDecision will have a decision and a message.
// policyDecision.message will be empty if the decision is allowed and no error met.
-func (v *CELValidator) Validate(a admission.Attributes, o admission.ObjectInterfaces, versionedParams runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) {
+func (v *CELValidator) Validate(versionedAttr *generic.VersionedAttributes, versionedParams runtime.Object) ([]PolicyDecision, error) {
// TODO: replace unstructured with ref.Val for CEL variables when native type support is available
-
- decisions := make([]policyDecision, len(v.compilationResults))
+ decisions := make([]PolicyDecision, len(v.compilationResults))
var err error
- versionedAttr, err := generic.NewVersionedAttributes(a, matchKind, o)
- if err != nil {
- return nil, err
- }
+
oldObjectVal, err := objectToResolveVal(versionedAttr.VersionedOldObject)
if err != nil {
return nil, err
@@ -189,6 +185,7 @@ func (v *CELValidator) Validate(a admission.Attributes, o admission.ObjectInterf
if err != nil {
return nil, err
}
+
request := createAdmissionRequest(versionedAttr.Attributes)
requestVal, err := convertObjectToUnstructured(request)
if err != nil {
@@ -214,41 +211,41 @@ func (v *CELValidator) Validate(a admission.Attributes, o admission.ObjectInterf
var policyDecision = &decisions[i]
if compilationResult.Error != nil {
- policyDecision.action = policyDecisionActionForError(f)
- policyDecision.evaluation = evalError
- policyDecision.message = fmt.Sprintf("compilation error: %v", compilationResult.Error)
+ policyDecision.Action = policyDecisionActionForError(f)
+ policyDecision.Evaluation = EvalError
+ policyDecision.Message = fmt.Sprintf("compilation error: %v", compilationResult.Error)
continue
}
if compilationResult.Program == nil {
- policyDecision.action = policyDecisionActionForError(f)
- policyDecision.evaluation = evalError
- policyDecision.message = "unexpected internal error compiling expression"
+ policyDecision.Action = policyDecisionActionForError(f)
+ policyDecision.Evaluation = EvalError
+ policyDecision.Message = "unexpected internal error compiling expression"
continue
}
t1 := time.Now()
evalResult, _, err := compilationResult.Program.Eval(va)
elapsed := time.Since(t1)
- policyDecision.elapsed = elapsed
+ policyDecision.Elapsed = elapsed
if err != nil {
- 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.Action = policyDecisionActionForError(f)
+ policyDecision.Evaluation = EvalError
+ policyDecision.Message = fmt.Sprintf("expression '%v' resulted in error: %v", v.policy.Spec.Validations[i].Expression, err)
} else if evalResult != celtypes.True {
- policyDecision.action = actionDeny
+ policyDecision.Action = ActionDeny
if validation.Reason == nil {
- policyDecision.reason = metav1.StatusReasonInvalid
+ policyDecision.Reason = metav1.StatusReasonInvalid
} else {
- policyDecision.reason = *validation.Reason
+ policyDecision.Reason = *validation.Reason
}
if len(validation.Message) > 0 {
- policyDecision.message = strings.TrimSpace(validation.Message)
+ policyDecision.Message = strings.TrimSpace(validation.Message)
} else {
- policyDecision.message = fmt.Sprintf("failed expression: %v", strings.TrimSpace(validation.Expression))
+ policyDecision.Message = fmt.Sprintf("failed expression: %v", strings.TrimSpace(validation.Expression))
}
} else {
- policyDecision.action = actionAdmit
- policyDecision.evaluation = evalAdmit
+ policyDecision.Action = ActionAdmit
+ policyDecision.Evaluation = EvalAdmit
}
}
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go
index fff818bee94..f71f3c46077 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator_test.go
@@ -31,6 +31,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission"
+ "k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
)
func TestCompile(t *testing.T) {
@@ -219,8 +220,8 @@ func getValidPolicy(validations []v1alpha1.Validation, params *v1alpha1.ParamKin
}
}
-func generatedDecision(k policyDecisionAction, m string, r metav1.StatusReason) policyDecision {
- return policyDecision{action: k, message: m, reason: r}
+func generatedDecision(k PolicyDecisionAction, m string, r metav1.StatusReason) PolicyDecision {
+ return PolicyDecision{Action: k, Message: m, Reason: r}
}
func TestValidate(t *testing.T) {
@@ -270,7 +271,7 @@ func TestValidate(t *testing.T) {
policy *v1alpha1.ValidatingAdmissionPolicy
attributes admission.Attributes
params runtime.Object
- policyDecisions []policyDecision
+ policyDecisions []PolicyDecision
}{
{
name: "valid syntax for object",
@@ -280,8 +281,8 @@ func TestValidate(t *testing.T) {
},
}, nil, nil),
attributes: newValidAttribute(nil, false),
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -292,8 +293,8 @@ func TestValidate(t *testing.T) {
},
}, nil, nil),
attributes: newValidAttribute(nil, false),
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -307,9 +308,9 @@ func TestValidate(t *testing.T) {
},
}, nil, nil),
attributes: newValidAttribute(nil, false),
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -318,8 +319,8 @@ func TestValidate(t *testing.T) {
{Expression: "request.operation == 'CREATE'"},
}, nil, nil),
attributes: newValidAttribute(nil, false),
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -329,8 +330,8 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, false),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -347,8 +348,8 @@ func TestValidate(t *testing.T) {
"fakeString": "fake",
},
},
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
},
},
{
@@ -363,9 +364,9 @@ func TestValidate(t *testing.T) {
}, hasParamKind, ignorePolicy),
attributes: newValidAttribute(nil, false),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
- generatedDecision(actionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
+ generatedDecision(ActionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
},
},
{
@@ -380,9 +381,9 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, false),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "failed expression: oldObject != null", metav1.StatusReasonInvalid),
- generatedDecision(actionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "failed expression: oldObject != null", metav1.StatusReasonInvalid),
+ generatedDecision(ActionDeny, "failed expression: object.subsets.size() > 2", metav1.StatusReasonInvalid),
},
},
{
@@ -397,9 +398,9 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, true),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -412,8 +413,8 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, true),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "failed expression: oldObject == null", metav1.StatusReasonForbidden),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "failed expression: oldObject == null", metav1.StatusReasonForbidden),
},
},
{
@@ -427,8 +428,8 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, true),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "old object should be present", metav1.StatusReasonForbidden),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "old object should be present", metav1.StatusReasonForbidden),
},
},
{
@@ -440,8 +441,8 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, true),
params: configMapParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "resulted in error", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "resulted in error", ""),
},
},
{
@@ -453,8 +454,8 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, false),
params: crdParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -469,9 +470,9 @@ func TestValidate(t *testing.T) {
}, hasParamKind, nil),
attributes: newValidAttribute(nil, false),
params: crdParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "compilation error: compilation failed: ERROR: :1:6: Syntax error:", ""),
- generatedDecision(actionDeny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "compilation error: compilation failed: ERROR: :1:6: Syntax error:", ""),
+ generatedDecision(ActionDeny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
},
},
{
@@ -486,9 +487,9 @@ func TestValidate(t *testing.T) {
}, hasParamKind, ignorePolicy),
attributes: newValidAttribute(nil, false),
params: crdParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "compilation error: compilation failed: ERROR:", ""),
- generatedDecision(actionDeny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "compilation error: compilation failed: ERROR:", ""),
+ generatedDecision(ActionDeny, "failed expression: object.subsets.size() > params.spec.testSize", metav1.StatusReasonInvalid),
},
},
{
@@ -500,8 +501,8 @@ func TestValidate(t *testing.T) {
}, nil, nil),
attributes: newValidAttribute(&podObject, false),
params: crdParams,
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
{
@@ -517,8 +518,8 @@ func TestValidate(t *testing.T) {
// Simulate a interface holding a nil pointer, since this is how param is passed to Validate
// if paramRef is unset on a binding
params: runtime.Object(nilUnstructured),
- policyDecisions: []policyDecision{
- generatedDecision(actionDeny, "params as required", metav1.StatusReasonForbidden),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionDeny, "params as required", metav1.StatusReasonForbidden),
},
},
{
@@ -533,8 +534,8 @@ func TestValidate(t *testing.T) {
// Simulate a interface holding a nil pointer, since this is how param is passed to Validate
// if paramRef is unset on a binding
params: runtime.Object(nilUnstructured),
- policyDecisions: []policyDecision{
- generatedDecision(actionAdmit, "", ""),
+ policyDecisions: []PolicyDecision{
+ generatedDecision(ActionAdmit, "", ""),
},
},
}
@@ -550,20 +551,25 @@ func TestValidate(t *testing.T) {
CompilationResults := validator.(*CELValidator).compilationResults
require.Equal(t, len(validations), len(CompilationResults))
- policyResults, err := validator.Validate(tc.attributes, newObjectInterfacesForTest(), tc.params, tc.attributes.GetKind())
+ versionedAttr, err := generic.NewVersionedAttributes(tc.attributes, tc.attributes.GetKind(), newObjectInterfacesForTest())
+ if err != nil {
+ t.Fatalf("unexpected error on conversion: %v", err)
+ }
+
+ policyResults, err := validator.Validate(versionedAttr, tc.params)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
require.Equal(t, len(policyResults), len(tc.policyDecisions))
for i, policyDecision := range tc.policyDecisions {
- if policyDecision.action != policyResults[i].action {
- t.Errorf("Expected policy decision kind '%v' but got '%v'", policyDecision.action, policyResults[i].action)
+ if policyDecision.Action != policyResults[i].Action {
+ t.Errorf("Expected policy decision kind '%v' but got '%v'", policyDecision.Action, policyResults[i].Action)
}
- if !strings.Contains(policyResults[i].message, policyDecision.message) {
- t.Errorf("Expected policy decision message contains '%v' but got '%v'", policyDecision.message, policyResults[i].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)
}
- if policyDecision.reason != policyResults[i].reason {
- t.Errorf("Expected policy decision reason '%v' but got '%v'", policyDecision.reason, policyResults[i].reason)
+ if policyDecision.Reason != policyResults[i].Reason {
+ t.Errorf("Expected policy decision reason '%v' but got '%v'", policyDecision.Reason, policyResults[i].Reason)
}
}
})