Authenticate with a seeded operator key; fold escalation and switches into TerdutTeam
Credentials: the TerdutServer controller generates <name>-operator-key in the server's own namespace (owned by it) and hands it to the pods as TERDUT_OPERATOR_KEY; the server creates its instance-scoped account from it at every start. A replaced Secret rolls the pods. The bootstrap handshake, the checkpoint Secret, per-team service accounts and credentials Secrets, BootstrapStateLost and credentials.deletionPolicy are gone. CRDs: TerdutServer, TerdutTeam and TerdutAlertSource. TerdutEscalationRule and TerdutDeadmanSwitch become spec.escalation and spec.deadmanSwitches[] on the team (matched by name, extras removed); team invites are removed. A team is created under the identity <namespace>/<name> (external_id), so a retry, a lost status or a deleted team heal by repeating the same call, and a display name owned by another team is TeamNameTaken instead of an adoption. The server resolves escalation usernames (UnknownUser condition). OIDC claim names and trustEmail are spec fields. Fixes: query values are URL-escaped; every delete treats 404 as success; deleting a team no longer depends on allowedTeams consent; a switch or integration deleted on the server is recreated; unnamed switches take the CR's name. Cleanup: scaffold e2e test, AGENTS.md, devcontainer, unused config/ pieces and Client.Version() removed; DESIGN.md, README, ROADMAP and the demo (run-demo.sh, manifests) rewritten for the new design. Secret RBAC stays cluster-wide, now stated in DESIGN.md section 9. Claude-Session: https://claude.ai/code/session_016mBLURvJoMuUEr9cB2RpUN
This commit is contained in:
@@ -1,44 +1,31 @@
|
||||
# Terdut operator
|
||||
|
||||
Aims to expose most config as CRD's, so end users can self-service over gitops.
|
||||
Exposes terdut-server's configuration as Kubernetes objects, so teams can self-service it over
|
||||
gitops. See [DESIGN.md](./DESIGN.md) for the design (read its revision section first: it is the
|
||||
current shape of credentials and the CRD catalog), and [examples/demo](./examples/demo) for a
|
||||
working install.
|
||||
|
||||
See [DESIGN.md](./DESIGN.md) for the full design: CRD catalog and specs,
|
||||
reconciliation semantics, bootstrap/auth, Postgres integration, RBAC, and the
|
||||
relationship to `charts/terdut-server`. This README stays a short pitch; the
|
||||
open questions it used to carry are now resolved decisions there (§2).
|
||||
## CRDs
|
||||
|
||||
## CRD's
|
||||
### TerdutServer
|
||||
A terdut-server install: Deployment, Service, database wiring (a DSN, or a Zalando
|
||||
`postgresClusterRef`), and an operator key Secret it hands to the server so the operator can
|
||||
authenticate. `allowedTeams` consents to `TerdutTeam`s in other namespaces.
|
||||
|
||||
### terdutServers
|
||||
Creates a server — Deployment, Service, database wiring, bootstrap, operator
|
||||
credentials, and `allowedTeams` consent for cross-namespace teams. See
|
||||
DESIGN.md §4.1, §4.6.
|
||||
### TerdutTeam
|
||||
One team on a server, possibly in another namespace (`serverRef`, gated by that server's
|
||||
`allowedTeams`). It carries the team's whole configuration:
|
||||
- `displayName` and OIDC group bindings
|
||||
- `escalation` — the escalation ladder
|
||||
- `deadmanSwitches` — dead man's switches, by name (switches not listed are removed)
|
||||
|
||||
### terdutTeams
|
||||
- team name
|
||||
- oidc groups
|
||||
- `serverRef` — explicit reference to its `TerdutServer`, may be in a
|
||||
different namespace (one team owns the server, others self-service a
|
||||
team against it), gated by that `TerdutServer`'s own `allowedTeams`
|
||||
field (DESIGN.md §2, §4.1, §4.2, §4.6)
|
||||
|
||||
### terdutEscalationrules
|
||||
- rule
|
||||
- `teamRef` — explicit reference to its `TerdutTeam` (DESIGN.md §2, §4.3)
|
||||
|
||||
### terdutDeadmansswitches
|
||||
- rule
|
||||
- `teamRef` (DESIGN.md §4.4)
|
||||
|
||||
### terdutAlertSources
|
||||
- `teamRef` (DESIGN.md §4.5)
|
||||
- URL/key are generated by the server at creation and surfaced only via a
|
||||
generated Secret, never set explicitly
|
||||
### TerdutAlertSource
|
||||
An alert-ingest integration on a team (`teamRef`). The server shows the webhook key once; it is
|
||||
surfaced only through a generated Secret next to the object, never set explicitly.
|
||||
|
||||
## Demo
|
||||
|
||||
[`examples/demo`](./examples/demo) wires one of every CRD above together
|
||||
— two teams, each with an escalation rule, a dead man's switch and an
|
||||
alert source — plus a script that fires synthetic Alertmanager webhooks
|
||||
at it, so you can watch real incidents open, escalate and resolve without
|
||||
a real Alertmanager anywhere in the picture.
|
||||
[`examples/demo`](./examples/demo) wires one of each together — two teams, each with an
|
||||
escalation ladder, a dead man's switch and an alert source — plus a script that fires synthetic
|
||||
Alertmanager webhooks at it, so you can watch incidents open, escalate and resolve without a real
|
||||
Alertmanager.
|
||||
|
||||
Reference in New Issue
Block a user