Skip to content

Add provisioning controller and REST API for managed warehouses#332

Draft
EDsCODE wants to merge 1 commit intomainfrom
eric/provisioning-controller
Draft

Add provisioning controller and REST API for managed warehouses#332
EDsCODE wants to merge 1 commit intomainfrom
eric/provisioning-controller

Conversation

@EDsCODE
Copy link
Contributor

@EDsCODE EDsCODE commented Mar 19, 2026

Summary

  • Provisioning controller that reconciles Duckling CRs via K8s dynamic client (pending→provisioning→ready, deleting→deleted)
  • Production-facing REST API on separate port (:9091) with POST /teams/:id/provision, POST /teams/:id/deprovision, GET /teams/:id/warehouse
  • Config store model additions (Image, AuroraMinACU, AuroraMaxACU) and new methods (ListWarehousesByStates, UpdateWarehouseState with CAS)
  • Team router gates stack creation on warehouse readiness and uses per-team namespace/SA
  • Separate --provisioning-token and --provisioning-port config
  • Teams auto-created on first provision call

Companion PR

Test plan

  • Unit tests: fake K8s dynamic client, all state transitions, CAS updates
  • Provisioning API tests: provision, deprovision, retry after failure, auto-create team
  • Local QA: OrbStack K8s + mock Duckling CRD, full provision→ready→deprovision flow triggered from PostHog UI
  • Build: go build -tags kubernetes ./... and go build ./...

🤖 Generated with Claude Code

Adds end-to-end provisioning flow: PostHog calls a REST API to initiate
provisioning, the controller drives Crossplane via Duckling CRs to create
per-team AWS resources (Aurora, S3, IAM), and updates the config store as
resources come up. The team router gates worker stack creation on warehouse
readiness and uses per-team namespace/SA from the warehouse config.

New packages:
- controlplane/provisioner: reconciliation loop + K8s dynamic client for
  Duckling CRs (pending→provisioning→ready, deleting→deleted, failure handling)
- controlplane/provisioning: production-facing REST API on separate port
  (POST /teams/:id/provision, POST /teams/:id/deprovision, GET /teams/:id/warehouse)

Key design decisions:
- Provisioning API runs on separate port (:9091) from admin (:9090)
- Separate bearer token (--provisioning-token) for provisioning vs admin
- Controller uses WarehouseStore interface for testability
- CAS (compare-and-swap) updates prevent state races
- Synced=False tolerance (5min grace period) for Crossplane transients
- Teams are auto-created on first provision call
- Non-K8s builds get stub (provisioning package has no build tag)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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