diff --git a/README.md b/README.md index eef192a..ae170c7 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Repo 內提供: # 例:用一次性 URL 安裝 vault-pass.txt INSTALL_VAULT_PASS_METHOD=url \ VAULT_PASS_URL="https://example.com/one-time/vault-pass.txt" \ +./scripts/install-vault-pass.sh --check-env ./scripts/install-vault-pass.sh ``` diff --git a/docs/agent-install-runbook.md b/docs/agent-install-runbook.md index c7098fa..97c701d 100644 --- a/docs/agent-install-runbook.md +++ b/docs/agent-install-runbook.md @@ -93,6 +93,14 @@ INSTALL_ENV_FILE=install.local.env ./scripts/install-vault-pass.sh 不要把含真實密碼/token 的 env 檔 commit。 +執行安裝前可先檢查 env 是否足夠非互動安裝: + +```bash +./scripts/install-vault-pass.sh --check-env +``` + +若輸出顯示 env 不足,installer 會在正式安裝時進入互動提示或列出缺少欄位。 + ## 3. 安裝 vault password file 標準位置: diff --git a/docs/human-guide.md b/docs/human-guide.md index 47f3fa0..d6e1fc1 100644 --- a/docs/human-guide.md +++ b/docs/human-guide.md @@ -28,6 +28,7 @@ cd agent-secret-vault 接著安裝 vault password file: ```bash +./scripts/install-vault-pass.sh --check-env ./scripts/install-vault-pass.sh ``` @@ -74,6 +75,7 @@ git push cd ~/projects/agent-secret-vault cp -n install.env.example install.env editor install.env +./scripts/install-vault-pass.sh --check-env ./scripts/install-vault-pass.sh ``` @@ -87,7 +89,8 @@ editor install.env 若 env 內含真實 secrets,不要 commit。可改用 `install.local.env`,再執行: ```bash -INSTALL_ENV_FILE=install.local.env ./scripts/install-vault-pass.sh +INSTALL_ENV_FILE=install.local.env ./scripts/install-vault-pass.sh --check-env +./scripts/install-vault-pass.sh ``` ## 給 agent 的全自動安裝方式 @@ -103,6 +106,7 @@ VAULT_PASS_URL="https://example.com/one-time/vault-pass.txt" \ # 或:zip 密碼放在本機安全檔案 INSTALL_VAULT_PASS_METHOD=archive \ VAULT_PASS_ZIP_PASSWORD_FILE=/secure/path/zip-password.txt \ +./scripts/install-vault-pass.sh --check-env ./scripts/install-vault-pass.sh ``` diff --git a/scripts/install-vault-pass.sh b/scripts/install-vault-pass.sh index 4eee773..d546591 100755 --- a/scripts/install-vault-pass.sh +++ b/scripts/install-vault-pass.sh @@ -56,6 +56,9 @@ Non-interactive agent mode (via install.env or environment variables): VAULT_PASS_ZIP_PASSWORD_FILE=/secure/pass INSTALL_VAULT_PASS_METHOD=archive ./scripts/install-vault-pass.sh VAULT_PASS_ZIP_PASSWORD='...' INSTALL_VAULT_PASS_METHOD=archive ./scripts/install-vault-pass.sh +Check env sufficiency without installing: + ./scripts/install-vault-pass.sh --check-env + Default archive path for method [4]: $REPO_DIR/secrets/vault-pass.txt.zip USAGE @@ -237,6 +240,78 @@ verify_vault_readable_if_possible() { fi } + +preflight_env_config() { + if [ ! -f "$ENV_FILE" ]; then + echo "Installer env file not found: $ENV_FILE" + echo "Copy template first: cp install.env.example install.env" + return 0 + fi + + echo "Loaded installer env: $ENV_FILE" + + if [ -f "$DEST" ]; then + echo "Preflight: vault password file already exists: $DEST" + return 0 + fi + + method="${INSTALL_VAULT_PASS_METHOD:-}" + if [ -z "$method" ]; then + echo "Preflight: install.env does not set INSTALL_VAULT_PASS_METHOD; interactive menu will be used." + return 0 + fi + + case "$method" in + create|1) + echo "Preflight: install.env is sufficient for method=create." + ;; + manual|2) + if [ -n "${VAULT_PASS_CONTENT:-}" ]; then + echo "Preflight: install.env is sufficient for method=manual (VAULT_PASS_CONTENT set)." + else + echo "Preflight: method=manual but VAULT_PASS_CONTENT is empty; hidden input will be required." + fi + ;; + url|3) + if [ -n "${VAULT_PASS_URL:-}" ]; then + echo "Preflight: install.env is sufficient for method=url." + else + echo "Preflight: method=url but VAULT_PASS_URL is empty; URL input will be required." + fi + ;; + archive|4) + if [ -n "${VAULT_PASS_ZIP_PASSWORD_FILE:-}" ] && [ -f "$VAULT_PASS_ZIP_PASSWORD_FILE" ]; then + echo "Preflight: install.env is sufficient for method=archive (password file exists)." + elif [ -n "${VAULT_PASS_ZIP_PASSWORD_FILE:-}" ]; then + echo "Preflight: method=archive but VAULT_PASS_ZIP_PASSWORD_FILE does not exist: $VAULT_PASS_ZIP_PASSWORD_FILE" + elif [ -n "${VAULT_PASS_ZIP_PASSWORD:-}" ]; then + echo "Preflight: install.env is sufficient for method=archive (inline zip password set)." + else + echo "Preflight: method=archive but no zip password is configured; unzip will prompt interactively." + fi + if [ ! -f "$ARCHIVE" ]; then + echo "Preflight: archive file is missing: $ARCHIVE" + fi + ;; + *) + echo "Preflight: invalid INSTALL_VAULT_PASS_METHOD: $method" + ;; + esac +} + +env_has_noninteractive_config() { + method="${INSTALL_VAULT_PASS_METHOD:-}" + case "$method" in + create|1) return 0 ;; + manual|2) [ -n "${VAULT_PASS_CONTENT:-}" ] ;; + url|3) [ -n "${VAULT_PASS_URL:-}" ] ;; + archive|4) + { [ -n "${VAULT_PASS_ZIP_PASSWORD:-}" ] || { [ -n "${VAULT_PASS_ZIP_PASSWORD_FILE:-}" ] && [ -f "$VAULT_PASS_ZIP_PASSWORD_FILE" ]; }; } && [ -f "$ARCHIVE" ] + ;; + *) return 1 ;; + esac +} + run_method() { case "$1" in create|1) create_new_password ;; @@ -252,12 +327,24 @@ if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then exit 0 fi +if [ "${1:-}" = "--check-env" ]; then + preflight_env_config + exit 0 +fi + if verify_existing; then verify_vault_readable_if_possible || true exit 0 fi +preflight_env_config + if [ -n "${INSTALL_VAULT_PASS_METHOD:-}" ]; then + if env_has_noninteractive_config; then + echo "Using non-interactive configuration from env." + else + echo "Env is not sufficient for a fully non-interactive install; installer may prompt." + fi run_method "$INSTALL_VAULT_PASS_METHOD" verify_vault_readable_if_possible || true exit 0