be declared via Custom Resource Definitions (CRDs) • CRDs encode the schema of our API • We want to validate inputs for our API What are we validating actually?
name: in-operator-check namespace: default spec: field: value status: conditions: - status: True type: Ready Type information Entity information identity of a resource Specification (desired state) controlled by the user (producer) Status information controlled by the operator (consumer)
Code Change Necessary? No Validation * No Custom status based validation * Yes OpenAPI Validation GA as 1.8 Yes Complete structural schema GA as of 1.16 Yes Common Expression Language GA as of 1.29 Yes Validating Admission Webhooks * Yes Validating Admission Policies GA as of 1.30 No CRD Ratcheting Beta as of 1.30, enabled by default No
what constraints are allowed No Validation Status based validation $ cat <<EOF | kubectl apply -f - apiVersion: my.domain/v1 kind: StatusBasedValidation metadata: name: in-operator-check spec: foo: 123 EOF Challenge • Validate input field “foo” is a number • Fail validation if field is “invalid”
namespace: default spec: foo: invalid status: conditions: - message: 'The spec is invalid: It must contain a field "foo" of type "int"' reason: InvalidSpec status: "False" type: Ready
Resource is not stored in Kubernetes • Easier GitOps flows • Enhanced UX • Early feedback to the user • “kubectl —dry-run” works Failures after kubectl apply • Invalid resource is stored in Kubernetes • Complex GitOps flows ◦ Need to check status • Worse UX • Late feedback to the user • “kubectl —dry-run” does not work
they reach the Kube API • Validation happens as a Go function(s) • Potentially very powerful and flexible • Useful for more complex data types and validation • Was the primary alternative to OpenAPI validations (until recently) Network call! Network call!
expression evaluation • Extends the current OpenAPI validation • Allows for more complex validation logic than built in OpenAPI validation • Makes use of the new x-kubernetes-validations extension • Can be defined using kubebuilder annotations, to fit nicely into current tooling // +kubebuilder:validation:XValidation:rule=(self.minReplicas <= self.replicas),message=”Replicas must be less than or equal to minimum replicas” …becomes… openAPIV3Schema: type: object properties: spec: type: object x-kubernetes-validations: - rule: "self.minReplicas <= self.replicas" - message: "Replicas must be less than or equal to minimum replicas"
oldSelf… // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" Use built in functions for more complex rules… // +kubebuilder:validation:XValidation:rule="oldSelf.all(x, x in self)",message="Values may only be added" … or combine them for even more complex cases! // +kubebuilder:validation:XValidation:rule=”self.envars.filter(e, e.name == 'MY_ENV').all(e, e.value.matches('^[a-zA-Z]*$')”,message=”” Extend the Kubernetes API with CustomResourceDefinitions: Validation Rules CRD Validation - The Kubebuilder Book Google CEL Specification
as a YAML resource, so can be included in an existing CRD bundle • Can be written and shared by Operator developers and users Spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments"] Validations: - expression: "object.spec.replicas <= params.maxReplicas" messageExpression: "'object.spec.replicas must be no greater than ' + string(params.maxReplicas)" reason: Invalid # Determines the HTTP Response Code Validating Admission Policy | Kubernetes
on an invalid resource, provided the change did not affect the invalid fields. ◦ “any invalid part of the resource that remains invalid must have already been wrong” • This means we can enforce or even tighten validation going forward, without breaking current configurations. • While this is not validation in itself, it makes implementing and improving validation much easier. • CRD Ratcheting is not supported for all validations; some will continue to error on update as usual, including required and any use of oldSelf.