62 lines
3.9 KiB
Text
62 lines
3.9 KiB
Text
#!/usr/bin/env nu
|
|
# onboard_operator/run.nu — issue NATS JWT, propose + sign delegation patch, verify, audit
|
|
|
|
def main [
|
|
--workspace: string = ""
|
|
--operator-name: string = ""
|
|
--operator-pubkey: string = ""
|
|
--operator-did: string = ""
|
|
--allowed-op-types: string = ""
|
|
--nats-account-url: string = ""
|
|
--dry-run
|
|
]: nothing -> nothing {
|
|
let ws = if ($workspace | is-not-empty) { $workspace } else { $env.PLAYBOOK_PARAM_WORKSPACE? | default "" }
|
|
let op_name = if ($operator_name | is-not-empty) { $operator_name } else { $env.PLAYBOOK_PARAM_OPERATOR_NAME? | default "" }
|
|
let op_pubkey = if ($operator_pubkey | is-not-empty) { $operator_pubkey } else { $env.PLAYBOOK_PARAM_OPERATOR_PUBKEY? | default "" }
|
|
let op_did = if ($operator_did | is-not-empty) { $operator_did } else { $env.PLAYBOOK_PARAM_OPERATOR_DID? | default "" }
|
|
let allowed_ops = if ($allowed_op_types | is-not-empty) { $allowed_op_types } else { $env.PLAYBOOK_PARAM_ALLOWED_OP_TYPES? | default "" }
|
|
let nats_url = if ($nats_account_url | is-not-empty) { $nats_account_url } else { $env.PLAYBOOK_PARAM_NATS_ACCOUNT_URL? | default "" }
|
|
|
|
if ($ws | is-empty) { error make { msg: "workspace is required" } }
|
|
if ($op_name | is-empty) { error make { msg: "operator-name is required" } }
|
|
if ($op_pubkey | is-empty) { error make { msg: "operator-pubkey (path to Ed25519 PEM) is required" } }
|
|
if ($op_did | is-empty) { error make { msg: "operator-did is required" } }
|
|
if ($allowed_ops | is-empty) { error make { msg: "allowed-op-types is required (e.g. deploy,rollback)" } }
|
|
|
|
let playbook_dir = $env.PLAYBOOK_DIR? | default ($env.FILE_PWD | path expand)
|
|
let dry_flag = if $dry_run { "--dry-run" } else { "" }
|
|
|
|
print $"[onboard_operator] workspace=($ws) operator=($op_name) did=($op_did) dry-run=($dry_run)"
|
|
print ""
|
|
|
|
print "[step 1/5] issuing NATS JWT credential..."
|
|
let r1 = do { ^nu ($playbook_dir | path join "steps/issue_nats_credential.nu") --workspace $ws --operator-name $op_name --operator-pubkey $op_pubkey --allowed-op-types $allowed_ops --nats-account-url $nats_url $dry_flag } | complete
|
|
if $r1.exit_code != 0 { error make { msg: $"NATS credential issuance failed: ($r1.stderr | str trim)" } }
|
|
print $r1.stdout
|
|
|
|
print "[step 2/5] proposing delegation addition on policy repo..."
|
|
let r2 = do { ^nu ($playbook_dir | path join "steps/propose_policy_patch.nu") --workspace $ws --operator-name $op_name --operator-did $op_did --allowed-op-types $allowed_ops $dry_flag } | complete
|
|
if $r2.exit_code != 0 { error make { msg: $"Policy patch proposal failed: ($r2.stderr | str trim)" } }
|
|
print $r2.stdout
|
|
|
|
print "[step 3/5] awaiting quorum signatures on policy patch..."
|
|
let r3 = do { ^nu ($playbook_dir | path join "steps/sign_policy_patch.nu") --workspace $ws --operator-name $op_name $dry_flag } | complete
|
|
if $r3.exit_code != 0 { error make { msg: $"Policy patch signing failed: ($r3.stderr | str trim)" } }
|
|
print $r3.stdout
|
|
|
|
print "[step 4/5] verifying new operator credential..."
|
|
let r4 = do { ^nu ($playbook_dir | path join "steps/verify_operator_sign.nu") --workspace $ws --operator-name $op_name $dry_flag } | complete
|
|
if $r4.exit_code != 0 {
|
|
print $" WARNING: operator sign verification failed: ($r4.stderr | str trim)"
|
|
} else {
|
|
print $r4.stdout
|
|
}
|
|
|
|
print "[step 5/5] emitting operator-onboard audit event..."
|
|
let r5 = do { ^nu ($playbook_dir | path join "steps/emit_audit.nu") --workspace $ws --event-type "operator_onboard" --operator-name $op_name --operator-did $op_did $dry_flag } | complete
|
|
if $r5.exit_code != 0 { print $" WARNING: audit emit failed: ($r5.stderr | str trim)" }
|
|
|
|
print ""
|
|
print "[onboard_operator] complete"
|
|
print $"Verify: keeper-cli sign --op test --workspace ($ws) should succeed with new operator credential"
|
|
}
|