Since version 1.11 Kubernetes supports validation of custom resource definitions against an OpenAPI version 3
schema. To make these schemata self-contained Kubernetes does not support referencing other components via
the reference object $ref
. But this is often desirable, for example to reference components from the
Kubernetes schema or to consolidate repeated parts inside the schema itself.
To overcome this limitation one solution is to resolve these references before installing the CRD. So this little
script will take a custom resource definition (both v1beta1
and v1
are supported) and will resolve any references.
It uses resolving validator of Prance to do the actual work. Several kinds of
references are supported:
- Local files:
foo/bar/example.json
(relative) and/foo/bar/example.json
(absolute) - URLs:
http://example.com/example.json#/foo/bar
- Python resources:
python://k8s_crd_resolver/schemata/k8s-1.13.4.json#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
Examples are included in the examples
directory. These are taken from the
Ceph OSD Operator project.
To install k8s-crd-resolver
:
pip install git+http://github.com/elemental-lf/k8s-crd-resolver
It is recommended to install k8s-crd-resolver
into a virtual environment. It has only
been tested with Python 3.
To invoke k8s-crd-resolver
simply supply it with a source and destination file:
k8s-crd-resolver $SOURCE_FILE $DESTINATION_FILE
k8s-crd-resolver
is able to read JSON and YAML formatted files and will write a YAML formatted file. Each CRD must
be in its own file. To facilitate the use in pipelines k8s-crd-resolver
will read from standard input if the source
filename is -
. And it will write to standard output if the destination filename is -
.
Kubernetes has a size limit on objects of one megabyte which also affects CRDs. It can easily be reached if the CRD
contains references to other large Kubernetes objects as all attributes in the official schemata are well documented.
k8s-crd-resolver
has a command line option to remove these descriptions to reduce the size of the resulting CRD:
--remove-descriptions
or -r
.
For dealing with validation errors when loading the generated CRDs into certain Kubernetes versions k8s-crd-resolver
supports applying a JSON patch on top of the resolved CRD to fix up these problems. See
kubernetes/kubernetes#91395 and related issues for a discussion of the details.
Example patches for fixing up a CRD containing a reference to the Kubernetes Pod
object:
- This is for a
v1beta1
CRD which references aPod
atspec.podTemplate
:
[
{"op": "remove", "path": "/spec/validation/openAPIV3Schema/properties/spec/properties/podTemplate/properties/spec/properties/initContainers/items/properties/ports/x-kubernetes-list-map-keys"},
{"op": "remove", "path": "/spec/validation/openAPIV3Schema/properties/spec/properties/podTemplate/properties/spec/properties/initContainers/items/properties/ports/x-kubernetes-list-type"},
{"op": "remove", "path": "/spec/validation/openAPIV3Schema/properties/spec/properties/podTemplate/properties/spec/properties/containers/items/properties/ports/x-kubernetes-list-map-keys"},
{"op": "remove", "path": "/spec/validation/openAPIV3Schema/properties/spec/properties/podTemplate/properties/spec/properties/containers/items/properties/ports/x-kubernetes-list-type"}
]
- And this is the same patch for the
v1
version of the same CRD:
[
{"op": "add", "path": "/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplate/properties/spec/properties/initContainers/items/properties/ports/items/properties/protocol/default", "value": "TCP"},
{"op": "add", "path": "/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplate/properties/spec/properties/containers/items/properties/ports/items/properties/protocol/default", "value": "TCP"}
]
See the examples
directory for the complete examples.
k8s-crd-resolver
includes schemata for a range of Kubernetes versions which can directly by used in CRDs
without incurring additional external dependencies:
- Kubernetes 1.12.3 schema :
python://k8s_crd_resolver/schemata/k8s-1.12.3.json
- Kubernetes 1.12.10 schema:
python://k8s_crd_resolver/schemata/k8s-1.12.10.json
- Kubernetes 1.13.4 schema :
python://k8s_crd_resolver/schemata/k8s-1.13.4.json
- Kubernetes 1.13.8 schema :
python://k8s_crd_resolver/schemata/k8s-1.13.8.json
- Kubernetes 1.14.4 schema :
python://k8s_crd_resolver/schemata/k8s-1.14.4.json
- Kubernetes 1.15.3 schema :
python://k8s_crd_resolver/schemata/k8s-1.15.3.json
- Kubernetes 1.16.7 schema :
python://k8s_crd_resolver/schemata/k8s-1.16.7.json
- Kubernetes 1.17.3 schema :
python://k8s_crd_resolver/schemata/k8s-1.17.3.json
- Kubernetes 1.20.7 schema :
python://k8s_crd_resolver/schemata/k8s-1.20.7.json
- Kubernetes 1.21.1 schema :
python://k8s_crd_resolver/schemata/k8s-1.21.1.json
- Kubernetes 1.22.8 schema :
python://k8s_crd_resolver/schemata/k8s-1.22.8.json
- Kubernetes 1.23.5 schema :
python://k8s_crd_resolver/schemata/k8s-1.23.5.json
- Kubernetes 1.24.6 schema :
python://k8s_crd_resolver/schemata/k8s-1.24.6.json
- Kubernetes 1.25.2 schema :
python://k8s_crd_resolver/schemata/k8s-1.25.2.json
But it is also possible to reference external schemata of course. This example directly references a schema in the official Kubernetes repository:
https://raw.githubusercontent.com/kubernetes/kubernetes/v1.15.1/api/openapi-spec/swagger.json
I've found some other projects which do something similar. All of them are written in Go and work directly with the Go data structures.