KCL Operator provides cluster integration, allowing you to use Access Webhook to generate, mutate, or validate resources based on KCL configuration when apply resources to the cluster. Webhook will capture creation, application, and editing operations, and execute KCLRun on the configuration associated with each operation, and the KCL programming language can be used to
- Add labels or annotations based on a condition.
- Inject a sidecar container in all KRM resources that contain a
PodTemplate. - Validate all KRM resources using KCL schema.
- Use an abstract model to generate KRM resources.
- Install Go 1.23+
- Install Kubectl and Kustomize
- Install Operator SDK
- Prepare a Kubernetes Cluster e.g., K3d
Run make help to get the help.
- Deploy the KCL Operator.
make deployUse the following command to watch and wait for the pod status is Running.
kubectl get po- Deploy the KCL source
kubectl apply -f- << EOF
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: set-annotation
spec:
params:
annotations:
managed-by: kcl-operator
source: oci://ghcr.io/kcl-lang/set-annotation
EOF- Validate the mutation result by creating a nginx Pod YAML.
kubectl apply -f- << EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx
annotations:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
EOF
kubectl get po nginx -o yaml | grep kcl-operatorThe output is
managed-by: kcl-operatorWe can find the annotation managed-by=kcl-operator is added on the pod.
Here's what you can do in the KCL script:
- Read resources from
option("resource_list"). Theoption("resource_list")complies with the KRM Functions Specification. You can read the input resources fromoption("items")and theparamsfromoption("params"). - Return an error using
assert {condition}, {error_message}. - Log variable values using the function
print(variable)and it will be output to the stdout of the pod. - Read the PATH variables. e.g.
option("PATH"). - Read the environment variables. e.g.
option("env").
option("items") is the resource the webhook mutates. On CREATE and UPDATE that is the admission object.
On UPDATE the API server also sends oldObject. The webhook copies both onto the KCLRun document that is fed to KCL, under spec.admission. The KCLRun stored in the cluster is unchanged, and option("items") is still only the resource to mutate.
option("resource_list").functionConfig.spec.admission.object— admissionobjectoption("resource_list").functionConfig.spec.admission.oldObject— admissionoldObject
With more than one KCLRun in the namespace, each program sees the same original pair. option("items") is the output of the previous program.
The API server sends oldObject for webhooks registered on UPDATE. The sample mutating webhook configuration registers CREATE only; add UPDATE to the webhook rules to receive oldObject.
item = option("items")[0]
old = option("resource_list").functionConfig.spec.admission.oldObject
items = [item | {
metadata.annotations: {"previous-image" = old.spec.containers[0].image}
}]A KRM YAML list means that each document must have an apiVersion, kind through the items field or a single YAML output.
- Using the
itemsfield
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: basic
spec:
source: |
items = [{
apiVersion: "v1"
kind: "Foo"
metadata.name = "foo"
}, {
apiVersion: "v1"
kind: "Bar"
metadata.name = "bar"
}]- Single YAML output
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: basic
spec:
source: |
{
apiVersion: "v1"
kind: "Foo"
metadata.name = "foo"
}You can directly use KCL standard libraries such as regex.match, math.log.
See here to study more features of KCL.
See here for more examples.
