2025-05-29 17:34:58 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
2025-06-01 23:48:20 +02:00
|
|
|
set -euo pipefail
|
|
|
|
|
|
2025-06-02 00:44:43 +02:00
|
|
|
dc_infisical() {
|
|
|
|
|
# If stdout is a real terminal, allocate TTY
|
|
|
|
|
if [ -t 1 ]; then
|
|
|
|
|
docker compose run --rm -t cli infisical "$@"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
docker compose run --rm cli infisical "$@"
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-29 17:34:58 +02:00
|
|
|
fetch_secret() {
|
|
|
|
|
local target_secret="${1:?Target secret local_secret is required}"
|
|
|
|
|
local env="${2:?Environment is required}"
|
|
|
|
|
local output_file="${3:?}"
|
|
|
|
|
|
2025-06-01 23:51:21 +02:00
|
|
|
if command -v infisical-dcli &>/dev/null; then
|
2025-06-01 23:35:31 +02:00
|
|
|
# If infisical CLI command is available, use it directly
|
2025-06-01 23:51:21 +02:00
|
|
|
infisical-dcli secrets --plain get "${target_secret}" --env "${env}" >"${output_file}"
|
2025-06-01 23:35:31 +02:00
|
|
|
else
|
2025-06-02 00:44:43 +02:00
|
|
|
if ! dc_infisical secrets --plain get "${target_secret}" --env "${env}" >"${output_file}"; then
|
|
|
|
|
rm -f "${output_file}" # Clean up if fetch failed
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
2025-06-01 23:35:31 +02:00
|
|
|
fi
|
2025-05-29 17:34:58 +02:00
|
|
|
|
|
|
|
|
# Check if file is empty
|
|
|
|
|
if [[ ! -s ${output_file} ]]; then
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main() {
|
|
|
|
|
local config_file="${1:-./secrets.json}"
|
|
|
|
|
local secrets_dir="${2:-./secrets}"
|
|
|
|
|
|
2025-06-01 23:35:31 +02:00
|
|
|
if ! command -v jq &>/dev/null; then
|
2025-05-29 17:34:58 +02:00
|
|
|
printf "Error: jq is required but not installed\n" >&2
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
2025-06-01 23:35:31 +02:00
|
|
|
if [[ ! -f ${config_file} ]]; then
|
2025-05-29 17:34:58 +02:00
|
|
|
printf "Error: Config file %s not found\n" "${config_file}" >&2
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
mkdir -p "${secrets_dir}"
|
|
|
|
|
|
|
|
|
|
mapfile -t entries < <(jq -c '.[]' "${config_file}")
|
|
|
|
|
|
2025-05-29 21:02:23 +02:00
|
|
|
local local_secret target_secret filename env obj
|
2025-05-29 17:34:58 +02:00
|
|
|
|
|
|
|
|
for obj in "${entries[@]}"; do
|
|
|
|
|
local_secret="$(jq -r .secret_name <<<"${obj}")"
|
|
|
|
|
target_secret="$(jq -r .target_secret <<<"${obj}")"
|
|
|
|
|
env="$(jq -r .env <<<"${obj}")"
|
2025-05-29 21:02:23 +02:00
|
|
|
filename="$(jq -r .filename <<<"${obj}")"
|
|
|
|
|
|
2025-06-01 23:45:21 +02:00
|
|
|
if [[ ${local_secret} == "null" || ${target_secret} == "null" ]]; then
|
|
|
|
|
printf "Error: Missing required fields in entry: %s\n" "${obj}" >&2
|
|
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
|
2025-05-29 21:02:23 +02:00
|
|
|
# Default output file name
|
2025-06-01 23:41:44 +02:00
|
|
|
output_file="${secrets_dir}/${local_secret}"
|
2025-05-29 21:02:23 +02:00
|
|
|
|
|
|
|
|
# If filename is specified in json, use it; otherwise, use the local_secret as the filename
|
2025-06-01 23:35:31 +02:00
|
|
|
if [[ -n ${filename} && ${filename} != "null" ]]; then
|
2025-05-29 21:12:48 +02:00
|
|
|
output_file="${secrets_dir}/${filename}"
|
2025-05-29 21:02:23 +02:00
|
|
|
fi
|
2025-05-29 17:34:58 +02:00
|
|
|
|
2025-06-01 23:45:52 +02:00
|
|
|
if [[ ${env} == "null" ]]; then
|
2025-06-01 23:47:07 +02:00
|
|
|
printf "Warning: Environment not specified for secret %s, assuming 'dev'\n" "${local_secret}" >&2
|
|
|
|
|
env="dev"
|
2025-05-29 17:34:58 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
printf "Processing %s -> %s (%s)\n" "${local_secret}" "${target_secret}" "${env}"
|
|
|
|
|
if fetch_secret "${target_secret}" "${env}" "${output_file}"; then
|
|
|
|
|
printf "✔ saved to %s\n" "${output_file}"
|
|
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
rm -f "${output_file}" # Clean up if fetch failed
|
|
|
|
|
printf "✘ failed to fetch %s\n" "${target_secret}" >&2
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main "$@"
|