Writing policies in Go
Go's support for WebAssembly is fast evolving. This page was last revised in December 2023.
The official Go compiler can produce WebAssembly binaries, for execution outside a browser, since v1.21.
There's another Go compiler that can build WebAssembly binaries usable by Kubewarden. This compiler project is TinyGo:
TinyGo brings the Go programming language to embedded systems and to the modern web by creating a new compiler based on LLVM.
You can compile and run TinyGo programs on over 94 different microcontroller boards such as the BBC micro:bit and the Arduino Uno.
TinyGo can also produce WebAssembly (Wasm) code which is very compact in size. You can compile programs for web browsers, as well as for server and edge computing environments that support the WebAssembly System Interface (WASI) family of interfaces.
The Kubewarden project currently suggests using TinyGo for two reasons:
- binaries are smaller
- support for waPC by the ability to export functions to the runtime
TinyGo limitations​
TinyGo doesn't yet support all the Go features,
see the TinyGo language support page
to see the current project status.
Currently, its largest limitation is the lack of a fully supported reflect
package.
This means that official Kubernetes Go API types (e.g.: k8s.io/api/core/v1
) don't compile.
Kubewarden policies need to process JSON data such as policy settings and the request received by Kubernetes.
Despite TinyGo's current limitations, it's still easy to write Kubewarden validation policies with it.
Tooling​
Writing Kubewarden policies requires a version of TinyGo greater than v0.28.1
.
However, use the latest version, for the best results.
Using older versions of TinyGo results in runtime errors due to the limited support for Go reflection.
These Go libraries are useful when writing a Kubewarden policy:
- Kubewarden Go SDK: Provides structures and functions reducing the amount of code necessary. It also provides test helpers.
- Kubernetes Go types: The official Kubernetes Go Types can't be used with TinyGo. This module provides all the Kubernetes Types in a TinyGo-friendly way.
- gjson:
This provides a query language for quick navigation of JSON documents and data retrieval.
This library doesn't use the
encoding/json
package provided by Go'sstdlib
, hence it's usable with TinyGo. - mapset:
Provides a Go implementation of the
Set
data structure.
This library reduces the amount of code to write as operations such as
Set
union
,intersection
,difference
are common operation in Kubewarden policies.
Lastly, the Kubewarden project provides a template Go policy project you can use to create Kubewarden Go policies.
Getting TinyGo dependencies​
The easiest way to get TinyGo is by using the upstream container images. Official releases are here, while builds from the development branch are automatically pushed here.
If needed, try TinyGo's getting started page for more information.
Tutorial prerequisites​
During this tutorial you need these tools on your development machine:
- docker or another container engine: used to build the WebAssembly policy. You'll be using the compiler shipped in the official TinyGo container image.
- bats: used to write the tests and automate their execution.
- kwctl: CLI tool provided by Kubewarden to run its policies outside of Kubernetes, among other actions. It's covered in this section of the documentation.