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,8 +0,0 @@
|
||||
## Append samples of your project ##
|
||||
resources:
|
||||
- terdut_v1alpha1_terdutserver.yaml
|
||||
- terdut_v1alpha1_terdutteam.yaml
|
||||
- terdut_v1alpha1_terdutescalationrule.yaml
|
||||
- terdut_v1alpha1_terdutdeadmanswitch.yaml
|
||||
- terdut_v1alpha1_terdutalertsource.yaml
|
||||
# +kubebuilder:scaffold:manifestskustomizesamples
|
||||
@@ -1,19 +0,0 @@
|
||||
apiVersion: terdut.ryuvia.com/v1alpha1
|
||||
kind: TerdutAlertSource
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: terdut-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: terdutalertsource-sample
|
||||
spec:
|
||||
teamRef:
|
||||
name: terdutteam-sample
|
||||
# kind defaults to "alertmanager" -- the only value terdut-server
|
||||
# supports today. Changing it after this object exists rotates the
|
||||
# webhook key (DESIGN.md §5): the old integration is deleted and a new
|
||||
# one created, which breaks whatever still sends to the old URL.
|
||||
kind: alertmanager
|
||||
# name is this source's own display name server-side, distinct from this
|
||||
# object's own metadata.name above -- renaming it is safe and never
|
||||
# rotates the key.
|
||||
name: prod-alertmanager
|
||||
@@ -1,15 +0,0 @@
|
||||
apiVersion: terdut.ryuvia.com/v1alpha1
|
||||
kind: TerdutDeadmanSwitch
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: terdut-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: terdutdeadmanswitch-sample
|
||||
spec:
|
||||
teamRef:
|
||||
name: terdutteam-sample
|
||||
# name is optional -- left empty, terdut-server derives it from matcher's
|
||||
# own canonical form (DESIGN.md §4.4).
|
||||
matcher: "alertname=Watchdog"
|
||||
timeout: 15m
|
||||
severity: critical
|
||||
@@ -1,25 +0,0 @@
|
||||
apiVersion: terdut.ryuvia.com/v1alpha1
|
||||
kind: TerdutEscalationRule
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: terdut-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: terdutescalationrule-sample
|
||||
spec:
|
||||
# One per team (DESIGN.md §4.3) -- a second TerdutEscalationRule naming
|
||||
# the same teamRef would simply clobber this one every reconcile, since
|
||||
# there's no admission-time check for it in v1.
|
||||
teamRef:
|
||||
name: terdutteam-sample
|
||||
repeatCount: 2
|
||||
fallbackTopic: platform-fallback
|
||||
levels:
|
||||
# username is required iff kind is "user", and rejected otherwise --
|
||||
# enforced at apply time via CEL (api/v1alpha1/terdutescalationrule_types.go).
|
||||
- timeout: 5m
|
||||
targets:
|
||||
- kind: user
|
||||
username: alice
|
||||
- timeout: 10m
|
||||
targets:
|
||||
- kind: oncall
|
||||
@@ -1,42 +0,0 @@
|
||||
apiVersion: terdut.ryuvia.com/v1alpha1
|
||||
kind: TerdutServer
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: terdut-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: terdutserver-sample
|
||||
spec:
|
||||
image:
|
||||
repository: git.ryuvia.com/niklas/terdut-server
|
||||
tag: v0.20.0
|
||||
replicas: 1
|
||||
networking:
|
||||
hostname: terdut.example.com
|
||||
servicePort: 8080
|
||||
# Bring-your-own DSN (simplest path, no external CRD dependency). For the
|
||||
# Zalando postgres-operator path instead, use:
|
||||
# database:
|
||||
# postgresClusterRef:
|
||||
# name: terdut-postgres
|
||||
database:
|
||||
dsn: "postgres://terdut@terdut-postgres:5432/terdut?sslmode=require"
|
||||
passwordSecretRef:
|
||||
name: terdut-postgres-password
|
||||
key: password
|
||||
sweeper:
|
||||
staleAfter: 6h
|
||||
archiveAfter: 168h
|
||||
deadman:
|
||||
matchers: "alertname=Watchdog"
|
||||
timeout: 15m
|
||||
severity: critical
|
||||
passwordLogin: true
|
||||
# Pod-level customization, all optional -- see PodSpec in
|
||||
# api/v1alpha1/terdutserver_types.go for the full shape (tolerations,
|
||||
# affinity, topologySpreadConstraints, securityContext,
|
||||
# serviceAccountName, extraEnv/extraVolumes, imagePullSecrets,
|
||||
# disruptionBudget, ...). Example:
|
||||
# pod:
|
||||
# resources:
|
||||
# requests: {cpu: 100m, memory: 128Mi}
|
||||
# limits: {memory: 256Mi}
|
||||
@@ -1,20 +0,0 @@
|
||||
apiVersion: terdut.ryuvia.com/v1alpha1
|
||||
kind: TerdutTeam
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: terdut-operator
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: terdutteam-sample
|
||||
spec:
|
||||
# serverRef.namespace is optional, defaulting to this TerdutTeam's own
|
||||
# namespace (the common case). Set it only to reference a TerdutServer in
|
||||
# a different namespace -- which needs that TerdutServer's own
|
||||
# spec.allowedTeams to admit this namespace (DESIGN.md §4.6), otherwise
|
||||
# this reports Ready: False, reason: RefNotPermitted.
|
||||
serverRef:
|
||||
name: terdutserver-sample
|
||||
displayName: Platform
|
||||
# oidc is optional -- omit entirely for a password-login-only install.
|
||||
# oidc:
|
||||
# memberGroup: terdut-platform-members
|
||||
# ownerGroup: terdut-platform-owners
|
||||
Reference in New Issue
Block a user