Schemas#
Schemas are a required part of a CustomResource, and while normally derived automatically, there are numerous ways to customize or override aspects of them.
Generating#
Deriving#
Deriving a schema happens automatically when using #[derive(CustomResource, JsonSchema)]
on a spec struct.
The schema is generated by kube-derive using schemars and our own conformance rewriter for structural schemas.
The CustomResourceDefinition (along with schema(s)) can be extracted through the CustomResourceExt trait.
For an example of what is generated look at examples/crd_derive_schema.
Replacing#
Completely overriding can be done with #[kube(schema = "disabled)]
and hooking in a manual schema string on to each crd.spec.versions[].schema
. An example of this can be found in examples/crd_derive_no_schema.
Doing this allows eliding the #[derive(JsonSchema)]
instruction, which in some cases is your only choice if you do not own the struct.
If you would like to do it more programmatically, and you have partial JsonSchema
coverage, you could fill in the gaps with #[kube(schema = "manual")]
which avoids having to modify the CustomResourceDefinition
. See examples/crd_derive_custom_schema.
Overriding#
Overriding specific parts of a schema can be done using #[schemars(schema_with)]
. Some specific examples:
Versioning#
It is possible to progress between two structs in a versionend manner.
You can define multiple structs within versioned modules ala https://github.com/kube-rs/kube/blob/main/examples/crd_derive_multi.rs and then use merge_crds to combine them.
See CustomResource#versioning, and upstream docs on Versions in CustomResourceDefinitions for more info.
Validation#
Kubernetes >1.25 supports including validation rules in the openapi schema, and there are a couple of ways to include these.
See the Openapi V3 blogpost for more context.
Manual Writing#
This can be done by following upstream docs, and doing manual #overriding.
This way will grant you entry to the 1.25 Common Expression Language feature. Note however, that there are no recommended ways of doing client-side validation with this approach, but there are new cel parser/interpreter crates that might be useful here.
Deriving via Garde#
Using garde is a nice for the simple case because it allows doing both client-side validation, and server-side validation, with the caveat that it only works on both sides for basic validation rules as schemars can only pick up on some of them.