provisioning-catalog/playbooks/dr_daoshi_lost/run.nu

75 lines
4 KiB
Text
Raw Normal View History

#!/usr/bin/env nu
# dr_daoshi_lost/run.nu — daoshi cluster DR: provision → forgejo restore → CI keys → Radicle reconnect → verify
def main [
--workspace: string = ""
--hetzner-context: string = ""
--wuji-nats-url: string = ""
--ops-vm-host: string = ""
--skip-provision: string = "false"
--dry-run
]: nothing -> nothing {
let ws = if ($workspace | is-not-empty) { $workspace } else { $env.PLAYBOOK_PARAM_WORKSPACE? | default "libre-daoshi" }
let hetzner_ctx = if ($hetzner_context | is-not-empty) { $hetzner_context } else { $env.PLAYBOOK_PARAM_HETZNER_CONTEXT? | default "" }
let wuji_nats = if ($wuji_nats_url | is-not-empty) { $wuji_nats_url } else { $env.PLAYBOOK_PARAM_WUJI_NATS_URL? | default "" }
let vm_host = if ($ops_vm_host | is-not-empty) { $ops_vm_host } else { $env.PLAYBOOK_PARAM_OPS_VM_HOST? | default "" }
let skip_prov = if ($skip_provision | is-not-empty) { $skip_provision } else { $env.PLAYBOOK_PARAM_SKIP_PROVISION? | default "false" }
if ($ws | is-empty) { error make { msg: "workspace is required" } }
if ($vm_host | is-empty) { error make { msg: "ops-vm-host is required" } }
let playbook_dir = $env.PLAYBOOK_DIR? | default ($env.FILE_PWD | path expand)
let dry_flag = if $dry_run { "--dry-run" } else { "" }
print $"[dr_daoshi_lost] workspace=($ws) dry-run=($dry_run)"
print "WARNING: This is a disaster recovery playbook. In-flight builds at time of failure are lost."
print ""
print "[step 1/7] verifying wuji accessibility..."
let r1 = do { ^nu ($playbook_dir | path join "steps/verify_wuji_accessible.nu") --wuji-nats-url $wuji_nats $dry_flag } | complete
if $r1.exit_code != 0 { error make { msg: $"wuji accessibility check failed: ($r1.stderr | str trim)" } }
print $r1.stdout
print "[step 2/7] provisioning new cluster..."
let r2 = do { ^nu ($playbook_dir | path join "steps/provision_new_cluster.nu") --workspace $ws --hetzner-context $hetzner_ctx --skip-provision $skip_prov $dry_flag } | complete
if $r2.exit_code != 0 { error make { msg: $"Cluster provision failed: ($r2.stderr | str trim)" } }
print $r2.stdout
print "[step 3/7] restoring forgejo from Radicle mirrors..."
let r3 = do { ^nu ($playbook_dir | path join "steps/restore_forgejo_from_radicle.nu") --workspace $ws $dry_flag } | complete
if $r3.exit_code != 0 {
print $" WARNING: forgejo restore reported errors: ($r3.stderr | str trim)"
} else {
print $r3.stdout
}
print "[step 4/7] reissuing daoshi-CI NATS JWT..."
let r4 = do { ^nu ($playbook_dir | path join "steps/reissue_ci_keys.nu") --workspace $ws --ops-vm-host $vm_host $dry_flag } | complete
if $r4.exit_code != 0 { error make { msg: $"CI key reissuance failed: ($r4.stderr | str trim)" } }
print $r4.stdout
print "[step 5/7] reconnecting Radicle seed..."
let r5 = do { ^nu ($playbook_dir | path join "steps/reconnect_radicle_seed.nu") --workspace $ws $dry_flag } | complete
if $r5.exit_code != 0 {
print $" WARNING: Radicle reconnect reported errors: ($r5.stderr | str trim)"
} else {
print $r5.stdout
}
print "[step 6/7] verifying CI pipeline..."
let r6 = do { ^nu ($playbook_dir | path join "steps/verify_ci_pipeline.nu") --workspace $ws --wuji-nats-url $wuji_nats $dry_flag } | complete
if $r6.exit_code != 0 {
print $" WARNING: CI pipeline verification failed: ($r6.stderr | str trim)"
} else {
print $r6.stdout
}
print "[step 7/7] emitting dr-daoshi-recovered audit event..."
let r7 = do { ^nu ($playbook_dir | path join "steps/emit_audit.nu") --workspace $ws --event-type "dr_daoshi_recovered" $dry_flag } | complete
if $r7.exit_code != 0 { print $" WARNING: audit emit failed: ($r7.stderr | str trim)" }
print ""
print "[dr_daoshi_lost] recovery complete"
print "Verify: kubectl get pods -n libre-daoshi; nats auth info --account libre-daoshi; woodpecker trigger test build"
}