Skip to main content

knete

knete logo

A lightweight Python framework for building Kubernetes controllers and admission webhooks.

Features

  • Controllers — watch any Kubernetes resource and react to create/update/delete events
  • Validating webhooks — reject requests that violate policy
  • Mutating webhooks — patch objects on the way in
  • Composite mutating webhooks — fan-out multiple mutators to a single endpoint, accumulating all patches in one round-trip
  • Decorator-style webhooks — register plain functions instead of subclasses
  • Manifest generatorpython -m knete <file.py> generates all k8s manifests (Deployment, Service, RBAC, WebhookConfigurations) including cert-manager TLS support

Installation

pip install knete

Quick start

Controller

from knete import Controller, Manager

class PodController(Controller):
    class Meta:
        resource  = "v1/pods"
        namespace = "default"

    def on_create(self, name, namespace, labels, spec):
        print(f"Pod created: {namespace}/{name}")

    def on_delete(self, name):
        print(f"Pod deleted: {name}")

Manager().register(PodController).start()

Validating webhook

from knete import ValidatingWebhook, AdmissionResponse, WebhookServer

class NoLatestTagWebhook(ValidatingWebhook):
    class Meta:
        resource   = "apps/v1/deployments"
        operations = ["CREATE", "UPDATE"]
        name       = "no-latest-tag"

    def validate(self, name, spec) -> AdmissionResponse:
        for c in spec.get("template", {}).get("spec", {}).get("containers", []):
            if c["image"].endswith(":latest") or ":" not in c["image"]:
                return AdmissionResponse.deny(f"image {c['image']!r} uses :latest tag")
        return AdmissionResponse.allow()

server = WebhookServer(cert_file="tls.crt", key_file="tls.key")
server.register(NoLatestTagWebhook)
server.start()

Mutating webhook

from knete import MutatingWebhook, AdmissionResponse

class InjectLabelWebhook(MutatingWebhook):
    class Meta:
        resource   = "v1/pods"
        operations = ["CREATE"]
        name       = "inject-label"

    def mutate(self, labels) -> AdmissionResponse:
        if "managed-by" in labels:
            return AdmissionResponse.allow()
        return AdmissionResponse.patch([
            {"op": "add", "path": "/metadata/labels/managed-by", "value": "knete"},
        ])

Multiple validators

Register each validating webhook separately — Kubernetes calls them in parallel, so total latency is max(validators) rather than sum(validators):

server.register(NoLatestTagWebhook)     # POST /validate/no-latest-tag
server.register(RequiredLabelsWebhook)  # POST /validate/required-labels

Decorator style

Skip the class entirely and register plain functions directly on the server:

server = WebhookServer(cert_file="tls.crt", key_file="tls.key")

@server.validate("apps/v1/deployments", operations=["CREATE", "UPDATE"], name="no-latest-tag")
def no_latest_tag(name, spec) -> AdmissionResponse:
    for c in spec.get("template", {}).get("spec", {}).get("containers", []):
        if c["image"].endswith(":latest") or ":" not in c["image"]:
            return AdmissionResponse.deny(f"image {c['image']!r} uses :latest tag")

@server.mutate("v1/pods", operations=["CREATE"], name="inject-label")
def inject_label(labels) -> AdmissionResponse:
    if "managed-by" not in labels:
        return AdmissionResponse.patch([
            {"op": "add", "path": "/metadata/labels/managed-by", "value": "knete"},
        ])

server.start()

Both styles can be mixed freely. name defaults to the function name if omitted.

Manifest generator

Generate all Kubernetes manifests for your operator or webhook server:

# Operator
python -m knete examples/my_operator.py --name my-operator --image my-operator:v1

# Webhook with cert-manager TLS (generates a self-signed ClusterIssuer)
python -m knete examples/my_webhook.py --name my-webhook --image my-webhook:v1 --cert-manager

# Webhook using an existing ClusterIssuer
python -m knete examples/my_webhook.py --name my-webhook --image my-webhook:v1 --cert-manager my-issuer

This writes k8s/ manifests and a Containerfile ready to build. Apply with:

kubectl apply -f k8s/

Examples

File What it shows
examples/webhook_example.py Validating + mutating + composite mutating webhooks
examples/forbid_reserved_prefixes_decorator.py Decorator-style validating + mutating webhooks
examples/example.py Basic pod controller
examples/kyverno_clusterrolebinding.py Controller equivalent of a Kyverno generate rule
examples/kyverno_clusterrolebinding_webhook.py Same policy as a mutating webhook with side-effects

Requirements

  • Python 3.10+
  • cert-manager (optional, for webhook TLS)

Release files for knete 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for knete 0.1.0
File Size Uploaded
knete-0.1.0.tar.gz 2.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for knete 0.1.0
File Interpreter ABI Platform
knete-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.4 MB

Release files / knete-0.1.0.tar.gz

Download URL knete-0.1.0.tar.gz
Size 2.3 MB
Tags Source
SHA-256 checksum
How to use checksums
cd3c98826838e2bdc32f73471039be9b31380905fe1abf4336403480edc8d719
BLAKE2b-256 checksum
How to use checksums
6a34a9b3fb5dabc08b13395346015f32eaa6f1ddec9cfc285893fb92d479eff5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / knete-0.1.0-py3-none-any.whl

Download URL knete-0.1.0-py3-none-any.whl
Size 20.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
96b05fe45d2f853d654bfb2b91d05ac6bce0c1bcc3275439615df16bc144966b
BLAKE2b-256 checksum
How to use checksums
3bb5732d76fd467286b0748cbc158af179ff52e6052d0dbc2e753240deaf5bd9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page