The tool capi-jsgen
creates json-schemas for cluster-API Clusters which reference a ClusterClass. The primary use-case for these schemas is to create UI-Forms out of it, but they can be used in other contexts as well.
The generic Cluster specification is merged with a ClusterClass to create a specialized version of the Cluster specification. The tailoring takes place by copying the variable schemas from a ClusterClass to the generic Cluster spec. Additional to that, capi-jsgen
can set default values for the ClusterClass, the MachineDeployment class and the namespace. Most likely you do not want certain fields like .status
or .metadata.gereration
in your UI. It is possible to remove or customize this by changing the "base schema". This is the schema that capi-jsgen
works on to create specialized cluster-schemas. If you want to create a custom baseschema have a look at the baseschema-builder it contains a good starting point to create your custom baseschema.
generic cluster-spec
+-----------------------------+
|apiVersion: cluster.x-k8s.io |
|kind: Cluster | specialized cluster-spec
|spec: |----+ +-----------------------------+
| topology: | | |apiVersion: cluster.x-k8s.io |
| variables: <[]Object> | | |kind: Cluster |
+-----------------------------+ | |spec: |
| | topology: |
| | class: example-cc |
+------->| variables: |
| | - name var1 |
specific clusterclass | | schema: sc1 |
+-----------------------------+ | | - name var2 |
|apiVersion: cluster.x-k8s.io | | | schema: sc2 |
|kind: ClusterClass | | +-----------------------------+
|name: example-cc | |
|spec: | |
| variables: |----+
| - name: var1 |
| schema: sc1 |
| - name: var2 |
| schema: sc2 |
+-----------------------------+
Notice that the above graphic recklessly mixes specification (Cluster) and instances (ClusterClass). It is not correct in every detail and only meant to get a quick idea of the concept.
Usage of ./capi-jsgen:
-baseschema string
path to baseschema file (default "data/baseschema.json")
-cache string
Duration how long API-responses are cached (default "1h")
-default-clusterclass
When set, the clusterclass is used as default for .spec.topology.class (default true)
-default-machineclass
When set, the clusterclass name is used as default for .spec.topology.workers.machineDeployments.class (default true)
-default-namespace
When set, the namespace of the clusterclass is used as default for .metadata.namespace (default true)
-listen string
listen address (default ":8080")
-local
run in local mode
-required
only include required variables into the schema
There are two API endpoints that can be consumed. The first one offers information about the namespaces and the offered cluster-classes in the cluster. The second API offers Cluster schemas that are specific for a clusterclass in a namespace.
Kubernetes stores structured objects (resources) in its database. Before saving a new resource to its database, the kubernetes-apiserver validates whether the resource adheres to a certain structure. You can describe the desired structure (schema) for a kubernetes resource using kubectl explain
. If you do so, kubectl
retrieves the corresponding schema from the kubernetes-apiserver under <server>/openapi/v3
. The format of this schema is json-schema, a standard to describe the validity of a structured object. This schema can be used to generate documentation, display a help-text (kubectl explain
), generate a GUI or validate whether an object adheres to the required structure in the schema.
If a resource is validated by the schema this is only a necessary condition for it to be accepted by the kubernetes-apiserver. The schema validation alone is not sufficient to guarantee that the resource is accepted by the kubernetes-apiserver. For example, there can be webhooks that impose additional, stricter requirements upon the structure of the resource.
cluster-API is an extension to the kubernetes-apiserver. It introduces several new resource definitions (CRDs). The purpose of those CRDs is to define the schema of resources that are used to define kubernetes clusters. An important, central schema is called Cluster. It can be used in two ways (simplified):
- manually set all required values
- use a templating mechanism called ClusterClass and only feed variables to customize the output of the template
Both approaches use the same schema. The part in the schema (subschema) that defines the format of the variables is loosely defined. Basically, it accepts arbitrary key-value pairs. This makes sense because this schema has to validate all thinkable instances of Cluster, no matter which variables are used by a ClusterClass or if a ClusterClass is used at all.
The loose definition of the variables makes the generic Cluster schema a bad choice for creating a form or validating if a Cluster adheres to the required variables in a specific ClusterClass. The validation process for a Cluster that uses a ClusterClass is as follows:
- Read the referenced ClusterClass from
.spec.topology.class
from the Cluster resource. - Use the referenced ClusterClass obtained in the prior step to read the variables and their schemas from
.status.variables
- Validate all variables set in the Cluster resource under
.spec.topology.variables
against the variable schemas obtained in the prior step
capi-jsgen
creates a concrete schema out of the generic Cluster schema and the variables of a concrete ClusterClass by embedding the variable schemas of the ClusterClass into the Cluster schema.
- only inline Patches work (no Runtime-SDK support), but configurable behaviour for
definitionsConflict: true
is planned - CEL is not supported, probably as long as it is not part of json-schema
A kubernetes object. Its structure can be validated by its schema.
A description of the structure of an object.
A description of a part of the structure of an object. Part of a schema.