Hi everybody, I'm kumquat! You can configure me to watch Kubernetes resources and generate new resources from them!
Kumquat is KUbernetes Metacontroller QUery And Template.
Kumquat:
- Queries multiple Kubernetes resources.
- Sends the query results to a template engine as the input data.
- Uses a template to generate more Kubernetes resources.
The query and the template are configured in one or more Template
resources that are loaded at run-time.
Kumquat supports the following template languages:
- cue
- gotemplate
- jsonnet (when built with
-tags jsonnet
)
Kubernetes RBAC is powerful, but sometimes it is a bit limited. Imagine you want a ClusterRole
that provides read access to all the Crossplane resources in your cluster that are provided by
the Crossplane AWS providers. Each provider creates resources under a multitude of API groups:
s3.aws.upbound.io
, dynamodb.aws.upbound.io
, etc. Since Kubernetes doesn't support wildcards
in the apiGroups
field of the ClusterRole
, you'll have to list them all manually, and keep
this list up-to-date as new AWS providers are installed.
Kumquat can help! In the following Template
, kumquat queries for all the CRDs in the cluster, and
finds those that end in .aws.upbound.io
. It passes those to a CUE program that finds the set of
unique API group names, and outputs a ClusterRole
with those API groups.
apiVersion: kumquat.guidewire.com/v1beta1
kind: Template
metadata:
name: generate-role
namespace: templates
spec:
query: | #sql
SELECT crd.data AS crd
FROM "CustomResourceDefinition.apiextensions.k8s.io" AS crd
WHERE crd.name LIKE "%.aws.upbound.io"
template:
language: cue
batchModeProcessing: true
data: | #cue
_unique_groups_map: {
for result in DATA {
"\(result.crd.spec.group)": result.crd.spec.group
}
}
_unique_groups: [ for g in _unique_groups_map {g}]
{
apiVersion: "rbac.authorization.k8s.io/v1"
kind: "ClusterRole"
metadata:
name: "crossplane-aws-readers-role"
rules: [
{
apiGroups: _unique_groups
resources: "*"
verbs: ["get", "list", "watch"]
}
]
}
The expected output depends on which Crossplane AWS providers are installed, but should be roughly like this:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: crossplane-aws-readers-role
rules:
- apiGroups:
- dynamodb.aws.upbound.io
- opensearch.aws.upbound.io
- appautoscaling.aws.upbound.io
resources: '*'
verbs:
- get
- list
- watch
Because kumquat is a controller, when new Crossplane AWS providers are installed it will automatically
detect the new CRDs and update the ClusterRole
accordingly.
- PV needing a reference to an external volume and looking it up in a ConfigMap
- The example we use could be a toy example, e.g. hello world, and we could put better examples in an examples directory, with a README to motivate them
You can make all the examples in the examples
folder by running:
go run mage.go examples
This will also compare each example output against the expected output, and acts as a kind of acceptance test in a way.
go build -buildvcs=false -tags jsonnet .
Historic results for the benchmarks are available on the benchmarks page.
- Using SQL with Kubernetes:
- Metacontroller
- jsPolicy; see the Controller policy type.