Commit Graph

6 Commits

Author SHA1 Message Date
unkinben 9c81320df8 BindTSIGKey: add secretTemplate for labels/annotations on the managed Secret
The operator-generated TSIG Secret previously carried only the managed-by
label, so it could not be mirrored to another namespace by emberstack
reflector (which requires reflection-allowed annotations on the source).

Add spec.secretTemplate.{annotations,labels}, applied both when the Secret
is first generated and reconciled onto the existing Secret when the CR
changes (imported secrets are left untouched so we don't fight their
external manager). This lets the external-dns TSIG key be managed in
bind-internal and reflected into the externaldns namespace.
2026-07-20 23:45:41 +10:00
unkinben 53db084c2d Add companion TSIG API and BindTSIGAPI CRD
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
The vault-plugin-secrets-bind-tsig plugin needs an HTTP endpoint that
creates, reads, rotates and deletes TSIG keys on its behalf, decoupling
Vault from direct Kubernetes API access. This adds that companion API and
lets the operator deploy it declaratively.

- Add BindTSIGAPI CRD: creating one makes the operator reconcile a
  Deployment, Service, ConfigMap (env vars), token Secret and namespaced
  RBAC for the companion API. Spec covers image, replicas, port,
  targetNamespace, tokenSecretName, extra env, service exposure and
  resources.
- Generate the master access token Secret only when absent, so a
  VaultStaticSecret may pre-seed/overwrite it; the operator does not own it.
- Add the companion API server (internal/tsigapi): bearer-auth HTTP
  contract POST /v1/keys, GET/DELETE /v1/keys/{name}, POST
  /v1/keys/{name}/rotate, backed by BindTSIGKey custom resources the
  operator reconciles into key material.
- Add cmd/tsigapi entrypoint and Dockerfile.tsigapi (distroless).
- Wire the reconciler into setup, regenerate CRDs/RBAC/deepcopy, and add
  Woodpecker build (PR dry-run) and release (tag push) steps for the
  bind-tsig-api image.
- Cover the API server with auth and key-lifecycle unit tests.
2026-07-11 12:44:13 +10:00
unkinben 28ae6538cb Add a primary (write) Service routing to pod-0
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
Secondaries reject RFC2136/nsupdate writes, but the read Service round-
robins across all pods. Add an optional per-cluster write endpoint that
targets only the primary pod (ordinal 0) via the StatefulSet pod-name
label. Reads keep using the all-pods Service.

- api: BindCluster.spec.primaryService (*ClusterServiceSpec) — ClusterIP
  for in-cluster writers (external-dns) or LoadBalancer for external
- reconcilePrimaryService creates <cluster>-primary selecting pod-0 when
  set, deletes it when unset
- regenerate CRDs + install.yaml
2026-07-04 22:29:55 +10:00
unkinben e0bd3973ed Support externalTrafficPolicy on the client Service
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
Adds BindCluster.spec.service.externalTrafficPolicy so DNS LoadBalancers
can preserve client source IPs (Local), which the source-IP ACLs on the
authoritative/resolver need to actually restrict external clients (Cluster
SNATs everything to node IPs).

- api: ClusterServiceSpec.externalTrafficPolicy (enum Cluster;Local)
- set it on the client Service for LoadBalancer/NodePort types
- regenerate CRDs + install.yaml
2026-07-04 22:15:22 +10:00
unkinben 55e80b467c Add clusterRef to BindTSIGKey
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
TSIG keys were included in every cluster's keys.conf namespace-wide. When
multiple clusters share a namespace, that leaks keys across clusters. Add
spec.clusterRef so a key can target a specific BindCluster; empty keeps
the shared (all-clusters-in-namespace) behaviour.

- api: BindTSIGKey.spec.clusterRef (optional)
- BindCluster keys.conf now includes only keys with matching or empty
  clusterRef
- regenerate CRDs + install.yaml bundle
2026-07-03 23:44:35 +10:00
unkinben 947b45d09f Bundle CRDs into a single install manifest
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
Adds config/crd/install.yaml (all 9 CRDs concatenated) so downstream
GitOps can reference the CRDs by a single stable raw URL instead of
vendoring copies.

- make generate now writes config/crd/install.yaml from config/crd/bases
2026-07-03 18:54:54 +10:00