The operator is built with kopf
. It is basically a server that will react to
events coming from Kubernetes. The main event to react to is the deployment of a Custom Resource Definition that
configures OpenWhisk and all the related components.
All the code is in the package nuvolaris
. Events are handled in main.py
.
Each event handlers uses utility functions you can find the various service specific files like openwhisk
or couchdb
.
In general the operator react to events and execute kustomizations.
To develop,
- you start and test writing a base YAML configuration in code;
- you can then modify this base configuration in code using
kustomize
(wrapped in python); - finally you apply the configuration with
kubectl
(wrapped in python).
A good example of how to build a configuration is the following.
Start creating a basic definition under deploy
for example couchdb
. All the utils searches set of deployments under
some folder under deploy
.
Then you can do this (obvious details omitted)
1 kust = kus.secretLiteral("couchdb-auth", user, pasw)
2 kust += kus.patchTemplate("couchdb", "set-attach.yaml", data)
3 spec = kus.kustom_list("couchdb", kust, templates=["couchdb-init.yaml"], data=data)
4 kube.apply(spec)
-
You create a customization to create a secret.
-
there is a customization to create a
patch
for it. There are a few utility functions for that in thenuvolaris.kustomize
package. Some of them are actually templatized (have Template name) so the actual file is generated expanding a template. All templates are undernuvolaris/templates
. A templatized configuration usesJinja2
. When you use templates you also have to provide thedata
dictionary for the templates. -
Once finished you generate a configuration to be applied. Usually it is better to be a series of configuration, hence you invoke
kustom_list
. Note that kustom list, in addition to customize a configuration, can also add more configuration in the form of templates. Specify the templates to use astemplates=templates
and do not forget to providedata=data
to provide data. -
Finally, you apply the configuration with
kube.apply
- there are more utility functions runningkubectl
in a pythonic way.
There are multiple level of testings:
- first test algorithm with unit tests (
task utest
- I use a lot doctest); - then test with integration tests without starting the operator (
task itest
) - tests uses ipython and assertions; - run the operator locally without deploying it (with
task run
) and run taskdeploy
to deploy a test CRD; - deploy in local kind with
task build-and-load
without having to publish it, then execute tests (see theTaskfileTest.yml
file); - finally, test the image build and publish it with
task image-tag ; git push --tags
; wait it builds and test against real kubernetes, using theTaskfile