This repository provides the CLI tool k8s-objects-generator
.
The purpose of this tool is to process the OpenAPI file provided by Kubernetes and generate models for all the types defined inside of it.
The Go models created by this project are compatible with TinyGo and can be serialized and deserialized using the JSON format.
Note: this tool is useless for regular users of Kubewarden. If you just want to use Kubernetes objects inside of a TinyGo program, just consume the files generated by this tool.
You can find them inside of the
github.com/kubewarden/k8s-objects
module.
TinyGo is an alternative Go compiler that can produce WebAssembly code that is not targeting the browser. The official Go compiler isn't capable of that yet. TinyGo is the only option for developers who want to write Go code and build it into a WebAssembly module meant to be run outside of the browser.
TinyGo doesn't yet support the full Go Standard Library, plus it has limited
support of Go reflection.
Because of that, it is not possible to import the official Kubernetes Go library
from upstream (e.g.: k8s.io/api/core/v1
).
Importing these official Kubernetes types will result in a compilation failure.
This section describes how k8s-objects-generator
solves the problems
that prevent the usage of the official Kubernetes Go library with TinyGo.
The Go types defined inside of the official Kubernetes library have a series of methods that perform operations such as validating the object.
These methods are the ones that rely on pieces of the Go Standard Library and on 3rd party libraries that are not compatible with the WebAssembly target.
The good news is that, for the Kubewarden scenario, we don't care about these extra methods. We only need vanilla Go types that all the Kubernetes resources.
The k8s-objects-generator
leverages go-swagger to
process the official swagger.json
file provided by Kubernetes and create
all the models defined inside of it.
These models are created using a custom template of go-swagger that just
writes objects definitions.
However, the models generated by go-swagger include some data types that are not defined by the Go standard library. That includes types to handle base64-encoded bytes and datetime objects.
All these custom data types are provided by the github.com/go-openapi/strfmt
module.
Unfortunately this module includes some dependencies that do not compile when
using TinyGo.
Luckily, these dependencies are required only when implementing the validation methods that we do not care about.
To solve this issue, a stripped down version of the github.com/go-openapi/strfmt
library
has been created here:
github.com/kubewarden/strfmt
.
The go.mod
file generated by k8s-objects-generator
features a replace
directive that substitutes the usage of the github.com/go-openapi/strfmt
with github.com/kubewarden/strfmt
.
By default, swagger generates all the Kubernetes objects inside of the same
Go package.
That means you would end up with more than 560 Go types defined inside of the same
directory and that objects would have names like IoK8sAPICoreV1Pod
or
IoK8sApimachineryPkgApisMetaV1ObjectMeta
.
The k8s-objects-generator
solves this problem by splitting the big swagger file
provided by Kubernetes developers into smaller ones.
The tool creates one swagger file per package. The final code will have the same
package structure of the official Kubernetes Go libraries.
During the split operation, the OpenAPI definitions are partially rewritten to ensure the final objects can resolve each others.
The swagger CLI tool from the go-swagger project must be installed.
Consuming the types generated by this project requires TinyGo 0.28.1 or later.
Warning Using an older version of TinyGo will result in runtime errors due to the limited support for Go reflection.
swagger 0.29.0 or later should be installed
Obtain the
swagger.json
file from Kubernetes upstream repository
Invoke the following command:
k8s-objects-generator -f swagger.json -o ~/k8s-data-types
This command reads the swagger file referenced by the -f
flag and creates all
the files inside of the ~/k8s-data-types
directory.
The output directory provided via the -o
flag will have
the following structure:
~/k8s-data-types
|
\-- src
|
\-- github.com
|
\-- kubewarden
|
\-- k8s-objects
k8s-objects-generator
will invoke the go
binary using ~/k8s-data-types
as exclusive GOPATH
.
That means that, by the end of the process, the output directory will feature also pkg
and other src
directories.
The relevant files are going to be stored inside of the
~/k8s-data-types/src/github.com/kubewarden/k8s-objects
directory. This is the only directory you need to preserve.
Note: the name of the final Git repository can be changed using the
-repo
flag.
Set KUBERNETES_VERSION_MIN
, KUBERNETES_VERSION_MAX
in mass-generate.sh
,
KUBEMINOR
in mass-push.sh
as needed.
Delete and reclone kubewarden/k8s-objects. In my case:
cd suse/kw
rm k8s-objects; git clone git@github.com:kubewarden/k8s-objects.git
Generate all files for all k8s versions, each on its own branch:
./mass-generate.sh -m commit.md --git-dir ~/suse/kw/k8s-objects
Now, push to upstream kubewarden/k8s-objects as needed. You can either push the new branch for the new k8s release (e.g: 1.30):
cd ~/suse/kw/k8s-objects
git push origin release-1.30
git push origin v1.30.0-kw1
Or do a mass push, potentially overwritting old branches:
mv ~/suse/kw/k8s-objects ~/hacking/kubernetes/kubewarden/k8s-objects
./mass-push.sh -m commit.md --git-dir ~/suse/kw/k8s-objects