Enforce signed backup evidence before migrations

This commit is contained in:
2026-08-03 02:01:13 +02:00
parent 2c515f73c2
commit cbbe08d912
16 changed files with 2157 additions and 52 deletions
+26 -1
View File
@@ -10,6 +10,7 @@ import re
from typing import Any, Mapping
from urllib.parse import urlsplit
from .bundle import BACKUP_RUNTIME_ENV_KEYS
from .model import InstallationSpec, image_is_digest_pinned
@@ -55,6 +56,7 @@ _CONFIG_KEYS = (
"FILE_STORAGE_S3_BUCKET",
"FILE_STORAGE_S3_DEPLOYMENT_MANAGED",
"FILE_STORAGE_S3_ENDPOINT_TRUSTED",
*BACKUP_RUNTIME_ENV_KEYS,
)
_QUEUE_NAME = re.compile(r"^[a-z][a-z0-9_.-]{0,63}$")
@@ -75,6 +77,8 @@ def render_kubernetes(
secret_name: str = "govoplan-runtime",
tls_secret_name: str = "govoplan-tls",
ingress_class_name: str | None = None,
backup_required: bool = True,
backup_evidence: Mapping[str, object] | None = None,
) -> dict[str, Any]:
"""Render runtime roles only; shared state services stay externally managed."""
@@ -199,6 +203,8 @@ def render_kubernetes(
environment,
"MIGRATION",
),
backup_required=backup_required,
backup_evidence=backup_evidence,
),
]
for pool in worker_pools:
@@ -765,9 +771,28 @@ def _migration_job(
secret_name: str,
service_account: str,
database_environment: Mapping[str, str],
backup_required: bool,
backup_evidence: Mapping[str, object] | None,
) -> dict[str, Any]:
job_labels = {**labels, "app.kubernetes.io/component": "migration"}
job_name = _name_with_suffix(name, f"migrate-{release_key}")
backup_annotations = {
"govoplan.add-ideas.de/backup-required": str(backup_required).lower(),
}
if backup_evidence is not None:
backup_annotations.update(
{
"govoplan.add-ideas.de/backup-evidence-sha256": str(
backup_evidence["evidence_sha256"]
),
"govoplan.add-ideas.de/recovery-point": str(
backup_evidence["recovery_point_id"]
),
"govoplan.add-ideas.de/restore-drill": str(
backup_evidence["restore_drill_id"]
),
}
)
return {
"apiVersion": "batch/v1",
"kind": "Job",
@@ -777,7 +802,7 @@ def _migration_job(
"labels": job_labels,
"annotations": {
"govoplan.add-ideas.de/recovery-mode": "forward-recovery",
"govoplan.add-ideas.de/backup-required": "true",
**backup_annotations,
"argocd.argoproj.io/sync-wave": "-1",
},
},