fix: [nomad-step-2] S2.2 — tools/vault-import.sh (import .env + sops into KV) (#880) #889
1 changed files with 63 additions and 20 deletions
|
|
@ -127,12 +127,14 @@ _kv_put_secret() {
|
||||||
local path="$1"
|
local path="$1"
|
||||||
shift
|
shift
|
||||||
local kv_pairs=("$@")
|
local kv_pairs=("$@")
|
||||||
local payload='{"data":{}}'
|
|
||||||
|
|
||||||
|
# Build JSON payload with all key-value pairs
|
||||||
|
local payload='{"data":{}}'
|
||||||
for kv in "${kv_pairs[@]}"; do
|
for kv in "${kv_pairs[@]}"; do
|
||||||
local k="${kv%%=*}"
|
local k="${kv%%=*}"
|
||||||
local v="${kv#*=}"
|
local v="${kv#*=}"
|
||||||
payload="$(printf '%s' "$payload" | jq -n --arg k "$k" --arg v "$v" '.data[$k] = $v')"
|
# Use jq to merge the new pair into the data object
|
||||||
|
payload="$(printf '%s' "$payload" | jq ". * {\"data\": {\"$k\": \"$v\"}}")"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Use curl directly for KV v2 write with versioning
|
# Use curl directly for KV v2 write with versioning
|
||||||
|
|
@ -419,6 +421,10 @@ EOF
|
||||||
local updated=0
|
local updated=0
|
||||||
local unchanged=0
|
local unchanged=0
|
||||||
|
|
||||||
|
# First pass: collect all operations with their parsed values
|
||||||
|
# Store as: ops_data["vault_path:kv_key"] = "source_value|status"
|
||||||
|
declare -A ops_data
|
||||||
|
|
||||||
for op in "${operations[@]}"; do
|
for op in "${operations[@]}"; do
|
||||||
# Parse operation: category|field|subkey|file|envvar (5 fields for bots/runner)
|
# Parse operation: category|field|subkey|file|envvar (5 fields for bots/runner)
|
||||||
# or category|field|file|envvar (4 fields for forge/woodpecker/chat)
|
# or category|field|file|envvar (4 fields for forge/woodpecker/chat)
|
||||||
|
|
@ -475,10 +481,9 @@ EOF
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Check if path exists
|
# Determine status for this key
|
||||||
local status="created"
|
local status="created"
|
||||||
if _kv_path_exists "$vault_path"; then
|
if _kv_path_exists "$vault_path"; then
|
||||||
# Check if key exists in path
|
|
||||||
local existing_value
|
local existing_value
|
||||||
if existing_value="$(_kv_get_value "$vault_path" "$vault_key")" 2>/dev/null; then
|
if existing_value="$(_kv_get_value "$vault_path" "$vault_key")" 2>/dev/null; then
|
||||||
if [ "$existing_value" = "$source_value" ]; then
|
if [ "$existing_value" = "$source_value" ]; then
|
||||||
|
|
@ -486,30 +491,68 @@ EOF
|
||||||
else
|
else
|
||||||
status="updated"
|
status="updated"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
status="created"
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Output status
|
# Store operation data: key = "vault_path:kv_key", value = "source_value|status"
|
||||||
_format_status "$status" "$vault_path" "$vault_key"
|
ops_data["${vault_path}:${vault_key}"]="${source_value}|${status}"
|
||||||
printf '\n'
|
done
|
||||||
|
|
||||||
# Write if not unchanged
|
# Second pass: group by vault_path and write
|
||||||
if [ "$status" != "unchanged" ]; then
|
declare -A paths_to_write
|
||||||
if ! _kv_put_secret "$vault_path" "${vault_key}=${source_value}"; then
|
declare -A path_statuses
|
||||||
_err "Failed to write $vault_key to $vault_path"
|
|
||||||
exit 1
|
for key in "${!ops_data[@]}"; do
|
||||||
fi
|
local data="${ops_data[$key]}"
|
||||||
case "$status" in
|
local source_value="${data%%|*}"
|
||||||
updated) ((updated++)) || true ;;
|
local status="${data##*|}"
|
||||||
created) ((created++)) || true ;;
|
local vault_path="${key%:*}"
|
||||||
esac
|
local vault_key="${key#*:}"
|
||||||
else
|
|
||||||
|
if [ "$status" = "unchanged" ]; then
|
||||||
|
_format_status "$status" "$vault_path" "$vault_key"
|
||||||
|
printf '\n'
|
||||||
((unchanged++)) || true
|
((unchanged++)) || true
|
||||||
|
else
|
||||||
|
# Add to paths_to_write for this vault_path
|
||||||
|
if [ -z "${paths_to_write[$vault_path]:-}" ]; then
|
||||||
|
paths_to_write[$vault_path]="${vault_key}=${source_value}"
|
||||||
|
else
|
||||||
|
paths_to_write[$vault_path]="${paths_to_write[$vault_path]}|${vault_key}=${source_value}"
|
||||||
|
fi
|
||||||
|
# Track status for counting (use last status for the path)
|
||||||
|
path_statuses[$vault_path]="$status"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Write each path with all its key-value pairs
|
||||||
|
for vault_path in "${!paths_to_write[@]}"; do
|
||||||
|
local status="${path_statuses[$vault_path]}"
|
||||||
|
|
||||||
|
# Read pipe-separated key-value pairs and write them
|
||||||
|
local pairs_string="${paths_to_write[$vault_path]}"
|
||||||
|
local pairs_array=()
|
||||||
|
local IFS='|'
|
||||||
|
read -r -a pairs_array <<< "$pairs_string"
|
||||||
|
|
||||||
|
if ! _kv_put_secret "$vault_path" "${pairs_array[@]}"; then
|
||||||
|
_err "Failed to write to $vault_path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Output status for each key in this path
|
||||||
|
for kv in "${pairs_array[@]}"; do
|
||||||
|
local kv_key="${kv%%=*}"
|
||||||
|
_format_status "$status" "$vault_path" "$kv_key"
|
||||||
|
printf '\n'
|
||||||
|
done
|
||||||
|
|
||||||
|
case "$status" in
|
||||||
|
updated) ((updated++)) || true ;;
|
||||||
|
created) ((created++)) || true ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
_log ""
|
_log ""
|
||||||
_log "=== Import complete ==="
|
_log "=== Import complete ==="
|
||||||
_log "Created: $created"
|
_log "Created: $created"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue