fix: [nomad-step-2] S2.5 — bin/disinto init --import-env / --import-sops / --age-key wire-up (#883) #907
3 changed files with 67 additions and 4 deletions
38
bin/disinto
38
bin/disinto
|
|
@ -684,13 +684,21 @@ _disinto_init_nomad() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Step 2/3/4 scripts must exist as soon as any --import-* flag is set,
|
||||
# since we unconditionally invoke policies+auth and optionally import.
|
||||
# --empty short-circuits after cluster-up: no policies, no auth, no
|
||||
# import, no deploy. It's the "cluster-only escape hatch" for debugging
|
||||
# (docs/nomad-migration.md). Caller-side validation already rejects
|
||||
# --empty combined with --with or any --import-* flag, so reaching
|
||||
# this branch with those set is a bug in the caller.
|
||||
#
|
||||
# On the default (non-empty) path, vault-apply-policies.sh and
|
||||
# vault-nomad-auth.sh are invoked unconditionally — they are idempotent
|
||||
# and cheap to re-run, and subsequent --with deployments depend on
|
||||
# them. vault-import.sh is invoked only when an --import-* flag is set.
|
||||
local import_any=false
|
||||
if [ -n "$import_env" ] || [ -n "$import_sops" ]; then
|
||||
import_any=true
|
||||
fi
|
||||
if [ "$import_any" = true ]; then
|
||||
if [ "$empty" != "true" ]; then
|
||||
if [ ! -x "$vault_policies_sh" ]; then
|
||||
echo "Error: ${vault_policies_sh} not found or not executable" >&2
|
||||
exit 1
|
||||
|
|
@ -699,7 +707,7 @@ _disinto_init_nomad() {
|
|||
echo "Error: ${vault_auth_sh} not found or not executable" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -x "$vault_import_sh" ]; then
|
||||
if [ "$import_any" = true ] && [ ! -x "$vault_import_sh" ]; then
|
||||
echo "Error: ${vault_import_sh} not found or not executable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -722,6 +730,13 @@ _disinto_init_nomad() {
|
|||
"${cmd[@]}" || true
|
||||
echo ""
|
||||
|
||||
# --empty skips policies/auth/import/deploy — cluster-up only, no
|
||||
# workloads. The operator-visible dry-run plan must match the real
|
||||
# run, so short-circuit here too.
|
||||
if [ "$empty" = "true" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Vault policies + auth are invoked on every nomad real-run path
|
||||
# regardless of --import-* flags (they're idempotent; S2.1 + S2.3).
|
||||
# Mirror that ordering in the dry-run plan so the operator sees the
|
||||
|
|
@ -793,6 +808,12 @@ _disinto_init_nomad() {
|
|||
sudo -n -- "${cluster_cmd[@]}" || exit $?
|
||||
fi
|
||||
|
||||
# --empty short-circuits here: cluster-up only, no policies/auth/import
|
||||
# and no deploy. Matches the dry-run plan above and the docs/runbook.
|
||||
if [ "$empty" = "true" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Apply Vault policies (S2.1) — idempotent, safe to re-run.
|
||||
echo ""
|
||||
echo "── Applying Vault policies ────────────────────────────"
|
||||
|
|
@ -1005,6 +1026,15 @@ disinto_init() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# --empty is the cluster-only escape hatch — it skips policies, auth,
|
||||
# import, and deploy. Pairing it with --import-* silently does nothing,
|
||||
# which is a worse failure mode than a clear error. Reject explicitly.
|
||||
if [ "$empty" = true ] \
|
||||
&& { [ -n "$import_env" ] || [ -n "$import_sops" ] || [ -n "$age_key" ]; }; then
|
||||
echo "Error: --empty and --import-env/--import-sops/--age-key are mutually exclusive" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dispatch on backend — the nomad path runs lib/init/nomad/cluster-up.sh
|
||||
# (S0.4). The default and --empty variants are identical today; Step 1
|
||||
# will branch on $empty to add job deployment to the default path.
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ This runs, in order:
|
|||
- `--age-key` without `--import-sops` → error.
|
||||
- `--import-env` alone (no sops) → OK (imports just the plaintext `.env`).
|
||||
- `--backend=docker` with any `--import-*` flag → error.
|
||||
- `--empty` with any `--import-*` flag → error (mutually exclusive: `--empty`
|
||||
skips the import step, so pairing them silently discards the import
|
||||
intent).
|
||||
|
||||
## Idempotency
|
||||
|
||||
|
|
|
|||
|
|
@ -280,3 +280,33 @@ setup_file() {
|
|||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"env file: /tmp/.env"* ]]
|
||||
}
|
||||
|
||||
# --empty short-circuits after cluster-up: no policies, no auth, no
|
||||
# import, no deploy. The dry-run plan must match that — cluster-up plan
|
||||
# appears, but none of the S2.x section banners do.
|
||||
@test "disinto init --backend=nomad --empty --dry-run skips policies/auth/import sections" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --empty --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
# Cluster-up still runs (it's what --empty brings up).
|
||||
[[ "$output" == *"Cluster-up dry-run"* ]]
|
||||
# Policies + auth + import must NOT appear under --empty.
|
||||
[[ "$output" != *"Vault policies dry-run"* ]]
|
||||
[[ "$output" != *"Vault auth dry-run"* ]]
|
||||
[[ "$output" != *"Vault import dry-run"* ]]
|
||||
[[ "$output" != *"no --import-env/--import-sops"* ]]
|
||||
}
|
||||
|
||||
# --empty + any --import-* flag silently does nothing (import is skipped),
|
||||
# so the CLI rejects the combination up front rather than letting it
|
||||
# look like the import "succeeded".
|
||||
@test "disinto init --backend=nomad --empty --import-env errors" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --empty --import-env /tmp/.env --dry-run
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"--empty and --import-env/--import-sops/--age-key are mutually exclusive"* ]]
|
||||
}
|
||||
|
||||
@test "disinto init --backend=nomad --empty --import-sops --age-key errors" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --empty --import-sops /tmp/.env.vault.enc --age-key /tmp/keys.txt --dry-run
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"--empty and --import-env/--import-sops/--age-key are mutually exclusive"* ]]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue