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.
Technical details
This section describes how k8s-objects-generator
solves the problems
that prevent the usage of the official Kubernetes Go library with TinyGo.
Solving the compilation errors
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
.
Solving the "flat" package problem
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.
Requirements
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
Usage
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.
Output directory layout
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.