2026-07-14 00:36:54 +02:00
|
|
|
---
|
|
|
|
|
id: RAILIANCE-WP-0015
|
|
|
|
|
type: workplan
|
|
|
|
|
title: "CNPG backup ScheduledBackup coverage — drive cnpg-backup-status to healthy"
|
|
|
|
|
domain: financials
|
|
|
|
|
repo: railiance-apps
|
2026-07-22 17:53:35 +02:00
|
|
|
status: active
|
2026-07-14 00:36:54 +02:00
|
|
|
owner: codex
|
|
|
|
|
topic_slug: railiance
|
|
|
|
|
created: "2026-07-14"
|
2026-07-22 17:53:35 +02:00
|
|
|
updated: "2026-07-22"
|
2026-07-14 00:38:26 +02:00
|
|
|
state_hub_workstream_id: "1437c98c-e37b-4578-b033-dc3da8ba7870"
|
2026-07-14 00:36:54 +02:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# CNPG backup ScheduledBackup coverage
|
|
|
|
|
|
|
|
|
|
**Parent / origin:** descoped out of `RAIL-HO-WP-0005` (Forgejo Production
|
|
|
|
|
Migration, finished 2026-07-14) T04/T09. The migration is complete; this is the
|
|
|
|
|
residual **DB-backup operational hardening**, not a migration blocker.
|
|
|
|
|
|
|
|
|
|
## Goal
|
|
|
|
|
|
|
|
|
|
Drive `make cnpg-backup-status` (railiance-apps) from **degraded → healthy**:
|
|
|
|
|
scheduled, unattended, encrypted, off-cluster backups with a passing restore
|
|
|
|
|
drill for all four production CNPG clusters — `apps-pg`, `gitea-db`,
|
2026-07-22 17:53:35 +02:00
|
|
|
`net-kingdom-pg`, `state-hub-db` (CoulombCore `databases` namespace).
|
|
|
|
|
|
|
|
|
|
## Current state (2026-07-22)
|
|
|
|
|
|
|
|
|
|
- T01 (CCR-2026-0004 offsite credentials) is **done**: catalog
|
|
|
|
|
`railiance-backup-offsite-lane` is `resolvable: true` / `readiness: ready`;
|
|
|
|
|
OpenBao path holds `NC_WEBDAV_TOKEN`, `NC_WEBDAV_URL`, `AGE_PRIVATE_KEY`;
|
|
|
|
|
OIDC role `railiance-backup-workload-kv-read` grants `read` on the data path
|
|
|
|
|
(verified 2026-07-22, capabilities-safe / key inventory only).
|
|
|
|
|
- `cnpg-backup-status` still reports degraded under the old barman
|
|
|
|
|
`ScheduledBackup` definition; Option A logical-dump schedules are the target.
|
|
|
|
|
- Phase 1 evidence for `apps-pg`/`vergabe_db` exists (RAILIANCE-WP-0013); this
|
|
|
|
|
workplan generalizes to all four clusters with unattended coverage.
|
2026-07-14 00:36:54 +02:00
|
|
|
|
|
|
|
|
## Task: Provision CCR-2026-0004 offsite credentials (operator)
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
id: RAILIANCE-WP-0015-T01
|
2026-07-22 17:53:35 +02:00
|
|
|
status: done
|
2026-07-14 00:36:54 +02:00
|
|
|
priority: high
|
2026-07-22 17:53:35 +02:00
|
|
|
needs_human: false
|
2026-07-14 00:38:26 +02:00
|
|
|
state_hub_task_id: "3df45d8d-39e0-45db-9611-941f066c610a"
|
2026-07-14 00:36:54 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Operator provisions `NC_WEBDAV_TOKEN`, `NC_WEBDAV_URL`, `AGE_PRIVATE_KEY` per
|
|
|
|
|
`CCR-2026-0004` so the lane becomes resolvable. **Done when:**
|
|
|
|
|
`warden access railiance-backup-offsite-lane --fetch NC_WEBDAV_TOKEN` succeeds and
|
|
|
|
|
the CCR flips to `resolvable: true`.
|
|
|
|
|
|
2026-07-22 17:53:35 +02:00
|
|
|
**Closed 2026-07-22:** CCR `resolvable: true`, `readiness: ready`; OIDC login +
|
|
|
|
|
data-path `read` capability + field presence verified without printing values.
|
|
|
|
|
Note: OIDC token cannot `auth/token/create` (403 expected); verify with
|
|
|
|
|
`bao token capabilities` on the current token and/or key inventory, not child
|
|
|
|
|
token minting.
|
|
|
|
|
|
2026-07-14 00:36:54 +02:00
|
|
|
## Task: Create offsite backup Secret in databases namespace
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
id: RAILIANCE-WP-0015-T02
|
2026-07-22 17:53:35 +02:00
|
|
|
status: progress
|
2026-07-14 00:36:54 +02:00
|
|
|
priority: high
|
2026-07-14 00:38:26 +02:00
|
|
|
state_hub_task_id: "7d9b2022-c533-4d49-9a91-fc34ae99aa9a"
|
2026-07-14 00:36:54 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Once T01 resolves, materialize the `databases` namespace Secret from the lane
|
|
|
|
|
(no plaintext in Git — sourced via OpenBao/operator path). **Done when:** the
|
|
|
|
|
Secret exists and `pg_dump`/WebDAV upload authenticates.
|
|
|
|
|
|
|
|
|
|
## Task: Wire scheduled backup for all four CNPG clusters
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
id: RAILIANCE-WP-0015-T03
|
2026-07-22 17:53:35 +02:00
|
|
|
status: progress
|
2026-07-14 00:36:54 +02:00
|
|
|
priority: high
|
2026-07-14 00:38:26 +02:00
|
|
|
state_hub_task_id: "2b97e3ee-6284-4e5f-b56e-df57194cc7b8"
|
2026-07-14 00:36:54 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Implement the decided Option A lane as an unattended schedule for `apps-pg`,
|
|
|
|
|
`gitea-db`, `net-kingdom-pg`, `state-hub-db`: age-encrypted logical dump →
|
|
|
|
|
Nextcloud WebDAV, 14 daily + 4 weekly retention. Uncomment/parameterize
|
|
|
|
|
`manifests/cnpg-backup-readiness.yaml` (or CronJob equivalent). **Done when:**
|
|
|
|
|
each cluster has a running scheduled backup producing encrypted off-cluster
|
|
|
|
|
artifacts without manual intervention.
|
|
|
|
|
|
|
|
|
|
## Task: Reconcile cnpg-backup-status health definition with Option A
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
id: RAILIANCE-WP-0015-T04
|
2026-07-22 17:53:35 +02:00
|
|
|
status: progress
|
2026-07-14 00:36:54 +02:00
|
|
|
priority: medium
|
2026-07-14 00:38:26 +02:00
|
|
|
state_hub_task_id: "151656cb-73ca-4d52-842e-22f14690f71c"
|
2026-07-14 00:36:54 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`cnpg-backup-status.sh` currently reports `degraded` whenever a CNPG-native
|
|
|
|
|
`ScheduledBackup` resource is absent, but the decided approach is logical-dump
|
|
|
|
|
CronJobs, not barman `ScheduledBackup`. Update the health check so a passing
|
|
|
|
|
Option-A schedule reports **healthy** (or adopt barman ObjectStore if chosen
|
|
|
|
|
instead). **Done when:** `make cnpg-backup-status` reflects the real, decided
|
|
|
|
|
posture.
|
|
|
|
|
|
|
|
|
|
## Task: Restore drill + RPO/RTO evidence, mark healthy
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
id: RAILIANCE-WP-0015-T05
|
|
|
|
|
status: wait
|
|
|
|
|
priority: high
|
2026-07-14 00:38:26 +02:00
|
|
|
state_hub_task_id: "59f41267-94a9-45f0-a9d7-3c0cb16689ff"
|
2026-07-14 00:36:54 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Run an isolated-namespace restore drill from a scheduled artifact for at least
|
|
|
|
|
one cluster; record RPO 24h / RTO 4h evidence. **Done when:** `make
|
|
|
|
|
cnpg-backup-status` → **healthy** and restore evidence is recorded.
|