Disallowing additional properties in a Kubernetes CRD schema

89 Views Asked by At

Let's say I have the following CRD:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: examples.tomasaschan.com
spec:
  group: tomasaschan.com
  names:
    kind: Example
    listKind: Examples
    plural: examples
    singular: example
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          properties:
            spec:
              properties:
                foo:
                  type: string
              type: object
          type: object

A valid example object would look like this:

apiVersion: tomasaschan.com/v1
kind: Example
metadata:
  name: example1
spec:
  foo: bar

Now, because foo isn't required, if I misspell it this resource will still be accepted by the API server:

apiVersion: tomasaschan.com/v1
kind: Example
metadata:
  name: example1
spec:
  boo: far

I would like to make it so that this raises a schema validation error.

In JSONSchema, I'd do that by setting additionalProperties: false on the schema.openAPIV3Schema.properties.spec node, but that's not allowed structural CRD schemas (if I try, the API server responds with Forbidden: additionalProperties and properties are mutual exclusive).

This old thread recommends setting spec.preserveUnknownFields: false (on the CRD spec); in more recent Kubernetes versions this is instead accomplished by setting x-kubernetes-preserve-unknown-fields: false on each object node in the schema, but as far as I understand they are otherwise equivalent (modulo the scope they apply to). The effect of that would be the API server dropping the misspelled property, but still happily accepting the resulting config - I want it to return a 400 response with a validation error message that the property boo is unknown.

How do I best accomplish that?

1

There are 1 best solutions below

0
pwoltschk On

The Kubernetes API server's validation mechanism is intended to be tolerant, ignoring unknown fields rather than rejecting them. The schema validation in Kubernetes is based on OpenAPI v3, which is designed to ignore additional properties by default. See https://kubernetes.io/blog/2019/06/20/crd-structural-schema/

As you already stated corretly x-kubernetes-preserve-unknown-fields will not cause an error. And also additionalProperties: false is not possible.

If you really need to achieve this at all cost you can accomplish this by creating a validating admission webhook that checks the resource for unknown properties and rejects the request if any are found. This would involve more complex logic and would need to be maintained separately from the CRD itself. Therefore you need to decide on your own if this works for you.