Kubernetes operator for multi-cluster resource brokering. Kubebuilder v4, multigroup layout. Built on sigs.k8s.io/multicluster-runtime.
Read the org-wide AGENTS.md for general conventions. Read CONTRIBUTING.md for contribution workflow.
make check— codegen + lint + test + test-e2e (CI gate)make test— unit testsmake test TEST_ARGS="-run TestName"— single unit testmake test-e2e— e2e tests (uses envtest)make test-e2e TEST_ARGS="-run TestName"— single e2e testmake codegen— regenerate CRDs, RBAC, DeepCopy from API typesmake lint/make lint-fix— golangci-lint v2make build— build broker binarymake build-operator— build operator binarymake run— run broker locally (debug logging)make run-operator— run operator locally (debug logging)make examples— run all example walkthroughsmake help— list all targets
api/ CRD types, grouped by domain
broker/ AcceptAPI, Migration, MigrationConfiguration
generic/ Cross-cloud APIs (databases, networking, storage, compute, etc.)
example/ Example CRDs (Certificate, VM)
operator/ Broker operator CRD
cmd/ Entrypoints
main.go resource-broker
operator/ resource-broker-operator
pkg/ Core logic
broker/ Reconcilers (acceptapi, generic, migration)
sync/ Resource copy and condition tracking
conditions/ Status condition utilities
kubernetes/ Annotation and map helpers
config/ Kustomize manifests (CRDs, RBAC, deployment)
test/ E2e tests and test utilities
examples/ Runnable walkthroughs (certs, kcp-certs, platform-mesh)
contrib/kcp/ kcp-specific Dockerfile and config
Three cluster roles: coordination, consumer, provider. Two separate binaries: operator (single-cluster, manages Broker CRD, deploys broker) and broker manager (multi-cluster, runs reconcilers).
- Consumer resource created → consumer watch triggers GenericReconciler
decorateInConsumer()adds finalizer + annotationsproviderAcceptsObj()queries AcceptAPI registry (in-memory map protected by lock)- Resource copied to provider with hashed cluster prefix in name (
SanitizeClusterName()→ 12-char hex) to avoid multi-consumer collisions - Provider watch triggers via
providerEventHandlerwhich maps back to consumer using annotations - Status synced back to consumer via status subresource, with prefixes stripped by
StatusTransformer - Related resources (declared in
status.relatedResources) copied to consumer with owner references
If AcceptAPI no longer matches, reconciler sets new-provider-cluster annotation, syncs to new provider, waits for readiness, then deletes from old provider.
Staged state machine: Unknown → Pending → InitialInProgress → InitialCompleted → CutoverInProgress → CutoverCompleted. Each stage deploys template resources and evaluates CEL expressions against them before progressing.
broker.platform-mesh.io/consumer-cluster,consumer-name— origin trackingbroker.platform-mesh.io/provider-cluster— current providerbroker.platform-mesh.io/new-provider-cluster— migration target
- Cluster prefixes:
consumer,provider,coordination(pkg/broker/broker.go) - Finalizers:
broker.platform-mesh.io/acceptapi-finalizer,broker.platform-mesh.io/generic-finalizer - AcceptAPI filters: ValueIn (enum), Boundary (min/max), Suffix (string suffix) — keys use dot notation for nested spec fields
Tests: testify (require/assert). E2e: controller-runtime envtest.
Run make codegen after any change to api/ types. Run make lint-fix before committing.
Conventional Commits: feat:, fix:, chore(deps):, ci:, refactor:, test:, docs:
Never add AI attribution to commits or PRs.
- Edit
zz_generated.deepcopy.go— generated by controller-gen - Edit
config/*/crd/*.yamldirectly — generated bymake manifests - Add tool-specific instruction files (
CLAUDE.md,.cursorrules, etc.) — use this file - Commit without running
make codegenafter API type changes