Custom match criteria (#116350)
* Add custom match conditions for CEL admission This PR is based off of, and dependent on the following PR: https://github.com/kubernetes/kubernetes/pull/116261 Signed-off-by: Max Smythe <smythe@google.com> * run `make update` Signed-off-by: Max Smythe <smythe@google.com> * Fix unit tests Signed-off-by: Max Smythe <smythe@google.com> * Fix unit tests Signed-off-by: Max Smythe <smythe@google.com> * Update compatibility test data Signed-off-by: Max Smythe <smythe@google.com> * Revert "Update compatibility test data" This reverts commit 312ba7f9e74e0ec4a7ac1f07bf575479c608af28. * Allow params during validation; make match conditions optional Signed-off-by: Max Smythe <smythe@google.com> * Add conditional ignoring of matcher CEL expression validation on update Signed-off-by: Max Smythe <smythe@google.com> * Run codegen Signed-off-by: Max Smythe <smythe@google.com> * Add more validation tests Signed-off-by: Max Smythe <smythe@google.com> * Short-circuit CEL matcher when no matchers specified Signed-off-by: Max Smythe <smythe@google.com> * Run codegen Signed-off-by: Max Smythe <smythe@google.com> * Address review comments Signed-off-by: Max Smythe <smythe@google.com> --------- Signed-off-by: Max Smythe <smythe@google.com>
This commit is contained in:
parent
6711a81f02
commit
e5fd204c33
30
api/openapi-spec/swagger.json
generated
30
api/openapi-spec/swagger.json
generated
@ -428,6 +428,23 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"io.k8s.api.admissionregistration.v1alpha1.MatchCondition": {
|
||||||
|
"properties": {
|
||||||
|
"expression": {
|
||||||
|
"description": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"expression"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"io.k8s.api.admissionregistration.v1alpha1.MatchResources": {
|
"io.k8s.api.admissionregistration.v1alpha1.MatchResources": {
|
||||||
"description": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
|
"description": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -725,6 +742,19 @@
|
|||||||
"description": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
|
"description": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"matchConditions": {
|
||||||
|
"description": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/io.k8s.api.admissionregistration.v1alpha1.MatchCondition"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"x-kubernetes-list-map-keys": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"x-kubernetes-list-type": "map",
|
||||||
|
"x-kubernetes-patch-merge-key": "name",
|
||||||
|
"x-kubernetes-patch-strategy": "merge"
|
||||||
|
},
|
||||||
"matchConstraints": {
|
"matchConstraints": {
|
||||||
"$ref": "#/definitions/io.k8s.api.admissionregistration.v1alpha1.MatchResources",
|
"$ref": "#/definitions/io.k8s.api.admissionregistration.v1alpha1.MatchResources",
|
||||||
"description": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required."
|
"description": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required."
|
||||||
|
@ -41,6 +41,25 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"io.k8s.api.admissionregistration.v1alpha1.MatchCondition": {
|
||||||
|
"properties": {
|
||||||
|
"expression": {
|
||||||
|
"default": "",
|
||||||
|
"description": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"default": "",
|
||||||
|
"description": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"expression"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"io.k8s.api.admissionregistration.v1alpha1.MatchResources": {
|
"io.k8s.api.admissionregistration.v1alpha1.MatchResources": {
|
||||||
"description": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
|
"description": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -425,6 +444,24 @@
|
|||||||
"description": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
|
"description": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"matchConditions": {
|
||||||
|
"description": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
|
||||||
|
"items": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/io.k8s.api.admissionregistration.v1alpha1.MatchCondition"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"x-kubernetes-list-map-keys": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"x-kubernetes-list-type": "map",
|
||||||
|
"x-kubernetes-patch-merge-key": "name",
|
||||||
|
"x-kubernetes-patch-strategy": "merge"
|
||||||
|
},
|
||||||
"matchConstraints": {
|
"matchConstraints": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
|
@ -206,6 +206,24 @@ type ValidatingAdmissionPolicySpec struct {
|
|||||||
// +optional
|
// +optional
|
||||||
Validations []Validation
|
Validations []Validation
|
||||||
|
|
||||||
|
// MatchConditions is a list of conditions that must be met for a request to be validated.
|
||||||
|
// Match conditions filter requests that have already been matched by the rules,
|
||||||
|
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
|
||||||
|
// There are a maximum of 64 match conditions allowed.
|
||||||
|
//
|
||||||
|
// If a parameter object is provided, it can be accessed via the `params` handle in the same
|
||||||
|
// manner as validation expressions.
|
||||||
|
//
|
||||||
|
// The exact matching logic is (in order):
|
||||||
|
// 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
|
||||||
|
// 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
|
||||||
|
// 3. If any matchCondition evaluates to an error (but none are FALSE):
|
||||||
|
// - If failurePolicy=Fail, reject the request
|
||||||
|
// - If failurePolicy=Ignore, the policy is skipped
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
MatchConditions []MatchCondition
|
||||||
|
|
||||||
// failurePolicy defines how to handle failures for the admission policy. Failures can
|
// failurePolicy defines how to handle failures for the admission policy. Failures can
|
||||||
// occur from CEL expression parse errors, type check errors, runtime errors and invalid
|
// occur from CEL expression parse errors, type check errors, runtime errors and invalid
|
||||||
// or mis-configured policy definitions or bindings.
|
// or mis-configured policy definitions or bindings.
|
||||||
|
@ -59,6 +59,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*v1alpha1.MatchCondition)(nil), (*admissionregistration.MatchCondition)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v1alpha1_MatchCondition_To_admissionregistration_MatchCondition(a.(*v1alpha1.MatchCondition), b.(*admissionregistration.MatchCondition), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*admissionregistration.MatchCondition)(nil), (*v1alpha1.MatchCondition)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_admissionregistration_MatchCondition_To_v1alpha1_MatchCondition(a.(*admissionregistration.MatchCondition), b.(*v1alpha1.MatchCondition), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddGeneratedConversionFunc((*v1alpha1.MatchResources)(nil), (*admissionregistration.MatchResources)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddGeneratedConversionFunc((*v1alpha1.MatchResources)(nil), (*admissionregistration.MatchResources)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_v1alpha1_MatchResources_To_admissionregistration_MatchResources(a.(*v1alpha1.MatchResources), b.(*admissionregistration.MatchResources), scope)
|
return Convert_v1alpha1_MatchResources_To_admissionregistration_MatchResources(a.(*v1alpha1.MatchResources), b.(*admissionregistration.MatchResources), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -236,6 +246,28 @@ func Convert_admissionregistration_ExpressionWarning_To_v1alpha1_ExpressionWarni
|
|||||||
return autoConvert_admissionregistration_ExpressionWarning_To_v1alpha1_ExpressionWarning(in, out, s)
|
return autoConvert_admissionregistration_ExpressionWarning_To_v1alpha1_ExpressionWarning(in, out, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func autoConvert_v1alpha1_MatchCondition_To_admissionregistration_MatchCondition(in *v1alpha1.MatchCondition, out *admissionregistration.MatchCondition, s conversion.Scope) error {
|
||||||
|
out.Name = in.Name
|
||||||
|
out.Expression = in.Expression
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_v1alpha1_MatchCondition_To_admissionregistration_MatchCondition is an autogenerated conversion function.
|
||||||
|
func Convert_v1alpha1_MatchCondition_To_admissionregistration_MatchCondition(in *v1alpha1.MatchCondition, out *admissionregistration.MatchCondition, s conversion.Scope) error {
|
||||||
|
return autoConvert_v1alpha1_MatchCondition_To_admissionregistration_MatchCondition(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_admissionregistration_MatchCondition_To_v1alpha1_MatchCondition(in *admissionregistration.MatchCondition, out *v1alpha1.MatchCondition, s conversion.Scope) error {
|
||||||
|
out.Name = in.Name
|
||||||
|
out.Expression = in.Expression
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_admissionregistration_MatchCondition_To_v1alpha1_MatchCondition is an autogenerated conversion function.
|
||||||
|
func Convert_admissionregistration_MatchCondition_To_v1alpha1_MatchCondition(in *admissionregistration.MatchCondition, out *v1alpha1.MatchCondition, s conversion.Scope) error {
|
||||||
|
return autoConvert_admissionregistration_MatchCondition_To_v1alpha1_MatchCondition(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
func autoConvert_v1alpha1_MatchResources_To_admissionregistration_MatchResources(in *v1alpha1.MatchResources, out *admissionregistration.MatchResources, s conversion.Scope) error {
|
func autoConvert_v1alpha1_MatchResources_To_admissionregistration_MatchResources(in *v1alpha1.MatchResources, out *admissionregistration.MatchResources, s conversion.Scope) error {
|
||||||
out.NamespaceSelector = (*v1.LabelSelector)(unsafe.Pointer(in.NamespaceSelector))
|
out.NamespaceSelector = (*v1.LabelSelector)(unsafe.Pointer(in.NamespaceSelector))
|
||||||
out.ObjectSelector = (*v1.LabelSelector)(unsafe.Pointer(in.ObjectSelector))
|
out.ObjectSelector = (*v1.LabelSelector)(unsafe.Pointer(in.ObjectSelector))
|
||||||
@ -592,6 +624,7 @@ func autoConvert_v1alpha1_ValidatingAdmissionPolicySpec_To_admissionregistration
|
|||||||
out.Validations = *(*[]admissionregistration.Validation)(unsafe.Pointer(&in.Validations))
|
out.Validations = *(*[]admissionregistration.Validation)(unsafe.Pointer(&in.Validations))
|
||||||
out.FailurePolicy = (*admissionregistration.FailurePolicyType)(unsafe.Pointer(in.FailurePolicy))
|
out.FailurePolicy = (*admissionregistration.FailurePolicyType)(unsafe.Pointer(in.FailurePolicy))
|
||||||
out.AuditAnnotations = *(*[]admissionregistration.AuditAnnotation)(unsafe.Pointer(&in.AuditAnnotations))
|
out.AuditAnnotations = *(*[]admissionregistration.AuditAnnotation)(unsafe.Pointer(&in.AuditAnnotations))
|
||||||
|
out.MatchConditions = *(*[]admissionregistration.MatchCondition)(unsafe.Pointer(&in.MatchConditions))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,6 +645,7 @@ func autoConvert_admissionregistration_ValidatingAdmissionPolicySpec_To_v1alpha1
|
|||||||
out.MatchConstraints = nil
|
out.MatchConstraints = nil
|
||||||
}
|
}
|
||||||
out.Validations = *(*[]v1alpha1.Validation)(unsafe.Pointer(&in.Validations))
|
out.Validations = *(*[]v1alpha1.Validation)(unsafe.Pointer(&in.Validations))
|
||||||
|
out.MatchConditions = *(*[]v1alpha1.MatchCondition)(unsafe.Pointer(&in.MatchConditions))
|
||||||
out.FailurePolicy = (*v1alpha1.FailurePolicyType)(unsafe.Pointer(in.FailurePolicy))
|
out.FailurePolicy = (*v1alpha1.FailurePolicyType)(unsafe.Pointer(in.FailurePolicy))
|
||||||
out.AuditAnnotations = *(*[]v1alpha1.AuditAnnotation)(unsafe.Pointer(&in.AuditAnnotations))
|
out.AuditAnnotations = *(*[]v1alpha1.AuditAnnotation)(unsafe.Pointer(&in.AuditAnnotations))
|
||||||
return nil
|
return nil
|
||||||
|
@ -213,6 +213,7 @@ func validateAdmissionReviewVersions(versions []string, requireRecognizedAdmissi
|
|||||||
func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||||
return validateValidatingWebhookConfiguration(e, validationOptions{
|
return validateValidatingWebhookConfiguration(e, validationOptions{
|
||||||
ignoreMatchConditions: false,
|
ignoreMatchConditions: false,
|
||||||
|
allowParamsInMatchConditions: false,
|
||||||
requireNoSideEffects: true,
|
requireNoSideEffects: true,
|
||||||
requireRecognizedAdmissionReviewVersion: true,
|
requireRecognizedAdmissionReviewVersion: true,
|
||||||
requireUniqueWebhookNames: true,
|
requireUniqueWebhookNames: true,
|
||||||
@ -241,6 +242,7 @@ func validateValidatingWebhookConfiguration(e *admissionregistration.ValidatingW
|
|||||||
func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
||||||
return validateMutatingWebhookConfiguration(e, validationOptions{
|
return validateMutatingWebhookConfiguration(e, validationOptions{
|
||||||
ignoreMatchConditions: false,
|
ignoreMatchConditions: false,
|
||||||
|
allowParamsInMatchConditions: false,
|
||||||
requireNoSideEffects: true,
|
requireNoSideEffects: true,
|
||||||
requireRecognizedAdmissionReviewVersion: true,
|
requireRecognizedAdmissionReviewVersion: true,
|
||||||
requireUniqueWebhookNames: true,
|
requireUniqueWebhookNames: true,
|
||||||
@ -250,6 +252,7 @@ func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebho
|
|||||||
|
|
||||||
type validationOptions struct {
|
type validationOptions struct {
|
||||||
ignoreMatchConditions bool
|
ignoreMatchConditions bool
|
||||||
|
allowParamsInMatchConditions bool
|
||||||
requireNoSideEffects bool
|
requireNoSideEffects bool
|
||||||
requireRecognizedAdmissionReviewVersion bool
|
requireRecognizedAdmissionReviewVersion bool
|
||||||
requireUniqueWebhookNames bool
|
requireUniqueWebhookNames bool
|
||||||
@ -324,7 +327,7 @@ func validateValidatingWebhook(hook *admissionregistration.ValidatingWebhook, op
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !opts.ignoreMatchConditions {
|
if !opts.ignoreMatchConditions {
|
||||||
allErrors = append(allErrors, validateMatchConditions(hook.MatchConditions, fldPath.Child("matchConditions"))...)
|
allErrors = append(allErrors, validateMatchConditions(hook.MatchConditions, opts, fldPath.Child("matchConditions"))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return allErrors
|
return allErrors
|
||||||
@ -382,7 +385,7 @@ func validateMutatingWebhook(hook *admissionregistration.MutatingWebhook, opts v
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !opts.ignoreMatchConditions {
|
if !opts.ignoreMatchConditions {
|
||||||
allErrors = append(allErrors, validateMatchConditions(hook.MatchConditions, fldPath.Child("matchConditions"))...)
|
allErrors = append(allErrors, validateMatchConditions(hook.MatchConditions, opts, fldPath.Child("matchConditions"))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return allErrors
|
return allErrors
|
||||||
@ -520,6 +523,17 @@ func ignoreValidatingWebhookMatchConditions(new, old []admissionregistration.Val
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignoreValidatingAdmissionPolicyMatchConditions returns true if there have been no updates that could invalidate previously-valid match conditions
|
||||||
|
func ignoreValidatingAdmissionPolicyMatchConditions(new, old *admissionregistration.ValidatingAdmissionPolicy) bool {
|
||||||
|
if !reflect.DeepEqual(new.Spec.ParamKind, old.Spec.ParamKind) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(new.Spec.MatchConditions, old.Spec.MatchConditions) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// mutatingHasUniqueWebhookNames returns true if all webhooks have unique names
|
// mutatingHasUniqueWebhookNames returns true if all webhooks have unique names
|
||||||
func mutatingHasUniqueWebhookNames(webhooks []admissionregistration.MutatingWebhook) bool {
|
func mutatingHasUniqueWebhookNames(webhooks []admissionregistration.MutatingWebhook) bool {
|
||||||
names := sets.NewString()
|
names := sets.NewString()
|
||||||
@ -610,6 +624,7 @@ func mutatingWebhookHasInvalidLabelValueInSelector(webhooks []admissionregistrat
|
|||||||
func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||||
return validateValidatingWebhookConfiguration(newC, validationOptions{
|
return validateValidatingWebhookConfiguration(newC, validationOptions{
|
||||||
ignoreMatchConditions: ignoreValidatingWebhookMatchConditions(newC.Webhooks, oldC.Webhooks),
|
ignoreMatchConditions: ignoreValidatingWebhookMatchConditions(newC.Webhooks, oldC.Webhooks),
|
||||||
|
allowParamsInMatchConditions: false,
|
||||||
requireNoSideEffects: validatingHasNoSideEffects(oldC.Webhooks),
|
requireNoSideEffects: validatingHasNoSideEffects(oldC.Webhooks),
|
||||||
requireRecognizedAdmissionReviewVersion: validatingHasAcceptedAdmissionReviewVersions(oldC.Webhooks),
|
requireRecognizedAdmissionReviewVersion: validatingHasAcceptedAdmissionReviewVersions(oldC.Webhooks),
|
||||||
requireUniqueWebhookNames: validatingHasUniqueWebhookNames(oldC.Webhooks),
|
requireUniqueWebhookNames: validatingHasUniqueWebhookNames(oldC.Webhooks),
|
||||||
@ -621,6 +636,7 @@ func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistrat
|
|||||||
func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
||||||
return validateMutatingWebhookConfiguration(newC, validationOptions{
|
return validateMutatingWebhookConfiguration(newC, validationOptions{
|
||||||
ignoreMatchConditions: ignoreMutatingWebhookMatchConditions(newC.Webhooks, oldC.Webhooks),
|
ignoreMatchConditions: ignoreMutatingWebhookMatchConditions(newC.Webhooks, oldC.Webhooks),
|
||||||
|
allowParamsInMatchConditions: false,
|
||||||
requireNoSideEffects: mutatingHasNoSideEffects(oldC.Webhooks),
|
requireNoSideEffects: mutatingHasNoSideEffects(oldC.Webhooks),
|
||||||
requireRecognizedAdmissionReviewVersion: mutatingHasAcceptedAdmissionReviewVersions(oldC.Webhooks),
|
requireRecognizedAdmissionReviewVersion: mutatingHasAcceptedAdmissionReviewVersions(oldC.Webhooks),
|
||||||
requireUniqueWebhookNames: mutatingHasUniqueWebhookNames(oldC.Webhooks),
|
requireUniqueWebhookNames: mutatingHasUniqueWebhookNames(oldC.Webhooks),
|
||||||
@ -638,16 +654,16 @@ const (
|
|||||||
|
|
||||||
// ValidateValidatingAdmissionPolicy validates a ValidatingAdmissionPolicy before creation.
|
// ValidateValidatingAdmissionPolicy validates a ValidatingAdmissionPolicy before creation.
|
||||||
func ValidateValidatingAdmissionPolicy(p *admissionregistration.ValidatingAdmissionPolicy) field.ErrorList {
|
func ValidateValidatingAdmissionPolicy(p *admissionregistration.ValidatingAdmissionPolicy) field.ErrorList {
|
||||||
return validateValidatingAdmissionPolicy(p)
|
return validateValidatingAdmissionPolicy(p, validationOptions{ignoreMatchConditions: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateValidatingAdmissionPolicy(p *admissionregistration.ValidatingAdmissionPolicy) field.ErrorList {
|
func validateValidatingAdmissionPolicy(p *admissionregistration.ValidatingAdmissionPolicy, opts validationOptions) field.ErrorList {
|
||||||
allErrors := genericvalidation.ValidateObjectMeta(&p.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
allErrors := genericvalidation.ValidateObjectMeta(&p.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||||
allErrors = append(allErrors, validateValidatingAdmissionPolicySpec(p.ObjectMeta, &p.Spec, field.NewPath("spec"))...)
|
allErrors = append(allErrors, validateValidatingAdmissionPolicySpec(p.ObjectMeta, &p.Spec, opts, field.NewPath("spec"))...)
|
||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateValidatingAdmissionPolicySpec(meta metav1.ObjectMeta, spec *admissionregistration.ValidatingAdmissionPolicySpec, fldPath *field.Path) field.ErrorList {
|
func validateValidatingAdmissionPolicySpec(meta metav1.ObjectMeta, spec *admissionregistration.ValidatingAdmissionPolicySpec, opts validationOptions, fldPath *field.Path) field.ErrorList {
|
||||||
var allErrors field.ErrorList
|
var allErrors field.ErrorList
|
||||||
if spec.FailurePolicy == nil {
|
if spec.FailurePolicy == nil {
|
||||||
allErrors = append(allErrors, field.Required(fldPath.Child("failurePolicy"), ""))
|
allErrors = append(allErrors, field.Required(fldPath.Child("failurePolicy"), ""))
|
||||||
@ -655,6 +671,7 @@ func validateValidatingAdmissionPolicySpec(meta metav1.ObjectMeta, spec *admissi
|
|||||||
allErrors = append(allErrors, field.NotSupported(fldPath.Child("failurePolicy"), *spec.FailurePolicy, supportedFailurePolicies.List()))
|
allErrors = append(allErrors, field.NotSupported(fldPath.Child("failurePolicy"), *spec.FailurePolicy, supportedFailurePolicies.List()))
|
||||||
}
|
}
|
||||||
if spec.ParamKind != nil {
|
if spec.ParamKind != nil {
|
||||||
|
opts.allowParamsInMatchConditions = true
|
||||||
allErrors = append(allErrors, validateParamKind(*spec.ParamKind, fldPath.Child("paramKind"))...)
|
allErrors = append(allErrors, validateParamKind(*spec.ParamKind, fldPath.Child("paramKind"))...)
|
||||||
}
|
}
|
||||||
if spec.MatchConstraints == nil {
|
if spec.MatchConstraints == nil {
|
||||||
@ -666,6 +683,9 @@ func validateValidatingAdmissionPolicySpec(meta metav1.ObjectMeta, spec *admissi
|
|||||||
allErrors = append(allErrors, field.Required(fldPath.Child("matchConstraints", "resourceRules"), ""))
|
allErrors = append(allErrors, field.Required(fldPath.Child("matchConstraints", "resourceRules"), ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !opts.ignoreMatchConditions {
|
||||||
|
allErrors = append(allErrors, validateMatchConditions(spec.MatchConditions, opts, fldPath.Child("matchConditions"))...)
|
||||||
|
}
|
||||||
if len(spec.Validations) == 0 && len(spec.AuditAnnotations) == 0 {
|
if len(spec.Validations) == 0 && len(spec.AuditAnnotations) == 0 {
|
||||||
allErrors = append(allErrors, field.Required(fldPath.Child("validations"), "validations or auditAnnotations must contain at least one item"))
|
allErrors = append(allErrors, field.Required(fldPath.Child("validations"), "validations or auditAnnotations must contain at least one item"))
|
||||||
allErrors = append(allErrors, field.Required(fldPath.Child("auditAnnotations"), "validations or auditAnnotations must contain at least one item"))
|
allErrors = append(allErrors, field.Required(fldPath.Child("auditAnnotations"), "validations or auditAnnotations must contain at least one item"))
|
||||||
@ -822,14 +842,14 @@ func validateNamedRuleWithOperations(n *admissionregistration.NamedRuleWithOpera
|
|||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateMatchConditions(m []admissionregistration.MatchCondition, fldPath *field.Path) field.ErrorList {
|
func validateMatchConditions(m []admissionregistration.MatchCondition, opts validationOptions, fldPath *field.Path) field.ErrorList {
|
||||||
var allErrors field.ErrorList
|
var allErrors field.ErrorList
|
||||||
conditionNames := sets.NewString()
|
conditionNames := sets.NewString()
|
||||||
if len(m) > 64 {
|
if len(m) > 64 {
|
||||||
allErrors = append(allErrors, field.TooMany(fldPath, len(m), 64))
|
allErrors = append(allErrors, field.TooMany(fldPath, len(m), 64))
|
||||||
}
|
}
|
||||||
for i, matchCondition := range m {
|
for i, matchCondition := range m {
|
||||||
allErrors = append(allErrors, validateMatchCondition(&matchCondition, fldPath.Index(i))...)
|
allErrors = append(allErrors, validateMatchCondition(&matchCondition, opts, fldPath.Index(i))...)
|
||||||
if len(matchCondition.Name) > 0 {
|
if len(matchCondition.Name) > 0 {
|
||||||
if conditionNames.Has(matchCondition.Name) {
|
if conditionNames.Has(matchCondition.Name) {
|
||||||
allErrors = append(allErrors, field.Duplicate(fldPath.Index(i).Child("name"), matchCondition.Name))
|
allErrors = append(allErrors, field.Duplicate(fldPath.Index(i).Child("name"), matchCondition.Name))
|
||||||
@ -841,14 +861,14 @@ func validateMatchConditions(m []admissionregistration.MatchCondition, fldPath *
|
|||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateMatchCondition(v *admissionregistration.MatchCondition, fldPath *field.Path) field.ErrorList {
|
func validateMatchCondition(v *admissionregistration.MatchCondition, opts validationOptions, fldPath *field.Path) field.ErrorList {
|
||||||
var allErrors field.ErrorList
|
var allErrors field.ErrorList
|
||||||
trimmedExpression := strings.TrimSpace(v.Expression)
|
trimmedExpression := strings.TrimSpace(v.Expression)
|
||||||
if len(trimmedExpression) == 0 {
|
if len(trimmedExpression) == 0 {
|
||||||
allErrors = append(allErrors, field.Required(fldPath.Child("expression"), ""))
|
allErrors = append(allErrors, field.Required(fldPath.Child("expression"), ""))
|
||||||
} else {
|
} else {
|
||||||
allErrors = append(allErrors, validateCELExpression(trimmedExpression, plugincel.OptionalVariableDeclarations{
|
allErrors = append(allErrors, validateCELExpression(trimmedExpression, plugincel.OptionalVariableDeclarations{
|
||||||
HasParams: false,
|
HasParams: opts.allowParamsInMatchConditions,
|
||||||
HasAuthorizer: true,
|
HasAuthorizer: true,
|
||||||
}, fldPath.Child("expression"))...)
|
}, fldPath.Child("expression"))...)
|
||||||
}
|
}
|
||||||
@ -995,7 +1015,7 @@ func validateParamRef(pr *admissionregistration.ParamRef, fldPath *field.Path) f
|
|||||||
|
|
||||||
// ValidateValidatingAdmissionPolicyUpdate validates update of validating admission policy
|
// ValidateValidatingAdmissionPolicyUpdate validates update of validating admission policy
|
||||||
func ValidateValidatingAdmissionPolicyUpdate(newC, oldC *admissionregistration.ValidatingAdmissionPolicy) field.ErrorList {
|
func ValidateValidatingAdmissionPolicyUpdate(newC, oldC *admissionregistration.ValidatingAdmissionPolicy) field.ErrorList {
|
||||||
return validateValidatingAdmissionPolicy(newC)
|
return validateValidatingAdmissionPolicy(newC, validationOptions{ignoreMatchConditions: ignoreValidatingAdmissionPolicyMatchConditions(newC, oldC)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateValidatingAdmissionPolicyStatusUpdate validates update of status of validating admission policy
|
// ValidateValidatingAdmissionPolicyStatusUpdate validates update of status of validating admission policy
|
||||||
|
@ -3150,6 +3150,131 @@ func TestValidateValidatingAdmissionPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedError: `spec.auditAnnotations[0].valueExpression: Invalid value: "object.x in [1, 2, ": compilation failed: ERROR: <input>:1:19: Syntax error: missing ']' at '<EOF>`,
|
expectedError: `spec.auditAnnotations[0].valueExpression: Invalid value: "object.x in [1, 2, ": compilation failed: ERROR: <input>:1:19: Syntax error: missing ']' at '<EOF>`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "single match condition must have a name",
|
||||||
|
config: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Expression: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: `spec.matchConditions[0].name: Required value`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "match condition with parameters allowed",
|
||||||
|
config: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
ParamKind: &admissionregistration.ParamKind{
|
||||||
|
Kind: "Foo",
|
||||||
|
APIVersion: "foobar/v1alpha1",
|
||||||
|
},
|
||||||
|
MatchConstraints: &admissionregistration.MatchResources{
|
||||||
|
ResourceRules: []admissionregistration.NamedRuleWithOperations{
|
||||||
|
{
|
||||||
|
RuleWithOperations: admissionregistration.RuleWithOperations{
|
||||||
|
Operations: []admissionregistration.OperationType{"*"},
|
||||||
|
Rule: admissionregistration.Rule{
|
||||||
|
APIGroups: []string{"a"},
|
||||||
|
APIVersions: []string{"a"},
|
||||||
|
Resources: []string{"a"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NamespaceSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
ObjectSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
MatchPolicy: func() *admissionregistration.MatchPolicyType {
|
||||||
|
r := admissionregistration.MatchPolicyType("Exact")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||||
|
r := admissionregistration.FailurePolicyType("Fail")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Name: "hasParams",
|
||||||
|
Expression: `params.foo == "okay"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "match condition with parameters not allowed if no param kind",
|
||||||
|
config: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
MatchConstraints: &admissionregistration.MatchResources{
|
||||||
|
ResourceRules: []admissionregistration.NamedRuleWithOperations{
|
||||||
|
{
|
||||||
|
RuleWithOperations: admissionregistration.RuleWithOperations{
|
||||||
|
Operations: []admissionregistration.OperationType{"*"},
|
||||||
|
Rule: admissionregistration.Rule{
|
||||||
|
APIGroups: []string{"a"},
|
||||||
|
APIVersions: []string{"a"},
|
||||||
|
Resources: []string{"a"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NamespaceSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
ObjectSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
MatchPolicy: func() *admissionregistration.MatchPolicyType {
|
||||||
|
r := admissionregistration.MatchPolicyType("Exact")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||||
|
r := admissionregistration.FailurePolicyType("Fail")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Name: "hasParams",
|
||||||
|
Expression: `params.foo == "okay"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: `undeclared reference to 'params'`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
@ -3293,6 +3418,202 @@ func TestValidateValidatingAdmissionPolicyUpdate(t *testing.T) {
|
|||||||
Spec: admissionregistration.ValidatingAdmissionPolicySpec{},
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "match conditions re-checked if paramKind changes",
|
||||||
|
oldconfig: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
ParamKind: &admissionregistration.ParamKind{
|
||||||
|
Kind: "Foo",
|
||||||
|
APIVersion: "foobar/v1alpha1",
|
||||||
|
},
|
||||||
|
MatchConstraints: &admissionregistration.MatchResources{
|
||||||
|
ResourceRules: []admissionregistration.NamedRuleWithOperations{
|
||||||
|
{
|
||||||
|
RuleWithOperations: admissionregistration.RuleWithOperations{
|
||||||
|
Operations: []admissionregistration.OperationType{"*"},
|
||||||
|
Rule: admissionregistration.Rule{
|
||||||
|
APIGroups: []string{"a"},
|
||||||
|
APIVersions: []string{"a"},
|
||||||
|
Resources: []string{"a"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NamespaceSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
ObjectSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
MatchPolicy: func() *admissionregistration.MatchPolicyType {
|
||||||
|
r := admissionregistration.MatchPolicyType("Exact")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||||
|
r := admissionregistration.FailurePolicyType("Fail")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Name: "hasParams",
|
||||||
|
Expression: `params.foo == "okay"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
MatchConstraints: &admissionregistration.MatchResources{
|
||||||
|
ResourceRules: []admissionregistration.NamedRuleWithOperations{
|
||||||
|
{
|
||||||
|
RuleWithOperations: admissionregistration.RuleWithOperations{
|
||||||
|
Operations: []admissionregistration.OperationType{"*"},
|
||||||
|
Rule: admissionregistration.Rule{
|
||||||
|
APIGroups: []string{"a"},
|
||||||
|
APIVersions: []string{"a"},
|
||||||
|
Resources: []string{"a"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NamespaceSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
ObjectSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
MatchPolicy: func() *admissionregistration.MatchPolicyType {
|
||||||
|
r := admissionregistration.MatchPolicyType("Exact")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||||
|
r := admissionregistration.FailurePolicyType("Fail")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Name: "hasParams",
|
||||||
|
Expression: `params.foo == "okay"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: `undeclared reference to 'params'`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "match conditions not re-checked if no change to paramKind or matchConditions",
|
||||||
|
oldconfig: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
MatchConstraints: &admissionregistration.MatchResources{
|
||||||
|
ResourceRules: []admissionregistration.NamedRuleWithOperations{
|
||||||
|
{
|
||||||
|
RuleWithOperations: admissionregistration.RuleWithOperations{
|
||||||
|
Operations: []admissionregistration.OperationType{"*"},
|
||||||
|
Rule: admissionregistration.Rule{
|
||||||
|
APIGroups: []string{"a"},
|
||||||
|
APIVersions: []string{"a"},
|
||||||
|
Resources: []string{"a"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NamespaceSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
ObjectSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
MatchPolicy: func() *admissionregistration.MatchPolicyType {
|
||||||
|
r := admissionregistration.MatchPolicyType("Exact")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||||
|
r := admissionregistration.FailurePolicyType("Fail")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Name: "hasParams",
|
||||||
|
Expression: `params.foo == "okay"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config: &admissionregistration.ValidatingAdmissionPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "config",
|
||||||
|
},
|
||||||
|
Spec: admissionregistration.ValidatingAdmissionPolicySpec{
|
||||||
|
MatchConstraints: &admissionregistration.MatchResources{
|
||||||
|
ResourceRules: []admissionregistration.NamedRuleWithOperations{
|
||||||
|
{
|
||||||
|
RuleWithOperations: admissionregistration.RuleWithOperations{
|
||||||
|
Operations: []admissionregistration.OperationType{"*"},
|
||||||
|
Rule: admissionregistration.Rule{
|
||||||
|
APIGroups: []string{"a"},
|
||||||
|
APIVersions: []string{"a"},
|
||||||
|
Resources: []string{"a"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NamespaceSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
ObjectSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{"a": "b"},
|
||||||
|
},
|
||||||
|
MatchPolicy: func() *admissionregistration.MatchPolicyType {
|
||||||
|
r := admissionregistration.MatchPolicyType("Exact")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
FailurePolicy: func() *admissionregistration.FailurePolicyType {
|
||||||
|
r := admissionregistration.FailurePolicyType("Ignore")
|
||||||
|
return &r
|
||||||
|
}(),
|
||||||
|
MatchConditions: []admissionregistration.MatchCondition{
|
||||||
|
{
|
||||||
|
Name: "hasParams",
|
||||||
|
Expression: `params.foo == "okay"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []admissionregistration.Validation{
|
||||||
|
{
|
||||||
|
Expression: "object.x < 50",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: "",
|
||||||
|
},
|
||||||
// TODO: CustomAuditAnnotations: string valueExpression with {oldObject} is allowed
|
// TODO: CustomAuditAnnotations: string valueExpression with {oldObject} is allowed
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -580,6 +580,11 @@ func (in *ValidatingAdmissionPolicySpec) DeepCopyInto(out *ValidatingAdmissionPo
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.MatchConditions != nil {
|
||||||
|
in, out := &in.MatchConditions, &out.MatchConditions
|
||||||
|
*out = make([]MatchCondition, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
if in.FailurePolicy != nil {
|
if in.FailurePolicy != nil {
|
||||||
in, out := &in.FailurePolicy, &out.FailurePolicy
|
in, out := &in.FailurePolicy, &out.FailurePolicy
|
||||||
*out = new(FailurePolicyType)
|
*out = new(FailurePolicyType)
|
||||||
|
56
pkg/generated/openapi/zz_generated.openapi.go
generated
56
pkg/generated/openapi/zz_generated.openapi.go
generated
@ -48,6 +48,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
|||||||
"k8s.io/api/admissionregistration/v1.WebhookClientConfig": schema_k8sio_api_admissionregistration_v1_WebhookClientConfig(ref),
|
"k8s.io/api/admissionregistration/v1.WebhookClientConfig": schema_k8sio_api_admissionregistration_v1_WebhookClientConfig(ref),
|
||||||
"k8s.io/api/admissionregistration/v1alpha1.AuditAnnotation": schema_k8sio_api_admissionregistration_v1alpha1_AuditAnnotation(ref),
|
"k8s.io/api/admissionregistration/v1alpha1.AuditAnnotation": schema_k8sio_api_admissionregistration_v1alpha1_AuditAnnotation(ref),
|
||||||
"k8s.io/api/admissionregistration/v1alpha1.ExpressionWarning": schema_k8sio_api_admissionregistration_v1alpha1_ExpressionWarning(ref),
|
"k8s.io/api/admissionregistration/v1alpha1.ExpressionWarning": schema_k8sio_api_admissionregistration_v1alpha1_ExpressionWarning(ref),
|
||||||
|
"k8s.io/api/admissionregistration/v1alpha1.MatchCondition": schema_k8sio_api_admissionregistration_v1alpha1_MatchCondition(ref),
|
||||||
"k8s.io/api/admissionregistration/v1alpha1.MatchResources": schema_k8sio_api_admissionregistration_v1alpha1_MatchResources(ref),
|
"k8s.io/api/admissionregistration/v1alpha1.MatchResources": schema_k8sio_api_admissionregistration_v1alpha1_MatchResources(ref),
|
||||||
"k8s.io/api/admissionregistration/v1alpha1.NamedRuleWithOperations": schema_k8sio_api_admissionregistration_v1alpha1_NamedRuleWithOperations(ref),
|
"k8s.io/api/admissionregistration/v1alpha1.NamedRuleWithOperations": schema_k8sio_api_admissionregistration_v1alpha1_NamedRuleWithOperations(ref),
|
||||||
"k8s.io/api/admissionregistration/v1alpha1.ParamKind": schema_k8sio_api_admissionregistration_v1alpha1_ParamKind(ref),
|
"k8s.io/api/admissionregistration/v1alpha1.ParamKind": schema_k8sio_api_admissionregistration_v1alpha1_ParamKind(ref),
|
||||||
@ -2008,6 +2009,35 @@ func schema_k8sio_api_admissionregistration_v1alpha1_ExpressionWarning(ref commo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func schema_k8sio_api_admissionregistration_v1alpha1_MatchCondition(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
|
return common.OpenAPIDefinition{
|
||||||
|
Schema: spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"name": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
|
||||||
|
Default: "",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"expression": {
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
|
||||||
|
Default: "",
|
||||||
|
Type: []string{"string"},
|
||||||
|
Format: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"name", "expression"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func schema_k8sio_api_admissionregistration_v1alpha1_MatchResources(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
func schema_k8sio_api_admissionregistration_v1alpha1_MatchResources(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||||
return common.OpenAPIDefinition{
|
return common.OpenAPIDefinition{
|
||||||
Schema: spec.Schema{
|
Schema: spec.Schema{
|
||||||
@ -2621,11 +2651,35 @@ func schema_k8sio_api_admissionregistration_v1alpha1_ValidatingAdmissionPolicySp
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"matchConditions": {
|
||||||
|
VendorExtensible: spec.VendorExtensible{
|
||||||
|
Extensions: spec.Extensions{
|
||||||
|
"x-kubernetes-list-map-keys": []interface{}{
|
||||||
|
"name",
|
||||||
|
},
|
||||||
|
"x-kubernetes-list-type": "map",
|
||||||
|
"x-kubernetes-patch-merge-key": "name",
|
||||||
|
"x-kubernetes-patch-strategy": "merge",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Description: "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
|
||||||
|
Type: []string{"array"},
|
||||||
|
Items: &spec.SchemaOrArray{
|
||||||
|
Schema: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Default: map[string]interface{}{},
|
||||||
|
Ref: ref("k8s.io/api/admissionregistration/v1alpha1.MatchCondition"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Dependencies: []string{
|
Dependencies: []string{
|
||||||
"k8s.io/api/admissionregistration/v1alpha1.AuditAnnotation", "k8s.io/api/admissionregistration/v1alpha1.MatchResources", "k8s.io/api/admissionregistration/v1alpha1.ParamKind", "k8s.io/api/admissionregistration/v1alpha1.Validation"},
|
"k8s.io/api/admissionregistration/v1alpha1.AuditAnnotation", "k8s.io/api/admissionregistration/v1alpha1.MatchCondition", "k8s.io/api/admissionregistration/v1alpha1.MatchResources", "k8s.io/api/admissionregistration/v1alpha1.ParamKind", "k8s.io/api/admissionregistration/v1alpha1.Validation"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +101,38 @@ func (m *ExpressionWarning) XXX_DiscardUnknown() {
|
|||||||
|
|
||||||
var xxx_messageInfo_ExpressionWarning proto.InternalMessageInfo
|
var xxx_messageInfo_ExpressionWarning proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *MatchCondition) Reset() { *m = MatchCondition{} }
|
||||||
|
func (*MatchCondition) ProtoMessage() {}
|
||||||
|
func (*MatchCondition) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_c3be8d256e3ae3cf, []int{2}
|
||||||
|
}
|
||||||
|
func (m *MatchCondition) XXX_Unmarshal(b []byte) error {
|
||||||
|
return m.Unmarshal(b)
|
||||||
|
}
|
||||||
|
func (m *MatchCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
b = b[:cap(b)]
|
||||||
|
n, err := m.MarshalToSizedBuffer(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b[:n], nil
|
||||||
|
}
|
||||||
|
func (m *MatchCondition) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_MatchCondition.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *MatchCondition) XXX_Size() int {
|
||||||
|
return m.Size()
|
||||||
|
}
|
||||||
|
func (m *MatchCondition) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_MatchCondition.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_MatchCondition proto.InternalMessageInfo
|
||||||
|
|
||||||
func (m *MatchResources) Reset() { *m = MatchResources{} }
|
func (m *MatchResources) Reset() { *m = MatchResources{} }
|
||||||
func (*MatchResources) ProtoMessage() {}
|
func (*MatchResources) ProtoMessage() {}
|
||||||
func (*MatchResources) Descriptor() ([]byte, []int) {
|
func (*MatchResources) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{2}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{3}
|
||||||
}
|
}
|
||||||
func (m *MatchResources) XXX_Unmarshal(b []byte) error {
|
func (m *MatchResources) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -132,7 +160,7 @@ var xxx_messageInfo_MatchResources proto.InternalMessageInfo
|
|||||||
func (m *NamedRuleWithOperations) Reset() { *m = NamedRuleWithOperations{} }
|
func (m *NamedRuleWithOperations) Reset() { *m = NamedRuleWithOperations{} }
|
||||||
func (*NamedRuleWithOperations) ProtoMessage() {}
|
func (*NamedRuleWithOperations) ProtoMessage() {}
|
||||||
func (*NamedRuleWithOperations) Descriptor() ([]byte, []int) {
|
func (*NamedRuleWithOperations) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{3}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{4}
|
||||||
}
|
}
|
||||||
func (m *NamedRuleWithOperations) XXX_Unmarshal(b []byte) error {
|
func (m *NamedRuleWithOperations) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -160,7 +188,7 @@ var xxx_messageInfo_NamedRuleWithOperations proto.InternalMessageInfo
|
|||||||
func (m *ParamKind) Reset() { *m = ParamKind{} }
|
func (m *ParamKind) Reset() { *m = ParamKind{} }
|
||||||
func (*ParamKind) ProtoMessage() {}
|
func (*ParamKind) ProtoMessage() {}
|
||||||
func (*ParamKind) Descriptor() ([]byte, []int) {
|
func (*ParamKind) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{4}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{5}
|
||||||
}
|
}
|
||||||
func (m *ParamKind) XXX_Unmarshal(b []byte) error {
|
func (m *ParamKind) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -188,7 +216,7 @@ var xxx_messageInfo_ParamKind proto.InternalMessageInfo
|
|||||||
func (m *ParamRef) Reset() { *m = ParamRef{} }
|
func (m *ParamRef) Reset() { *m = ParamRef{} }
|
||||||
func (*ParamRef) ProtoMessage() {}
|
func (*ParamRef) ProtoMessage() {}
|
||||||
func (*ParamRef) Descriptor() ([]byte, []int) {
|
func (*ParamRef) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{5}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{6}
|
||||||
}
|
}
|
||||||
func (m *ParamRef) XXX_Unmarshal(b []byte) error {
|
func (m *ParamRef) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -216,7 +244,7 @@ var xxx_messageInfo_ParamRef proto.InternalMessageInfo
|
|||||||
func (m *TypeChecking) Reset() { *m = TypeChecking{} }
|
func (m *TypeChecking) Reset() { *m = TypeChecking{} }
|
||||||
func (*TypeChecking) ProtoMessage() {}
|
func (*TypeChecking) ProtoMessage() {}
|
||||||
func (*TypeChecking) Descriptor() ([]byte, []int) {
|
func (*TypeChecking) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{6}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{7}
|
||||||
}
|
}
|
||||||
func (m *TypeChecking) XXX_Unmarshal(b []byte) error {
|
func (m *TypeChecking) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -244,7 +272,7 @@ var xxx_messageInfo_TypeChecking proto.InternalMessageInfo
|
|||||||
func (m *ValidatingAdmissionPolicy) Reset() { *m = ValidatingAdmissionPolicy{} }
|
func (m *ValidatingAdmissionPolicy) Reset() { *m = ValidatingAdmissionPolicy{} }
|
||||||
func (*ValidatingAdmissionPolicy) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicy) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicy) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicy) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{7}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{8}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicy) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicy) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -272,7 +300,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicy proto.InternalMessageInfo
|
|||||||
func (m *ValidatingAdmissionPolicyBinding) Reset() { *m = ValidatingAdmissionPolicyBinding{} }
|
func (m *ValidatingAdmissionPolicyBinding) Reset() { *m = ValidatingAdmissionPolicyBinding{} }
|
||||||
func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicyBinding) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicyBinding) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{8}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{9}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicyBinding) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicyBinding) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -300,7 +328,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyBinding proto.InternalMessageInfo
|
|||||||
func (m *ValidatingAdmissionPolicyBindingList) Reset() { *m = ValidatingAdmissionPolicyBindingList{} }
|
func (m *ValidatingAdmissionPolicyBindingList) Reset() { *m = ValidatingAdmissionPolicyBindingList{} }
|
||||||
func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicyBindingList) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicyBindingList) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{9}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{10}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicyBindingList) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicyBindingList) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -328,7 +356,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyBindingList proto.InternalMessageIn
|
|||||||
func (m *ValidatingAdmissionPolicyBindingSpec) Reset() { *m = ValidatingAdmissionPolicyBindingSpec{} }
|
func (m *ValidatingAdmissionPolicyBindingSpec) Reset() { *m = ValidatingAdmissionPolicyBindingSpec{} }
|
||||||
func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicyBindingSpec) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicyBindingSpec) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{10}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{11}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -356,7 +384,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyBindingSpec proto.InternalMessageIn
|
|||||||
func (m *ValidatingAdmissionPolicyList) Reset() { *m = ValidatingAdmissionPolicyList{} }
|
func (m *ValidatingAdmissionPolicyList) Reset() { *m = ValidatingAdmissionPolicyList{} }
|
||||||
func (*ValidatingAdmissionPolicyList) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicyList) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicyList) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicyList) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{11}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{12}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicyList) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicyList) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -384,7 +412,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyList proto.InternalMessageInfo
|
|||||||
func (m *ValidatingAdmissionPolicySpec) Reset() { *m = ValidatingAdmissionPolicySpec{} }
|
func (m *ValidatingAdmissionPolicySpec) Reset() { *m = ValidatingAdmissionPolicySpec{} }
|
||||||
func (*ValidatingAdmissionPolicySpec) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicySpec) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicySpec) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicySpec) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{12}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{13}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicySpec) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicySpec) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -412,7 +440,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicySpec proto.InternalMessageInfo
|
|||||||
func (m *ValidatingAdmissionPolicyStatus) Reset() { *m = ValidatingAdmissionPolicyStatus{} }
|
func (m *ValidatingAdmissionPolicyStatus) Reset() { *m = ValidatingAdmissionPolicyStatus{} }
|
||||||
func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {}
|
func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {}
|
||||||
func (*ValidatingAdmissionPolicyStatus) Descriptor() ([]byte, []int) {
|
func (*ValidatingAdmissionPolicyStatus) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{13}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{14}
|
||||||
}
|
}
|
||||||
func (m *ValidatingAdmissionPolicyStatus) XXX_Unmarshal(b []byte) error {
|
func (m *ValidatingAdmissionPolicyStatus) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -440,7 +468,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyStatus proto.InternalMessageInfo
|
|||||||
func (m *Validation) Reset() { *m = Validation{} }
|
func (m *Validation) Reset() { *m = Validation{} }
|
||||||
func (*Validation) ProtoMessage() {}
|
func (*Validation) ProtoMessage() {}
|
||||||
func (*Validation) Descriptor() ([]byte, []int) {
|
func (*Validation) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_c3be8d256e3ae3cf, []int{14}
|
return fileDescriptor_c3be8d256e3ae3cf, []int{15}
|
||||||
}
|
}
|
||||||
func (m *Validation) XXX_Unmarshal(b []byte) error {
|
func (m *Validation) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@ -468,6 +496,7 @@ var xxx_messageInfo_Validation proto.InternalMessageInfo
|
|||||||
func init() {
|
func init() {
|
||||||
proto.RegisterType((*AuditAnnotation)(nil), "k8s.io.api.admissionregistration.v1alpha1.AuditAnnotation")
|
proto.RegisterType((*AuditAnnotation)(nil), "k8s.io.api.admissionregistration.v1alpha1.AuditAnnotation")
|
||||||
proto.RegisterType((*ExpressionWarning)(nil), "k8s.io.api.admissionregistration.v1alpha1.ExpressionWarning")
|
proto.RegisterType((*ExpressionWarning)(nil), "k8s.io.api.admissionregistration.v1alpha1.ExpressionWarning")
|
||||||
|
proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchCondition")
|
||||||
proto.RegisterType((*MatchResources)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchResources")
|
proto.RegisterType((*MatchResources)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchResources")
|
||||||
proto.RegisterType((*NamedRuleWithOperations)(nil), "k8s.io.api.admissionregistration.v1alpha1.NamedRuleWithOperations")
|
proto.RegisterType((*NamedRuleWithOperations)(nil), "k8s.io.api.admissionregistration.v1alpha1.NamedRuleWithOperations")
|
||||||
proto.RegisterType((*ParamKind)(nil), "k8s.io.api.admissionregistration.v1alpha1.ParamKind")
|
proto.RegisterType((*ParamKind)(nil), "k8s.io.api.admissionregistration.v1alpha1.ParamKind")
|
||||||
@ -488,93 +517,95 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptor_c3be8d256e3ae3cf = []byte{
|
var fileDescriptor_c3be8d256e3ae3cf = []byte{
|
||||||
// 1367 bytes of a gzipped FileDescriptorProto
|
// 1407 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4b, 0x6f, 0x5b, 0xc5,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x6f, 0x1b, 0x45,
|
||||||
0x17, 0xcf, 0x8d, 0xdd, 0x36, 0x39, 0xce, 0xcb, 0xf3, 0x6f, 0x55, 0x37, 0xfa, 0xd7, 0x8e, 0xae,
|
0x18, 0xcf, 0xc6, 0x4e, 0x9a, 0x8c, 0xf3, 0xb0, 0x87, 0x56, 0x75, 0x23, 0x6a, 0x47, 0xab, 0x0a,
|
||||||
0x2a, 0xd4, 0x48, 0x70, 0x4d, 0xd2, 0x42, 0x01, 0x21, 0xa1, 0xdc, 0xbe, 0xe8, 0x23, 0x4d, 0x34,
|
0x35, 0x12, 0xec, 0x92, 0xb4, 0x50, 0x40, 0x48, 0x28, 0xdb, 0x17, 0x7d, 0xa4, 0x89, 0xa6, 0x28,
|
||||||
0x45, 0x89, 0x84, 0xa8, 0xc4, 0xe4, 0xde, 0x89, 0x3d, 0xb5, 0xef, 0x83, 0x3b, 0xd7, 0xa1, 0x11,
|
0x91, 0x10, 0x95, 0x98, 0xec, 0x4e, 0xec, 0xa9, 0xbd, 0x0f, 0x76, 0xd6, 0xa1, 0x11, 0x48, 0x54,
|
||||||
0x0b, 0x2a, 0xb1, 0x81, 0x1d, 0x0b, 0x36, 0x7c, 0x19, 0x24, 0x76, 0x5d, 0x76, 0x59, 0x16, 0x58,
|
0xe2, 0x02, 0x37, 0x0e, 0x5c, 0xf8, 0x5f, 0xb8, 0x70, 0xeb, 0xb1, 0xc7, 0x72, 0xc0, 0x22, 0xe6,
|
||||||
0xd4, 0x6c, 0xf8, 0x04, 0x20, 0x65, 0x03, 0x9a, 0xb9, 0x73, 0x9f, 0x76, 0x88, 0x53, 0x02, 0x3b,
|
0xc2, 0x5f, 0x00, 0x52, 0x2e, 0xa0, 0x99, 0x9d, 0x7d, 0x3b, 0xc4, 0x2e, 0x81, 0x9b, 0xf7, 0x7b,
|
||||||
0xdf, 0xf3, 0xf8, 0xfd, 0xe6, 0x9c, 0x39, 0x73, 0xe6, 0x8c, 0x01, 0x77, 0xde, 0xe1, 0x06, 0xf3,
|
0xfc, 0x7e, 0xf3, 0x7d, 0xf3, 0x7d, 0x33, 0xdf, 0x18, 0xa0, 0xce, 0x3b, 0x4c, 0xa3, 0xae, 0xde,
|
||||||
0x9a, 0x9d, 0xde, 0x0e, 0x0d, 0x5c, 0x1a, 0x52, 0xde, 0xdc, 0xa3, 0xae, 0xed, 0x05, 0x4d, 0xa5,
|
0xe9, 0xed, 0x12, 0xdf, 0x21, 0x01, 0x61, 0xfa, 0x3e, 0x71, 0x2c, 0xd7, 0xd7, 0xa5, 0x02, 0x7b,
|
||||||
0x20, 0x3e, 0x6b, 0x12, 0xdb, 0x61, 0x9c, 0x33, 0xcf, 0x0d, 0x68, 0x8b, 0xf1, 0x30, 0x20, 0x21,
|
0x54, 0xc7, 0x96, 0x4d, 0x19, 0xa3, 0xae, 0xe3, 0x93, 0x16, 0x65, 0x81, 0x8f, 0x03, 0xea, 0x3a,
|
||||||
0xf3, 0xdc, 0xe6, 0xde, 0x0a, 0xe9, 0xfa, 0x6d, 0xb2, 0xd2, 0x6c, 0x51, 0x97, 0x06, 0x24, 0xa4,
|
0xfa, 0xfe, 0x2a, 0xee, 0x7a, 0x6d, 0xbc, 0xaa, 0xb7, 0x88, 0x43, 0x7c, 0x1c, 0x10, 0x4b, 0xf3,
|
||||||
0xb6, 0xe1, 0x07, 0x5e, 0xe8, 0xa1, 0xe5, 0xc8, 0xd5, 0x20, 0x3e, 0x33, 0x46, 0xba, 0x1a, 0xb1,
|
0x7c, 0x37, 0x70, 0xe1, 0x4a, 0xe8, 0xaa, 0x61, 0x8f, 0x6a, 0x43, 0x5d, 0xb5, 0xc8, 0x75, 0xe9,
|
||||||
0xeb, 0xe2, 0x1b, 0x2d, 0x16, 0xb6, 0x7b, 0x3b, 0x86, 0xe5, 0x39, 0xcd, 0x96, 0xd7, 0xf2, 0x9a,
|
0x8d, 0x16, 0x0d, 0xda, 0xbd, 0x5d, 0xcd, 0x74, 0x6d, 0xbd, 0xe5, 0xb6, 0x5c, 0x5d, 0x20, 0xec,
|
||||||
0x12, 0x61, 0xa7, 0xb7, 0x2b, 0xbf, 0xe4, 0x87, 0xfc, 0x15, 0x21, 0x2f, 0x5e, 0x19, 0x63, 0x51,
|
0xf6, 0xf6, 0xc4, 0x97, 0xf8, 0x10, 0xbf, 0x42, 0xe4, 0xa5, 0x2b, 0x23, 0x2c, 0x2a, 0xbf, 0x9c,
|
||||||
0xc5, 0xe5, 0x2c, 0x5e, 0x4d, 0x9d, 0x1c, 0x62, 0xb5, 0x99, 0x4b, 0x83, 0xfd, 0xa6, 0xdf, 0x69,
|
0xa5, 0xab, 0x89, 0x93, 0x8d, 0xcd, 0x36, 0x75, 0x88, 0x7f, 0xa0, 0x7b, 0x9d, 0x16, 0x17, 0x30,
|
||||||
0x09, 0x01, 0x6f, 0x3a, 0x34, 0x24, 0xa3, 0xbc, 0x9a, 0x87, 0x79, 0x05, 0x3d, 0x37, 0x64, 0x0e,
|
0xdd, 0x26, 0x01, 0x1e, 0xe6, 0xa5, 0x1f, 0xe7, 0xe5, 0xf7, 0x9c, 0x80, 0xda, 0xa4, 0xe0, 0xf0,
|
||||||
0x1d, 0x72, 0x78, 0xfb, 0x28, 0x07, 0x6e, 0xb5, 0xa9, 0x43, 0x8a, 0x7e, 0x3a, 0x87, 0xf9, 0xb5,
|
0xf6, 0x49, 0x0e, 0xcc, 0x6c, 0x13, 0x1b, 0xe7, 0xfd, 0x54, 0x06, 0x16, 0xd7, 0x7b, 0x16, 0x0d,
|
||||||
0x9e, 0xcd, 0xc2, 0x35, 0xd7, 0xf5, 0x42, 0x19, 0x04, 0xba, 0x08, 0xa5, 0x0e, 0xdd, 0xaf, 0x69,
|
0xd6, 0x1d, 0xc7, 0x0d, 0x44, 0x10, 0xf0, 0x22, 0x28, 0x75, 0xc8, 0x41, 0x5d, 0x59, 0x56, 0x2e,
|
||||||
0x4b, 0xda, 0xe5, 0x69, 0xb3, 0xf2, 0xac, 0xdf, 0x98, 0x18, 0xf4, 0x1b, 0xa5, 0x7b, 0x74, 0x1f,
|
0xcf, 0x1a, 0x95, 0x67, 0xfd, 0xe6, 0xc4, 0xa0, 0xdf, 0x2c, 0xdd, 0x23, 0x07, 0x88, 0xcb, 0xe1,
|
||||||
0x0b, 0x39, 0x5a, 0x83, 0xf9, 0x3d, 0xd2, 0xed, 0xd1, 0x9b, 0x4f, 0xfc, 0x80, 0xca, 0x14, 0xd4,
|
0x3a, 0x58, 0xdc, 0xc7, 0xdd, 0x1e, 0xb9, 0xf9, 0xc4, 0xf3, 0x89, 0x48, 0x41, 0x7d, 0x52, 0x98,
|
||||||
0x26, 0xa5, 0xe9, 0x79, 0x65, 0x3a, 0xbf, 0x95, 0x57, 0xe3, 0xa2, 0xbd, 0xde, 0x85, 0x6a, 0xfa,
|
0x9e, 0x97, 0xa6, 0x8b, 0xdb, 0x59, 0x35, 0xca, 0xdb, 0xab, 0x5d, 0x50, 0x4b, 0xbe, 0x76, 0xb0,
|
||||||
0xb5, 0x4d, 0x02, 0x97, 0xb9, 0x2d, 0xf4, 0x3a, 0x4c, 0xed, 0x32, 0xda, 0xb5, 0x31, 0xdd, 0x55,
|
0xef, 0x50, 0xa7, 0x05, 0x5f, 0x07, 0x33, 0x7b, 0x94, 0x74, 0x2d, 0x44, 0xf6, 0x24, 0x60, 0x55,
|
||||||
0x80, 0x0b, 0x0a, 0x70, 0xea, 0x96, 0x92, 0xe3, 0xc4, 0x02, 0x2d, 0xc3, 0x99, 0xcf, 0x23, 0xc7,
|
0x02, 0xce, 0xdc, 0x92, 0x72, 0x14, 0x5b, 0xc0, 0x15, 0x70, 0xe6, 0xf3, 0xd0, 0xb1, 0x5e, 0x12,
|
||||||
0x5a, 0x49, 0x1a, 0xcf, 0x2b, 0xe3, 0x33, 0x0a, 0x0f, 0xc7, 0x7a, 0xfd, 0xa7, 0x32, 0xcc, 0xad,
|
0xc6, 0x8b, 0xd2, 0xf8, 0x8c, 0xc4, 0x43, 0x91, 0x5e, 0xdd, 0x03, 0x0b, 0x1b, 0x38, 0x30, 0xdb,
|
||||||
0x93, 0xd0, 0x6a, 0x63, 0xca, 0xbd, 0x5e, 0x60, 0x51, 0x8e, 0x9e, 0x40, 0xd5, 0x25, 0x0e, 0xe5,
|
0xd7, 0x5d, 0xc7, 0xa2, 0x22, 0xc2, 0x65, 0x50, 0x76, 0xb0, 0x4d, 0x64, 0x88, 0x73, 0xd2, 0xb3,
|
||||||
0x3e, 0xb1, 0xe8, 0x43, 0xda, 0xa5, 0x56, 0xe8, 0x05, 0x32, 0xe0, 0xca, 0xea, 0x15, 0x23, 0xad,
|
0xfc, 0x00, 0xdb, 0x04, 0x09, 0x0d, 0x5c, 0x03, 0x80, 0xe4, 0xe3, 0x83, 0xd2, 0x0e, 0xa4, 0x42,
|
||||||
0x9f, 0x24, 0x93, 0x86, 0xdf, 0x69, 0x09, 0x01, 0x37, 0xc4, 0x86, 0x19, 0x7b, 0x2b, 0xc6, 0x7d,
|
0x4b, 0x59, 0xa9, 0x3f, 0x97, 0x25, 0x11, 0x22, 0xcc, 0xed, 0xf9, 0x26, 0x61, 0xf0, 0x09, 0xa8,
|
||||||
0xb2, 0x43, 0xbb, 0xb1, 0xab, 0x79, 0x6e, 0xd0, 0x6f, 0x54, 0x1f, 0x14, 0x11, 0xf1, 0x30, 0x09,
|
0x71, 0x38, 0xe6, 0x61, 0x93, 0x3c, 0x24, 0x5d, 0x62, 0x06, 0xae, 0x2f, 0x58, 0x2b, 0x6b, 0x57,
|
||||||
0xf2, 0x60, 0xce, 0xdb, 0x79, 0x4c, 0xad, 0x30, 0xa1, 0x9d, 0x7c, 0x75, 0x5a, 0x34, 0xe8, 0x37,
|
0xb4, 0xa4, 0x4e, 0xe3, 0x1d, 0xd3, 0xbc, 0x4e, 0x8b, 0x0b, 0x98, 0xc6, 0x0b, 0x43, 0xdb, 0x5f,
|
||||||
0xe6, 0x36, 0x72, 0x70, 0xb8, 0x00, 0x8f, 0xbe, 0x84, 0xd9, 0x40, 0xc5, 0x8d, 0x7b, 0x5d, 0xca,
|
0xd5, 0xee, 0xe3, 0x5d, 0xd2, 0x8d, 0x5c, 0x8d, 0x73, 0x83, 0x7e, 0xb3, 0xf6, 0x20, 0x8f, 0x88,
|
||||||
0x6b, 0xa5, 0xa5, 0xd2, 0xe5, 0xca, 0xaa, 0x69, 0x8c, 0x7d, 0x4c, 0x0c, 0x11, 0x98, 0x2d, 0x9c,
|
0x8a, 0x24, 0xd0, 0x05, 0x0b, 0xee, 0xee, 0x63, 0x62, 0x06, 0x31, 0xed, 0xe4, 0xcb, 0xd3, 0xc2,
|
||||||
0xb7, 0x59, 0xd8, 0xde, 0xf0, 0x69, 0xa4, 0xe7, 0xe6, 0x39, 0x95, 0xf2, 0x59, 0x9c, 0x25, 0xc0,
|
0x41, 0xbf, 0xb9, 0xb0, 0x99, 0x81, 0x43, 0x39, 0x78, 0xf8, 0x15, 0x98, 0xf7, 0x65, 0xdc, 0xa8,
|
||||||
0x79, 0x3e, 0xf4, 0x9d, 0x06, 0x67, 0xe9, 0x13, 0xab, 0xdb, 0xb3, 0x69, 0xce, 0xae, 0x56, 0x3e,
|
0xd7, 0x25, 0xac, 0x5e, 0x5a, 0x2e, 0x5d, 0xae, 0xac, 0x19, 0xda, 0xc8, 0xed, 0xa8, 0xf1, 0xc0,
|
||||||
0xb1, 0x85, 0xfc, 0x5f, 0x2d, 0xe4, 0xec, 0xcd, 0x11, 0x3c, 0x78, 0x24, 0x3b, 0xba, 0x01, 0x15,
|
0x2c, 0xee, 0xbc, 0x43, 0x83, 0xf6, 0xa6, 0x47, 0x42, 0x3d, 0x33, 0xce, 0xc9, 0xc4, 0xcf, 0xa3,
|
||||||
0x47, 0x14, 0xc5, 0xa6, 0xd7, 0x65, 0xd6, 0x7e, 0xed, 0x8c, 0x2c, 0x22, 0x7d, 0xd0, 0x6f, 0x54,
|
0x34, 0x01, 0xca, 0xf2, 0xc1, 0xef, 0x15, 0x70, 0x96, 0x3c, 0x31, 0xbb, 0x3d, 0x8b, 0x64, 0xec,
|
||||||
0xd6, 0x53, 0xf1, 0x41, 0xbf, 0x31, 0x9f, 0xf9, 0xfc, 0x68, 0xdf, 0xa7, 0x38, 0xeb, 0xa6, 0xbf,
|
0xea, 0xe5, 0x53, 0x5b, 0xc8, 0xab, 0x72, 0x21, 0x67, 0x6f, 0x0e, 0xe1, 0x41, 0x43, 0xd9, 0xe1,
|
||||||
0xd0, 0xe0, 0xfc, 0x21, 0xab, 0x42, 0xd7, 0xd2, 0xcc, 0xcb, 0xd2, 0xa8, 0x69, 0x4b, 0xa5, 0xcb,
|
0x0d, 0x50, 0xb1, 0x79, 0x51, 0x6c, 0xb9, 0x5d, 0x6a, 0x1e, 0xd4, 0xcf, 0x88, 0x52, 0x52, 0x07,
|
||||||
0xd3, 0x66, 0x35, 0x9b, 0x31, 0xa9, 0xc0, 0x79, 0x3b, 0xf4, 0x95, 0x06, 0x28, 0x18, 0xc2, 0x53,
|
0xfd, 0x66, 0x65, 0x23, 0x11, 0x1f, 0xf5, 0x9b, 0x8b, 0xa9, 0xcf, 0x8f, 0x0e, 0x3c, 0x82, 0xd2,
|
||||||
0x85, 0x72, 0x6d, 0x9c, 0x7c, 0x19, 0x23, 0x92, 0xb4, 0xa8, 0x92, 0x84, 0x86, 0x75, 0x78, 0x04,
|
0x6e, 0xea, 0x0b, 0x05, 0x9c, 0x3f, 0x66, 0x55, 0xf0, 0x5a, 0x92, 0x79, 0x51, 0x1a, 0x75, 0x65,
|
||||||
0x9d, 0x4e, 0x60, 0x7a, 0x93, 0x04, 0xc4, 0xb9, 0xc7, 0x5c, 0x1b, 0xad, 0x02, 0x10, 0x9f, 0x6d,
|
0xb9, 0x74, 0x79, 0xd6, 0xa8, 0xa5, 0x33, 0x26, 0x14, 0x28, 0x6b, 0x07, 0xbf, 0x56, 0x00, 0xf4,
|
||||||
0xd1, 0x40, 0x9e, 0xf7, 0xa8, 0x35, 0x20, 0x05, 0x08, 0x6b, 0x9b, 0x77, 0x94, 0x06, 0x67, 0xac,
|
0x0b, 0x78, 0xb2, 0x50, 0xae, 0x8d, 0x92, 0x2f, 0x6d, 0x48, 0x92, 0x96, 0x64, 0x92, 0x60, 0x51,
|
||||||
0xd0, 0x12, 0x94, 0x3b, 0xcc, 0xb5, 0xd5, 0x61, 0x9e, 0x51, 0xd6, 0x65, 0x81, 0x87, 0xa5, 0x46,
|
0x87, 0x86, 0xd0, 0xa9, 0x18, 0xcc, 0x6e, 0x61, 0x1f, 0xdb, 0xf7, 0xa8, 0x63, 0xf1, 0xbe, 0xc3,
|
||||||
0x7f, 0x04, 0x53, 0x92, 0x42, 0x1c, 0xe8, 0x25, 0x28, 0x8b, 0xd3, 0xa2, 0xb0, 0x13, 0x6b, 0x91,
|
0x1e, 0xdd, 0x26, 0xbe, 0xe8, 0x3b, 0x25, 0xdb, 0x77, 0xeb, 0x5b, 0x77, 0xa4, 0x06, 0xa5, 0xac,
|
||||||
0x11, 0x2c, 0x35, 0xa8, 0x09, 0xd3, 0xc9, 0x79, 0x52, 0xa0, 0x55, 0x65, 0x36, 0x9d, 0x9c, 0x3d,
|
0x78, 0x37, 0x77, 0xa8, 0x63, 0xc9, 0x2e, 0x8d, 0xbb, 0x99, 0xe3, 0x21, 0xa1, 0x51, 0x1f, 0x81,
|
||||||
0x9c, 0xda, 0xe8, 0xdf, 0x6b, 0x30, 0x23, 0xb6, 0xec, 0x7a, 0x9b, 0x5a, 0x1d, 0xd1, 0x62, 0xbe,
|
0x19, 0x41, 0xc1, 0x0f, 0x8e, 0x93, 0x7b, 0x5f, 0x07, 0xb3, 0x71, 0x3f, 0x49, 0xd0, 0x9a, 0x34,
|
||||||
0xd6, 0x00, 0xd1, 0x62, 0xe3, 0x89, 0xf6, 0xa5, 0xb2, 0xfa, 0xfe, 0x31, 0x0a, 0x71, 0xa8, 0x7b,
|
0x9b, 0x8d, 0x7b, 0x0f, 0x25, 0x36, 0xea, 0x0f, 0x0a, 0x98, 0xe3, 0x5b, 0x76, 0xbd, 0x4d, 0xcc,
|
||||||
0xa5, 0xd9, 0x1d, 0x52, 0x71, 0x3c, 0x82, 0x53, 0xff, 0x79, 0x12, 0x2e, 0x6c, 0x91, 0x2e, 0xb3,
|
0x0e, 0x3f, 0xca, 0xbe, 0x51, 0x00, 0x24, 0xf9, 0x03, 0x2e, 0xdc, 0x97, 0xca, 0xda, 0xfb, 0x63,
|
||||||
0x49, 0xc8, 0xdc, 0xd6, 0x5a, 0x4c, 0x17, 0x95, 0x15, 0xfa, 0x14, 0xa6, 0xc4, 0x89, 0xb7, 0x49,
|
0x14, 0x62, 0xe1, 0x94, 0x4c, 0xb2, 0x5b, 0x50, 0x31, 0x34, 0x84, 0x53, 0xfd, 0x65, 0x12, 0x5c,
|
||||||
0x48, 0x54, 0x5b, 0x7a, 0x73, 0xbc, 0xfe, 0x10, 0x35, 0x83, 0x75, 0x1a, 0x92, 0x74, 0x7b, 0x52,
|
0xd8, 0xc6, 0x5d, 0x6a, 0xe1, 0x80, 0x3a, 0xad, 0xf5, 0x88, 0x2e, 0x2c, 0x2b, 0xf8, 0x29, 0x98,
|
||||||
0x19, 0x4e, 0x50, 0xd1, 0x63, 0x28, 0x73, 0x9f, 0x5a, 0xaa, 0xa8, 0x3e, 0x3c, 0x46, 0xec, 0x87,
|
0xe1, 0x1d, 0x6f, 0xe1, 0x00, 0xcb, 0x63, 0xe9, 0xcd, 0xd1, 0xce, 0x87, 0xf0, 0x30, 0xd8, 0x20,
|
||||||
0xae, 0xfa, 0xa1, 0x4f, 0xad, 0x74, 0xe3, 0xc4, 0x17, 0x96, 0x1c, 0x28, 0x80, 0xd3, 0x3c, 0x24,
|
0x01, 0x4e, 0xb6, 0x27, 0x91, 0xa1, 0x18, 0x15, 0x3e, 0x06, 0x65, 0xe6, 0x11, 0x53, 0x16, 0xd5,
|
||||||
0x61, 0x8f, 0xcb, 0x56, 0x5d, 0x59, 0xbd, 0x7b, 0x22, 0x6c, 0x12, 0xd1, 0x9c, 0x53, 0x7c, 0xa7,
|
0x87, 0x63, 0xc4, 0x7e, 0xec, 0xaa, 0x1f, 0x7a, 0xc4, 0x4c, 0x36, 0x8e, 0x7f, 0x21, 0xc1, 0x01,
|
||||||
0xa3, 0x6f, 0xac, 0x98, 0xf4, 0x3f, 0x34, 0x58, 0x3a, 0xd4, 0xd7, 0x64, 0xae, 0x2d, 0xea, 0xe1,
|
0x7d, 0x30, 0xcd, 0x02, 0x1c, 0xf4, 0x98, 0xb8, 0x12, 0x2a, 0x6b, 0x77, 0x4f, 0x85, 0x4d, 0x20,
|
||||||
0xdf, 0x4f, 0xf3, 0x67, 0xb9, 0x34, 0x6f, 0x9c, 0x44, 0xe0, 0x6a, 0xf1, 0x87, 0x65, 0x5b, 0xff,
|
0x1a, 0x0b, 0x92, 0x6f, 0x3a, 0xfc, 0x46, 0x92, 0x49, 0xfd, 0x53, 0x01, 0xcb, 0xc7, 0xfa, 0x1a,
|
||||||
0x5d, 0x83, 0x4b, 0x47, 0x39, 0xdf, 0x67, 0x3c, 0x44, 0x9f, 0x0c, 0x45, 0x6f, 0x8c, 0x79, 0x09,
|
0xd4, 0xb1, 0x78, 0x3d, 0xfc, 0xf7, 0x69, 0xfe, 0x2c, 0x93, 0xe6, 0xcd, 0xd3, 0x08, 0x5c, 0x2e,
|
||||||
0x31, 0x1e, 0xc5, 0x9e, 0x5c, 0xd0, 0xb1, 0x24, 0x13, 0xb9, 0x0f, 0xa7, 0x58, 0x48, 0x1d, 0xd1,
|
0xfe, 0xb8, 0x6c, 0xab, 0x7f, 0x28, 0xe0, 0xd2, 0x49, 0xce, 0xf7, 0x29, 0x0b, 0xe0, 0x27, 0x85,
|
||||||
0xb6, 0xc4, 0xe9, 0xba, 0x77, 0x82, 0xa1, 0x9b, 0xb3, 0x8a, 0xf7, 0xd4, 0x1d, 0xc1, 0x80, 0x23,
|
0xe8, 0xb5, 0x11, 0x2f, 0x21, 0xca, 0xc2, 0xd8, 0xe3, 0x41, 0x20, 0x92, 0xa4, 0x22, 0xf7, 0xc0,
|
||||||
0x22, 0xfd, 0x9b, 0xd2, 0xd1, 0x81, 0x8b, 0x3c, 0x89, 0x66, 0xe6, 0x4b, 0xe1, 0x83, 0xb4, 0xe1,
|
0x14, 0x0d, 0x88, 0xcd, 0x8f, 0x2d, 0xde, 0x5d, 0xf7, 0x4e, 0x31, 0x74, 0x63, 0x5e, 0xf2, 0x4e,
|
||||||
0x24, 0xdb, 0xb8, 0x99, 0x68, 0x70, 0xc6, 0x0a, 0x3d, 0x82, 0x29, 0x5f, 0xb5, 0xaa, 0x11, 0x37,
|
0xdd, 0xe1, 0x0c, 0x28, 0x24, 0x52, 0xbf, 0x2d, 0x9d, 0x1c, 0x38, 0xcf, 0x13, 0x3f, 0xcc, 0x3c,
|
||||||
0xf6, 0x51, 0x11, 0xc5, 0x5d, 0xce, 0x9c, 0x11, 0xd9, 0x8a, 0xbf, 0x70, 0x02, 0x89, 0x7a, 0x30,
|
0x21, 0x7c, 0x90, 0x1c, 0x38, 0xf1, 0x36, 0x6e, 0xc5, 0x1a, 0x94, 0xb2, 0x82, 0x8f, 0xc0, 0x8c,
|
||||||
0xe7, 0xe4, 0x46, 0x14, 0x75, 0x54, 0xde, 0x3d, 0x06, 0x49, 0x7e, 0xc6, 0x89, 0x86, 0x83, 0xbc,
|
0x27, 0x8f, 0xaa, 0x21, 0x37, 0xf6, 0x49, 0x11, 0x45, 0xa7, 0x9c, 0x31, 0xc7, 0xb3, 0x15, 0x7d,
|
||||||
0x0c, 0x17, 0x48, 0xd0, 0x36, 0x54, 0xf7, 0x54, 0xc6, 0x3c, 0x77, 0xcd, 0x8a, 0xee, 0x99, 0xb2,
|
0xa1, 0x18, 0x12, 0xf6, 0xc0, 0x82, 0x9d, 0x19, 0x51, 0x64, 0xab, 0xbc, 0x3b, 0x06, 0x49, 0x76,
|
||||||
0xbc, 0xa6, 0x96, 0xc5, 0x48, 0xb3, 0x55, 0x54, 0x1e, 0xf4, 0x1b, 0x0b, 0x45, 0x21, 0x1e, 0xc6,
|
0xc6, 0x09, 0x87, 0x83, 0xac, 0x0c, 0xe5, 0x48, 0xe0, 0x0e, 0xa8, 0xed, 0xcb, 0x8c, 0xb9, 0xce,
|
||||||
0xd0, 0x7f, 0xd3, 0xe0, 0xe2, 0xa1, 0x7b, 0xf1, 0x1f, 0x54, 0x1f, 0xcb, 0x57, 0xdf, 0x8d, 0x13,
|
0xba, 0x19, 0xde, 0x33, 0x65, 0x71, 0x4d, 0xad, 0xf0, 0x91, 0x66, 0x3b, 0xaf, 0x3c, 0xea, 0x37,
|
||||||
0xa9, 0xbe, 0xd1, 0x65, 0xf7, 0x43, 0xf9, 0x6f, 0x42, 0x95, 0xf5, 0x46, 0x60, 0xda, 0x8f, 0x6f,
|
0xab, 0x79, 0x21, 0x2a, 0x62, 0xa8, 0xbf, 0x2b, 0xe0, 0xe2, 0xb1, 0x7b, 0xf1, 0x3f, 0x54, 0x1f,
|
||||||
0x52, 0x15, 0xeb, 0xd5, 0xe3, 0x16, 0x8f, 0xf0, 0x35, 0x67, 0xc5, 0x55, 0x97, 0x7c, 0xe2, 0x14,
|
0xcd, 0x56, 0xdf, 0x8d, 0x53, 0xa9, 0xbe, 0xe1, 0x65, 0xf7, 0xe3, 0xd4, 0x3f, 0x84, 0x2a, 0xea,
|
||||||
0x15, 0x7d, 0x01, 0x0b, 0x72, 0x6b, 0xaf, 0x7b, 0xae, 0x00, 0x60, 0x6e, 0x18, 0xcf, 0x0b, 0xff,
|
0x0d, 0x83, 0x59, 0x2f, 0xba, 0x49, 0x65, 0xac, 0x57, 0xc7, 0x2d, 0x1e, 0xee, 0x6b, 0xcc, 0xf3,
|
||||||
0xa0, 0x82, 0xce, 0x0e, 0xfa, 0x8d, 0x85, 0xf5, 0x02, 0x2c, 0x1e, 0x22, 0x42, 0x5d, 0xa8, 0xa4,
|
0xab, 0x2e, 0xfe, 0x44, 0x09, 0x2a, 0xfc, 0x02, 0x54, 0x6d, 0x39, 0x4b, 0x73, 0x00, 0xea, 0x04,
|
||||||
0x15, 0x10, 0x0f, 0x98, 0x6f, 0xbd, 0x42, 0xca, 0x3d, 0xd7, 0xfc, 0x9f, 0xca, 0x71, 0x25, 0x95,
|
0xd1, 0xbc, 0xf0, 0x2f, 0x2a, 0xe8, 0xec, 0xa0, 0xdf, 0xac, 0x6e, 0xe4, 0x60, 0x51, 0x81, 0x08,
|
||||||
0x71, 0x9c, 0x85, 0x47, 0xf7, 0x61, 0x76, 0x97, 0xb0, 0x6e, 0x2f, 0xa0, 0x6a, 0x74, 0x2b, 0xcb,
|
0x76, 0x41, 0x25, 0xa9, 0x80, 0x68, 0xc0, 0x7c, 0xeb, 0x25, 0x52, 0xee, 0x3a, 0xc6, 0x2b, 0x32,
|
||||||
0x03, 0xfc, 0x9a, 0x18, 0xab, 0x6e, 0x65, 0x15, 0x07, 0xfd, 0x46, 0x35, 0x27, 0x90, 0xe3, 0x5b,
|
0xc7, 0x95, 0x44, 0xc6, 0x50, 0x1a, 0x1e, 0xde, 0x07, 0xf3, 0x7b, 0x98, 0x76, 0x7b, 0x3e, 0x91,
|
||||||
0xde, 0x19, 0x3d, 0xd5, 0x60, 0x81, 0xe4, 0x1f, 0x40, 0xbc, 0x76, 0x4a, 0x46, 0xf0, 0xde, 0x31,
|
0xa3, 0x5b, 0x59, 0x34, 0xf0, 0x6b, 0x7c, 0xac, 0xba, 0x95, 0x56, 0x1c, 0xf5, 0x9b, 0xb5, 0x8c,
|
||||||
0x22, 0x28, 0xbc, 0xa1, 0xcc, 0x9a, 0x0a, 0x63, 0xa1, 0xa0, 0xe0, 0x78, 0x88, 0x4d, 0xff, 0x71,
|
0x40, 0x8c, 0x6f, 0x59, 0x67, 0xf8, 0x54, 0x01, 0x55, 0x9c, 0x7d, 0x68, 0xb1, 0xfa, 0x94, 0x88,
|
||||||
0x12, 0x1a, 0x47, 0x5c, 0x73, 0xe8, 0x2e, 0x20, 0x6f, 0x87, 0xd3, 0x60, 0x8f, 0xda, 0xb7, 0xa3,
|
0xe0, 0xbd, 0x31, 0x22, 0xc8, 0xbd, 0xd5, 0x8c, 0xba, 0x0c, 0xa3, 0x9a, 0x53, 0x30, 0x54, 0x60,
|
||||||
0x17, 0x5c, 0x3c, 0x87, 0x95, 0xd2, 0xd1, 0x63, 0x63, 0xc8, 0x02, 0x8f, 0xf0, 0x42, 0x0e, 0xcc,
|
0x83, 0x5f, 0x82, 0x45, 0x3b, 0xf3, 0x0e, 0x62, 0xf5, 0x69, 0xb1, 0x80, 0xb1, 0xb7, 0x2e, 0x46,
|
||||||
0x84, 0x99, 0xa9, 0xe8, 0x38, 0x73, 0xa5, 0x8a, 0x36, 0x3b, 0x54, 0x99, 0x0b, 0x83, 0x7e, 0x23,
|
0x48, 0xde, 0x7c, 0x59, 0x39, 0x43, 0x79, 0x2a, 0xf5, 0xa7, 0x49, 0xd0, 0x3c, 0xe1, 0x92, 0x85,
|
||||||
0x37, 0x66, 0xe1, 0x1c, 0x3c, 0xb2, 0x00, 0x2c, 0xcf, 0xb5, 0x59, 0xb6, 0x38, 0x9a, 0xe3, 0x1d,
|
0x77, 0x01, 0x74, 0x77, 0x19, 0xf1, 0xf7, 0x89, 0x75, 0x3b, 0x7c, 0xa7, 0x46, 0x53, 0x60, 0x29,
|
||||||
0xf5, 0xeb, 0xb1, 0x5f, 0xda, 0x9e, 0x13, 0x11, 0xc7, 0x19, 0x58, 0xfd, 0x4f, 0x0d, 0x20, 0xad,
|
0x19, 0x7c, 0x36, 0x0b, 0x16, 0x68, 0x88, 0x17, 0xb4, 0xc1, 0x5c, 0x90, 0x9a, 0xc9, 0xc6, 0x99,
|
||||||
0x18, 0x74, 0x09, 0x20, 0xf3, 0x3c, 0x8d, 0x3a, 0x7c, 0x59, 0x40, 0xe0, 0x8c, 0x5c, 0xbc, 0x21,
|
0x6a, 0x65, 0xa8, 0xe9, 0x91, 0xce, 0xa8, 0x0e, 0xfa, 0xcd, 0xcc, 0x90, 0x87, 0x32, 0xf0, 0xd0,
|
||||||
0x1d, 0xca, 0x39, 0x69, 0xc5, 0xe3, 0x64, 0xf2, 0x86, 0x5c, 0x8f, 0xc4, 0x38, 0xd6, 0xa3, 0x6d,
|
0x04, 0xc0, 0x4c, 0xf2, 0x1a, 0x96, 0xa6, 0x3e, 0xda, 0x41, 0x93, 0x64, 0x33, 0xbe, 0x1c, 0x52,
|
||||||
0x38, 0x1d, 0x50, 0xc2, 0x3d, 0x57, 0xbd, 0x36, 0x3f, 0x10, 0x23, 0x07, 0x96, 0x92, 0x83, 0x7e,
|
0x89, 0x4c, 0xc1, 0xaa, 0x7f, 0x29, 0x00, 0x24, 0xf5, 0x0a, 0x2f, 0x81, 0xd4, 0x53, 0x54, 0xde,
|
||||||
0x63, 0x65, 0x9c, 0x37, 0xbe, 0xa1, 0x26, 0x14, 0xe9, 0x84, 0x15, 0x1c, 0xba, 0x0d, 0x55, 0xc5,
|
0x2f, 0x65, 0x0e, 0x81, 0x52, 0x72, 0xfe, 0x52, 0xb6, 0x09, 0x63, 0xb8, 0x15, 0x0d, 0xb3, 0xf1,
|
||||||
0x91, 0x59, 0x70, 0x54, 0xd1, 0x17, 0xd4, 0x6a, 0xaa, 0xeb, 0x45, 0x03, 0x3c, 0xec, 0x63, 0x6e,
|
0x4b, 0x79, 0x23, 0x14, 0xa3, 0x48, 0x0f, 0x77, 0xc0, 0xb4, 0x4f, 0x30, 0x73, 0x1d, 0xf9, 0xa6,
|
||||||
0x3c, 0x7b, 0x59, 0x9f, 0x78, 0xfe, 0xb2, 0x3e, 0xf1, 0xe2, 0x65, 0x7d, 0xe2, 0xe9, 0xa0, 0xae,
|
0xfe, 0x80, 0x0f, 0x3c, 0x48, 0x48, 0x8e, 0xfa, 0xcd, 0xd5, 0x51, 0xfe, 0xc9, 0xd0, 0xe4, 0x7c,
|
||||||
0x3d, 0x1b, 0xd4, 0xb5, 0xe7, 0x83, 0xba, 0xf6, 0x62, 0x50, 0xd7, 0x7e, 0x19, 0xd4, 0xb5, 0x6f,
|
0x24, 0x9c, 0x90, 0x84, 0x83, 0xb7, 0x41, 0x4d, 0x72, 0xa4, 0x16, 0x1c, 0xf6, 0xd3, 0x05, 0xb9,
|
||||||
0x7f, 0xad, 0x4f, 0x7c, 0xbc, 0x3c, 0xf6, 0xff, 0x2a, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc3,
|
0x9a, 0xda, 0x46, 0xde, 0x00, 0x15, 0x7d, 0x8c, 0xcd, 0x67, 0x87, 0x8d, 0x89, 0xe7, 0x87, 0x8d,
|
||||||
0xd9, 0x66, 0xdd, 0x9c, 0x11, 0x00, 0x00,
|
0x89, 0x17, 0x87, 0x8d, 0x89, 0xa7, 0x83, 0x86, 0xf2, 0x6c, 0xd0, 0x50, 0x9e, 0x0f, 0x1a, 0xca,
|
||||||
|
0x8b, 0x41, 0x43, 0xf9, 0x75, 0xd0, 0x50, 0xbe, 0xfb, 0xad, 0x31, 0xf1, 0xf1, 0xca, 0xc8, 0xff,
|
||||||
|
0x1e, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x08, 0xaf, 0xaa, 0x52, 0x82, 0x12, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AuditAnnotation) Marshal() (dAtA []byte, err error) {
|
func (m *AuditAnnotation) Marshal() (dAtA []byte, err error) {
|
||||||
@ -643,6 +674,39 @@ func (m *ExpressionWarning) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
return len(dAtA) - i, nil
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MatchCondition) Marshal() (dAtA []byte, err error) {
|
||||||
|
size := m.Size()
|
||||||
|
dAtA = make([]byte, size)
|
||||||
|
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dAtA[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MatchCondition) MarshalTo(dAtA []byte) (int, error) {
|
||||||
|
size := m.Size()
|
||||||
|
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
|
i := len(dAtA)
|
||||||
|
_ = i
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
i -= len(m.Expression)
|
||||||
|
copy(dAtA[i:], m.Expression)
|
||||||
|
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x12
|
||||||
|
i -= len(m.Name)
|
||||||
|
copy(dAtA[i:], m.Name)
|
||||||
|
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0xa
|
||||||
|
return len(dAtA) - i, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MatchResources) Marshal() (dAtA []byte, err error) {
|
func (m *MatchResources) Marshal() (dAtA []byte, err error) {
|
||||||
size := m.Size()
|
size := m.Size()
|
||||||
dAtA = make([]byte, size)
|
dAtA = make([]byte, size)
|
||||||
@ -1141,6 +1205,20 @@ func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int,
|
|||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
|
if len(m.MatchConditions) > 0 {
|
||||||
|
for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
|
||||||
|
{
|
||||||
|
size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i -= size
|
||||||
|
i = encodeVarintGenerated(dAtA, i, uint64(size))
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x32
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(m.AuditAnnotations) > 0 {
|
if len(m.AuditAnnotations) > 0 {
|
||||||
for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- {
|
for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- {
|
||||||
{
|
{
|
||||||
@ -1337,6 +1415,19 @@ func (m *ExpressionWarning) Size() (n int) {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MatchCondition) Size() (n int) {
|
||||||
|
if m == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
l = len(m.Name)
|
||||||
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
|
l = len(m.Expression)
|
||||||
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MatchResources) Size() (n int) {
|
func (m *MatchResources) Size() (n int) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return 0
|
return 0
|
||||||
@ -1545,6 +1636,12 @@ func (m *ValidatingAdmissionPolicySpec) Size() (n int) {
|
|||||||
n += 1 + l + sovGenerated(uint64(l))
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(m.MatchConditions) > 0 {
|
||||||
|
for _, e := range m.MatchConditions {
|
||||||
|
l = e.Size()
|
||||||
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
|
}
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1615,6 +1712,17 @@ func (this *ExpressionWarning) String() string {
|
|||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
func (this *MatchCondition) String() string {
|
||||||
|
if this == nil {
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
s := strings.Join([]string{`&MatchCondition{`,
|
||||||
|
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
|
||||||
|
`Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
|
||||||
|
`}`,
|
||||||
|
}, "")
|
||||||
|
return s
|
||||||
|
}
|
||||||
func (this *MatchResources) String() string {
|
func (this *MatchResources) String() string {
|
||||||
if this == nil {
|
if this == nil {
|
||||||
return "nil"
|
return "nil"
|
||||||
@ -1769,12 +1877,18 @@ func (this *ValidatingAdmissionPolicySpec) String() string {
|
|||||||
repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + ","
|
repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + ","
|
||||||
}
|
}
|
||||||
repeatedStringForAuditAnnotations += "}"
|
repeatedStringForAuditAnnotations += "}"
|
||||||
|
repeatedStringForMatchConditions := "[]MatchCondition{"
|
||||||
|
for _, f := range this.MatchConditions {
|
||||||
|
repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
|
||||||
|
}
|
||||||
|
repeatedStringForMatchConditions += "}"
|
||||||
s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`,
|
s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`,
|
||||||
`ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`,
|
`ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`,
|
||||||
`MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`,
|
`MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`,
|
||||||
`Validations:` + repeatedStringForValidations + `,`,
|
`Validations:` + repeatedStringForValidations + `,`,
|
||||||
`FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
|
`FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
|
||||||
`AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`,
|
`AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`,
|
||||||
|
`MatchConditions:` + repeatedStringForMatchConditions + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -2045,6 +2159,120 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (m *MatchCondition) Unmarshal(dAtA []byte) error {
|
||||||
|
l := len(dAtA)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
preIndex := iNdEx
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNum := int32(wire >> 3)
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
if wireType == 4 {
|
||||||
|
return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Name = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Expression = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
default:
|
||||||
|
iNdEx = preIndex
|
||||||
|
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
if (iNdEx + skippy) > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx += skippy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iNdEx > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (m *MatchResources) Unmarshal(dAtA []byte) error {
|
func (m *MatchResources) Unmarshal(dAtA []byte) error {
|
||||||
l := len(dAtA)
|
l := len(dAtA)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
@ -3582,6 +3810,40 @@ func (m *ValidatingAdmissionPolicySpec) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 6:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowGenerated
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthGenerated
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.MatchConditions = append(m.MatchConditions, MatchCondition{})
|
||||||
|
if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||||
|
@ -79,6 +79,34 @@ message ExpressionWarning {
|
|||||||
optional string warning = 3;
|
optional string warning = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message MatchCondition {
|
||||||
|
// Name is an identifier for this match condition, used for strategic merging of MatchConditions,
|
||||||
|
// as well as providing an identifier for logging purposes. A good name should be descriptive of
|
||||||
|
// the associated expression.
|
||||||
|
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
|
||||||
|
// must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or
|
||||||
|
// '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an
|
||||||
|
// optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
|
||||||
|
//
|
||||||
|
// Required.
|
||||||
|
optional string name = 1;
|
||||||
|
|
||||||
|
// Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
|
||||||
|
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
|
||||||
|
//
|
||||||
|
// 'object' - The object from the incoming request. The value is null for DELETE requests.
|
||||||
|
// 'oldObject' - The existing object. The value is null for CREATE requests.
|
||||||
|
// 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
|
||||||
|
// 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
|
||||||
|
// See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
|
||||||
|
// 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
|
||||||
|
// request resource.
|
||||||
|
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
|
||||||
|
//
|
||||||
|
// Required.
|
||||||
|
optional string expression = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// MatchResources decides whether to run the admission control policy on an object based
|
// MatchResources decides whether to run the admission control policy on an object based
|
||||||
// on whether it meets the match criteria.
|
// on whether it meets the match criteria.
|
||||||
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
|
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
|
||||||
@ -380,6 +408,28 @@ message ValidatingAdmissionPolicySpec {
|
|||||||
// +listType=atomic
|
// +listType=atomic
|
||||||
// +optional
|
// +optional
|
||||||
repeated AuditAnnotation auditAnnotations = 5;
|
repeated AuditAnnotation auditAnnotations = 5;
|
||||||
|
|
||||||
|
// MatchConditions is a list of conditions that must be met for a request to be validated.
|
||||||
|
// Match conditions filter requests that have already been matched by the rules,
|
||||||
|
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
|
||||||
|
// There are a maximum of 64 match conditions allowed.
|
||||||
|
//
|
||||||
|
// If a parameter object is provided, it can be accessed via the `params` handle in the same
|
||||||
|
// manner as validation expressions.
|
||||||
|
//
|
||||||
|
// The exact matching logic is (in order):
|
||||||
|
// 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
|
||||||
|
// 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
|
||||||
|
// 3. If any matchCondition evaluates to an error (but none are FALSE):
|
||||||
|
// - If failurePolicy=Fail, reject the request
|
||||||
|
// - If failurePolicy=Ignore, the policy is skipped
|
||||||
|
//
|
||||||
|
// +patchMergeKey=name
|
||||||
|
// +patchStrategy=merge
|
||||||
|
// +listType=map
|
||||||
|
// +listMapKey=name
|
||||||
|
// +optional
|
||||||
|
repeated MatchCondition matchConditions = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.
|
// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.
|
||||||
|
@ -179,8 +179,32 @@ type ValidatingAdmissionPolicySpec struct {
|
|||||||
// +listType=atomic
|
// +listType=atomic
|
||||||
// +optional
|
// +optional
|
||||||
AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"`
|
AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"`
|
||||||
|
|
||||||
|
// MatchConditions is a list of conditions that must be met for a request to be validated.
|
||||||
|
// Match conditions filter requests that have already been matched by the rules,
|
||||||
|
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
|
||||||
|
// There are a maximum of 64 match conditions allowed.
|
||||||
|
//
|
||||||
|
// If a parameter object is provided, it can be accessed via the `params` handle in the same
|
||||||
|
// manner as validation expressions.
|
||||||
|
//
|
||||||
|
// The exact matching logic is (in order):
|
||||||
|
// 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
|
||||||
|
// 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
|
||||||
|
// 3. If any matchCondition evaluates to an error (but none are FALSE):
|
||||||
|
// - If failurePolicy=Fail, reject the request
|
||||||
|
// - If failurePolicy=Ignore, the policy is skipped
|
||||||
|
//
|
||||||
|
// +patchMergeKey=name
|
||||||
|
// +patchStrategy=merge
|
||||||
|
// +listType=map
|
||||||
|
// +listMapKey=name
|
||||||
|
// +optional
|
||||||
|
MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MatchCondition v1.MatchCondition
|
||||||
|
|
||||||
// ParamKind is a tuple of Group Kind and Version.
|
// ParamKind is a tuple of Group Kind and Version.
|
||||||
// +structType=atomic
|
// +structType=atomic
|
||||||
type ParamKind struct {
|
type ParamKind struct {
|
||||||
|
@ -158,6 +158,7 @@ var map_ValidatingAdmissionPolicySpec = map[string]string{
|
|||||||
"validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
|
"validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
|
||||||
"failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
|
"failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
|
||||||
"auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.",
|
"auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.",
|
||||||
|
"matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
|
func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
|
||||||
|
@ -58,6 +58,22 @@ func (in *ExpressionWarning) DeepCopy() *ExpressionWarning {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *MatchCondition) DeepCopyInto(out *MatchCondition) {
|
||||||
|
*out = *in
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition.
|
||||||
|
func (in *MatchCondition) DeepCopy() *MatchCondition {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(MatchCondition)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *MatchResources) DeepCopyInto(out *MatchResources) {
|
func (in *MatchResources) DeepCopyInto(out *MatchResources) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -360,6 +376,11 @@ func (in *ValidatingAdmissionPolicySpec) DeepCopyInto(out *ValidatingAdmissionPo
|
|||||||
*out = make([]AuditAnnotation, len(*in))
|
*out = make([]AuditAnnotation, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
|
if in.MatchConditions != nil {
|
||||||
|
in, out := &in.MatchConditions, &out.MatchConditions
|
||||||
|
*out = make([]MatchCondition, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,12 @@
|
|||||||
"key": "keyValue",
|
"key": "keyValue",
|
||||||
"valueExpression": "valueExpressionValue"
|
"valueExpression": "valueExpressionValue"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"matchConditions": [
|
||||||
|
{
|
||||||
|
"name": "nameValue",
|
||||||
|
"expression": "expressionValue"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
Binary file not shown.
@ -37,6 +37,9 @@ spec:
|
|||||||
- key: keyValue
|
- key: keyValue
|
||||||
valueExpression: valueExpressionValue
|
valueExpression: valueExpressionValue
|
||||||
failurePolicy: failurePolicyValue
|
failurePolicy: failurePolicyValue
|
||||||
|
matchConditions:
|
||||||
|
- expression: expressionValue
|
||||||
|
name: nameValue
|
||||||
matchConstraints:
|
matchConstraints:
|
||||||
excludeResourceRules:
|
excludeResourceRules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
|
@ -28,8 +28,6 @@ import (
|
|||||||
celgo "github.com/google/cel-go/cel"
|
celgo "github.com/google/cel-go/cel"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
|
||||||
|
|
||||||
admissionv1 "k8s.io/api/admission/v1"
|
admissionv1 "k8s.io/api/admission/v1"
|
||||||
admissionRegistrationv1 "k8s.io/api/admissionregistration/v1"
|
admissionRegistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||||
"k8s.io/api/admissionregistration/v1alpha1"
|
"k8s.io/api/admissionregistration/v1alpha1"
|
||||||
@ -47,6 +45,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/admission/initializer"
|
"k8s.io/apiserver/pkg/admission/initializer"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic"
|
||||||
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
|
||||||
auditinternal "k8s.io/apiserver/pkg/apis/audit"
|
auditinternal "k8s.io/apiserver/pkg/apis/audit"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
@ -57,6 +56,7 @@ import (
|
|||||||
clienttesting "k8s.io/client-go/testing"
|
clienttesting "k8s.io/client-go/testing"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/component-base/featuregate"
|
"k8s.io/component-base/featuregate"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -418,7 +418,7 @@ func setupTestCommon(t *testing.T, compiler cel.FilterCompiler, matcher Matcher,
|
|||||||
// Override compiler used by controller for tests
|
// Override compiler used by controller for tests
|
||||||
controller = handler.evaluator.(*celAdmissionController)
|
controller = handler.evaluator.(*celAdmissionController)
|
||||||
controller.policyController.filterCompiler = compiler
|
controller.policyController.filterCompiler = compiler
|
||||||
controller.policyController.newValidator = func(validationFilter, auditAnnotationFilter, messageFilter cel.Filter, fail *admissionRegistrationv1.FailurePolicyType, authorizer authorizer.Authorizer) Validator {
|
controller.policyController.newValidator = func(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, fail *admissionRegistrationv1.FailurePolicyType, authorizer authorizer.Authorizer) Validator {
|
||||||
f := validationFilter.(*fakeFilter)
|
f := validationFilter.(*fakeFilter)
|
||||||
v := validatorMap[f.keyId]
|
v := validatorMap[f.keyId]
|
||||||
v.validationFilter = f
|
v.validationFilter = f
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
celmetrics "k8s.io/apiserver/pkg/admission/cel"
|
celmetrics "k8s.io/apiserver/pkg/admission/cel"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic"
|
||||||
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
|
||||||
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
@ -99,7 +100,7 @@ type policyController struct {
|
|||||||
authz authorizer.Authorizer
|
authz authorizer.Authorizer
|
||||||
}
|
}
|
||||||
|
|
||||||
type newValidator func(validationFilter cel.Filter, auditAnnotationFilter cel.Filter, messageFilter cel.Filter, failurePolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator
|
type newValidator func(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, failurePolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator
|
||||||
|
|
||||||
func newPolicyController(
|
func newPolicyController(
|
||||||
restMapper meta.RESTMapper,
|
restMapper meta.RESTMapper,
|
||||||
@ -503,11 +504,22 @@ func (c *policyController) latestPolicyData() []policyData {
|
|||||||
}
|
}
|
||||||
optionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: true}
|
optionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: true}
|
||||||
expressionOptionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: false}
|
expressionOptionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: false}
|
||||||
|
failurePolicy := convertv1alpha1FailurePolicyTypeTov1FailurePolicyType(definitionInfo.lastReconciledValue.Spec.FailurePolicy)
|
||||||
|
var matcher matchconditions.Matcher = nil
|
||||||
|
matchConditions := definitionInfo.lastReconciledValue.Spec.MatchConditions
|
||||||
|
if len(matchConditions) > 0 {
|
||||||
|
matchExpressionAccessors := make([]cel.ExpressionAccessor, len(matchConditions))
|
||||||
|
for i := range matchConditions {
|
||||||
|
matchExpressionAccessors[i] = (*matchconditions.MatchCondition)(&matchConditions[i])
|
||||||
|
}
|
||||||
|
matcher = matchconditions.NewMatcher(c.filterCompiler.Compile(matchExpressionAccessors, optionalVars, celconfig.PerCallLimit), c.authz, failurePolicy, "validatingadmissionpolicy", definitionInfo.lastReconciledValue.Name)
|
||||||
|
}
|
||||||
bindingInfo.validator = c.newValidator(
|
bindingInfo.validator = c.newValidator(
|
||||||
c.filterCompiler.Compile(convertv1alpha1Validations(definitionInfo.lastReconciledValue.Spec.Validations), optionalVars, celconfig.PerCallLimit),
|
c.filterCompiler.Compile(convertv1alpha1Validations(definitionInfo.lastReconciledValue.Spec.Validations), optionalVars, celconfig.PerCallLimit),
|
||||||
|
matcher,
|
||||||
c.filterCompiler.Compile(convertv1alpha1AuditAnnotations(definitionInfo.lastReconciledValue.Spec.AuditAnnotations), optionalVars, celconfig.PerCallLimit),
|
c.filterCompiler.Compile(convertv1alpha1AuditAnnotations(definitionInfo.lastReconciledValue.Spec.AuditAnnotations), optionalVars, celconfig.PerCallLimit),
|
||||||
c.filterCompiler.Compile(convertV1Alpha1MessageExpressions(definitionInfo.lastReconciledValue.Spec.Validations), expressionOptionalVars, celconfig.PerCallLimit),
|
c.filterCompiler.Compile(convertV1Alpha1MessageExpressions(definitionInfo.lastReconciledValue.Spec.Validations), expressionOptionalVars, celconfig.PerCallLimit),
|
||||||
convertv1alpha1FailurePolicyTypeTov1FailurePolicyType(definitionInfo.lastReconciledValue.Spec.FailurePolicy),
|
failurePolicy,
|
||||||
c.authz,
|
c.authz,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
||||||
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
|
||||||
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||||
@ -36,6 +37,7 @@ import (
|
|||||||
|
|
||||||
// validator implements the Validator interface
|
// validator implements the Validator interface
|
||||||
type validator struct {
|
type validator struct {
|
||||||
|
celMatcher matchconditions.Matcher
|
||||||
validationFilter cel.Filter
|
validationFilter cel.Filter
|
||||||
auditAnnotationFilter cel.Filter
|
auditAnnotationFilter cel.Filter
|
||||||
messageFilter cel.Filter
|
messageFilter cel.Filter
|
||||||
@ -43,8 +45,9 @@ type validator struct {
|
|||||||
authorizer authorizer.Authorizer
|
authorizer authorizer.Authorizer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewValidator(validationFilter, auditAnnotationFilter, messageFilter cel.Filter, failPolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator {
|
func NewValidator(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, failPolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator {
|
||||||
return &validator{
|
return &validator{
|
||||||
|
celMatcher: celMatcher,
|
||||||
validationFilter: validationFilter,
|
validationFilter: validationFilter,
|
||||||
auditAnnotationFilter: auditAnnotationFilter,
|
auditAnnotationFilter: auditAnnotationFilter,
|
||||||
messageFilter: messageFilter,
|
messageFilter: messageFilter,
|
||||||
@ -77,6 +80,26 @@ func (v *validator) Validate(ctx context.Context, versionedAttr *admission.Versi
|
|||||||
f = *v.failPolicy
|
f = *v.failPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v.celMatcher != nil {
|
||||||
|
matchResults := v.celMatcher.Match(ctx, versionedAttr, versionedParams)
|
||||||
|
if matchResults.Error != nil {
|
||||||
|
return ValidateResult{
|
||||||
|
Decisions: []PolicyDecision{
|
||||||
|
{
|
||||||
|
Action: policyDecisionActionForError(f),
|
||||||
|
Evaluation: EvalError,
|
||||||
|
Message: matchResults.Error.Error(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if preconditions are not met, then do not return any validations
|
||||||
|
if !matchResults.Matches {
|
||||||
|
return ValidateResult{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
optionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams, Authorizer: v.authorizer}
|
optionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams, Authorizer: v.authorizer}
|
||||||
expressionOptionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams}
|
expressionOptionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams}
|
||||||
admissionRequest := cel.CreateAdmissionRequest(versionedAttr.Attributes)
|
admissionRequest := cel.CreateAdmissionRequest(versionedAttr.Attributes)
|
||||||
|
@ -23,16 +23,17 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
celtypes "github.com/google/cel-go/common/types"
|
celtypes "github.com/google/cel-go/common/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
admissionv1 "k8s.io/api/admission/v1"
|
admissionv1 "k8s.io/api/admission/v1"
|
||||||
v1 "k8s.io/api/admissionregistration/v1"
|
v1 "k8s.io/api/admissionregistration/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
"k8s.io/apiserver/pkg/admission/plugin/cel"
|
||||||
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
|
||||||
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
||||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||||
)
|
)
|
||||||
@ -61,6 +62,17 @@ func (f *fakeCelFilter) CompilationErrors() []error {
|
|||||||
return []error{}
|
return []error{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ matchconditions.Matcher = &fakeCELMatcher{}
|
||||||
|
|
||||||
|
type fakeCELMatcher struct {
|
||||||
|
error error
|
||||||
|
matches bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeCELMatcher) Match(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object) matchconditions.MatchResult {
|
||||||
|
return matchconditions.MatchResult{Matches: f.matches, FailedConditionName: "placeholder", Error: f.error}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidate(t *testing.T) {
|
func TestValidate(t *testing.T) {
|
||||||
ignore := v1.Ignore
|
ignore := v1.Ignore
|
||||||
fail := v1.Fail
|
fail := v1.Fail
|
||||||
@ -74,6 +86,7 @@ func TestValidate(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
failPolicy *v1.FailurePolicyType
|
failPolicy *v1.FailurePolicyType
|
||||||
|
matcher matchconditions.Matcher
|
||||||
evaluations []cel.EvaluationResult
|
evaluations []cel.EvaluationResult
|
||||||
messageEvaluations []cel.EvaluationResult
|
messageEvaluations []cel.EvaluationResult
|
||||||
auditEvaluations []cel.EvaluationResult
|
auditEvaluations []cel.EvaluationResult
|
||||||
@ -819,11 +832,46 @@ func TestValidate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
costBudget: 1, // shared between expression and messageExpression, needs 1 + 1 = 2 in total
|
costBudget: 1, // shared between expression and messageExpression, needs 1 + 1 = 2 in total
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "no match surpresses failure",
|
||||||
|
matcher: &fakeCELMatcher{matches: false},
|
||||||
|
evaluations: []cel.EvaluationResult{
|
||||||
|
{
|
||||||
|
Error: errors.New("expected"),
|
||||||
|
ExpressionAccessor: &ValidationCondition{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
policyDecision: []PolicyDecision{},
|
||||||
|
failPolicy: &fail,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "match error => presumed match",
|
||||||
|
matcher: &fakeCELMatcher{matches: true, error: fmt.Errorf("test error")},
|
||||||
|
evaluations: []cel.EvaluationResult{
|
||||||
|
{
|
||||||
|
Error: errors.New("expected"),
|
||||||
|
ExpressionAccessor: &ValidationCondition{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
policyDecision: []PolicyDecision{
|
||||||
|
{
|
||||||
|
Action: ActionDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
failPolicy: &fail,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
var matcher matchconditions.Matcher
|
||||||
|
if tc.matcher == nil {
|
||||||
|
matcher = &fakeCELMatcher{matches: true}
|
||||||
|
} else {
|
||||||
|
matcher = tc.matcher
|
||||||
|
}
|
||||||
v := validator{
|
v := validator{
|
||||||
failPolicy: tc.failPolicy,
|
failPolicy: tc.failPolicy,
|
||||||
|
celMatcher: matcher,
|
||||||
validationFilter: &fakeCelFilter{
|
validationFilter: &fakeCelFilter{
|
||||||
evaluations: tc.evaluations,
|
evaluations: tc.evaluations,
|
||||||
throwError: tc.throwError,
|
throwError: tc.throwError,
|
||||||
@ -884,6 +932,7 @@ func TestContextCanceled(t *testing.T) {
|
|||||||
f := fc.Compile([]cel.ExpressionAccessor{&ValidationCondition{Expression: "[1,2,3,4,5,6,7,8,9,10].map(x, [1,2,3,4,5,6,7,8,9,10].map(y, x*y)) == []"}}, cel.OptionalVariableDeclarations{HasParams: false, HasAuthorizer: false}, celconfig.PerCallLimit)
|
f := fc.Compile([]cel.ExpressionAccessor{&ValidationCondition{Expression: "[1,2,3,4,5,6,7,8,9,10].map(x, [1,2,3,4,5,6,7,8,9,10].map(y, x*y)) == []"}}, cel.OptionalVariableDeclarations{HasParams: false, HasAuthorizer: false}, celconfig.PerCallLimit)
|
||||||
v := validator{
|
v := validator{
|
||||||
failPolicy: &fail,
|
failPolicy: &fail,
|
||||||
|
celMatcher: &fakeCELMatcher{matches: true},
|
||||||
validationFilter: f,
|
validationFilter: f,
|
||||||
messageFilter: f,
|
messageFilter: f,
|
||||||
auditAnnotationFilter: &fakeCelFilter{
|
auditAnnotationFilter: &fakeCelFilter{
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use
|
||||||
|
// with apply.
|
||||||
|
type MatchConditionApplyConfiguration struct {
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Expression *string `json:"expression,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with
|
||||||
|
// apply.
|
||||||
|
func MatchCondition() *MatchConditionApplyConfiguration {
|
||||||
|
return &MatchConditionApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithName sets the Name field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Name field is set to the value of the last call.
|
||||||
|
func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration {
|
||||||
|
b.Name = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithExpression sets the Expression field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Expression field is set to the value of the last call.
|
||||||
|
func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration {
|
||||||
|
b.Expression = &value
|
||||||
|
return b
|
||||||
|
}
|
@ -30,6 +30,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct {
|
|||||||
Validations []ValidationApplyConfiguration `json:"validations,omitempty"`
|
Validations []ValidationApplyConfiguration `json:"validations,omitempty"`
|
||||||
FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"`
|
FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"`
|
||||||
AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"`
|
AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"`
|
||||||
|
MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatingAdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicySpec type for use with
|
// ValidatingAdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicySpec type for use with
|
||||||
@ -87,3 +88,16 @@ func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithAuditAnnotations(v
|
|||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, values provided by each call will be appended to the MatchConditions field.
|
||||||
|
func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration {
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithMatchConditions")
|
||||||
|
}
|
||||||
|
b.MatchConditions = append(b.MatchConditions, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
@ -274,6 +274,17 @@ var schemaYAML = typed.YAMLObject(`types:
|
|||||||
type:
|
type:
|
||||||
scalar: string
|
scalar: string
|
||||||
default: ""
|
default: ""
|
||||||
|
- name: io.k8s.api.admissionregistration.v1alpha1.MatchCondition
|
||||||
|
map:
|
||||||
|
fields:
|
||||||
|
- name: expression
|
||||||
|
type:
|
||||||
|
scalar: string
|
||||||
|
default: ""
|
||||||
|
- name: name
|
||||||
|
type:
|
||||||
|
scalar: string
|
||||||
|
default: ""
|
||||||
- name: io.k8s.api.admissionregistration.v1alpha1.MatchResources
|
- name: io.k8s.api.admissionregistration.v1alpha1.MatchResources
|
||||||
map:
|
map:
|
||||||
fields:
|
fields:
|
||||||
@ -433,6 +444,14 @@ var schemaYAML = typed.YAMLObject(`types:
|
|||||||
- name: failurePolicy
|
- name: failurePolicy
|
||||||
type:
|
type:
|
||||||
scalar: string
|
scalar: string
|
||||||
|
- name: matchConditions
|
||||||
|
type:
|
||||||
|
list:
|
||||||
|
elementType:
|
||||||
|
namedType: io.k8s.api.admissionregistration.v1alpha1.MatchCondition
|
||||||
|
elementRelationship: associative
|
||||||
|
keys:
|
||||||
|
- name
|
||||||
- name: matchConstraints
|
- name: matchConstraints
|
||||||
type:
|
type:
|
||||||
namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources
|
namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources
|
||||||
|
@ -145,6 +145,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
|||||||
return &admissionregistrationv1alpha1.AuditAnnotationApplyConfiguration{}
|
return &admissionregistrationv1alpha1.AuditAnnotationApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("ExpressionWarning"):
|
case v1alpha1.SchemeGroupVersion.WithKind("ExpressionWarning"):
|
||||||
return &admissionregistrationv1alpha1.ExpressionWarningApplyConfiguration{}
|
return &admissionregistrationv1alpha1.ExpressionWarningApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("MatchCondition"):
|
||||||
|
return &admissionregistrationv1alpha1.MatchConditionApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("MatchResources"):
|
case v1alpha1.SchemeGroupVersion.WithKind("MatchResources"):
|
||||||
return &admissionregistrationv1alpha1.MatchResourcesApplyConfiguration{}
|
return &admissionregistrationv1alpha1.MatchResourcesApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("NamedRuleWithOperations"):
|
case v1alpha1.SchemeGroupVersion.WithKind("NamedRuleWithOperations"):
|
||||||
|
Loading…
Reference in New Issue
Block a user