Skip to content

feat(operator): the Kates operator, reconcilers, chart and publishing - #614

Merged
bmscomp merged 6 commits into
mainfrom
operator
Nov 6, 2026
Merged

bmscomp merged 6 commits into
mainfrom
operator

Conversation

@bmscomp

@bmscomp bmscomp commented Nov 5, 2026

Copy link
Copy Markdown
Owner

Why

Kates has no declarative, per-namespace way to run a test or a compliance check. operator/ on main is only the workspace and the KatesTest CRD. This brings the working operator: an API-backed controller that drives a Kates API already running, and never installs one.

Merging this reverses the standalone decision of 2026-11-05 only in part: the code lands on main, but it still touches no kates/, cli/, charts/ or release.yml. Nothing outside operator/ changes except the two workflows below.

What

  • KatesTest and KafkaCompliance reconcilers, kates-client, leader election, metrics, the crds apply hook.
  • operator/chart: own namespace, some namespaces, every namespace, and no cluster-scoped rights. It stays out of charts/, so publish-charts.yml and the chart version gates never see it.
  • publish-operator.yml: an operator-v* tag builds amd64 and arm64 and pushes the image and chart to GHCR, signed with cosign. operator-v0.1.0 is out, and operator-v0.1.1 carries the tenant bounds.
  • Tenant bounds: interval capped at a year, answers at 8 MiB, the client cache at 256, the CRD hook's get, create and patch scoped to the two Kates CRDs.
  • ci-operator.yml: CRDs generated into operator/chart/crds, and a push trigger on operator.

Deliberately not done

  • No kates deploy --with-operator, no book chapter, no KatesSchedule or KatesDisruption: the chart README has a CronJob recipe instead.
  • Fail-over, install modes, the upgrade hook and the Kafka change trigger were checked by hand, not in e2e.sh.
  • OpenShift: the fixed runAsUser: 65532 is probably refused by restricted-v2. Not tested, nor is EKS, GKE or AKS.

Known limit

In per-namespace mode, kubectl delete namespace with a live KatesTest hangs, because the operator's RoleBinding goes with the namespace. The chart README has the patch.

Tests

Rust: fmt, clippy, tests, cargo-deny. e2e.sh green on kind with Kates 1.38.0 and Strimzi, the CronJob recipe run from the README, and the published 0.1.0 chart installed on k3d with no local image.

…election

kates-client classifies every answer of the Kates API; KatesTest and
KafkaCompliance reconcile on it, with their decisions in plain functions over
the status. The binary takes the Lease, holds off on a stale CRD, and runs one
controller per watched namespace. CRDs move to operator/chart/crds: the
operator stays self-contained and nothing under charts/ learns about it.
…twork errors

operator/chart holds the Deployment, the three install modes and the
no-cluster-rights mode, leader-election RBAC, the crds apply hook,
NetworkPolicy, PodMonitor, aggregated roles and a values schema. It stays out
of charts/, so nothing publishes it. operator/e2e.sh runs the plan's outcomes
against a real Kates and Kafka.
…CronJob recipe

ci-operator.yml now runs on pushes to operator. cargo-deny failed on the
path dependencies, so deny.toml allows wildcard paths; the crates are
unpublished. e2e.sh covers KafkaCompliance and takes the Kafka namespace
and name. The chart README gains the schedule recipe that stands in for a
KatesSchedule kind.
The chart's default image never existed, so an install failed at the CRD
hook on every cluster but one with a loaded image. publish-operator.yml
builds amd64 and arm64 on native runners, then pushes and signs the image
and the chart on GHCR. It runs from its own tag, so a Kates release never
sees it. The chart README installs from the registry.
A huge KafkaCompliance interval could reach an expect, so it is capped at
a year. A kates-connection can name any host, so an answer is capped at
8 MiB, under the pod's 128 Mi limit, and the client cache at 256 entries.
The CRD hook's get, create and patch name the two Kates CRDs. The key goes
through bearer_auth, which marks the header sensitive. Chart 0.1.1.
CI only asked the apiserver to accept the CRDs, so a reconciler regression
passed. The Kind job now builds the operator image and runs e2e.sh on the
one-broker stack e2e-stack.sh deploys, which a scratch cluster uses too.
@bmscomp
bmscomp merged commit 3420856 into main Nov 6, 2026
65 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant