Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- Config, docs, scripts, and backup manifests - Submodule refs unchanged (m = modified content in submodules) Made-with: Cursor
241 lines
8.4 KiB
Bash
Executable File
241 lines
8.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Migrate secrets from .env files and scripts to HashiCorp Vault
|
|
# This script helps automate the migration process
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[✗]${NC} $1"; }
|
|
|
|
# Configuration
|
|
VAULT_ADDR="${VAULT_ADDR:-http://127.0.0.1:8200}"
|
|
VAULT_TOKEN="${VAULT_TOKEN:-}"
|
|
DRY_RUN="${DRY_RUN:-true}"
|
|
PROJECT_ROOT="${PROJECT_ROOT:-/home/intlc/projects}"
|
|
|
|
# Check if vault CLI is available
|
|
if ! command -v vault &> /dev/null; then
|
|
log_error "Vault CLI not found. Please install HashiCorp Vault CLI."
|
|
exit 1
|
|
fi
|
|
|
|
# Check vault connection
|
|
if [ -z "$VAULT_TOKEN" ]; then
|
|
log_warn "VAULT_TOKEN not set. Attempting to use vault auth..."
|
|
if ! vault auth -method=userpass username=admin 2>/dev/null; then
|
|
log_error "Cannot authenticate to Vault. Please set VAULT_TOKEN or configure authentication."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if ! vault status &>/dev/null; then
|
|
log_error "Cannot connect to Vault at $VAULT_ADDR"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Connected to Vault at $VAULT_ADDR"
|
|
echo ""
|
|
|
|
# Function to migrate a secret
|
|
migrate_secret() {
|
|
local vault_path="$1"
|
|
local secret_name="$2"
|
|
local secret_value="$3"
|
|
local description="$4"
|
|
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
log_info "[DRY RUN] Would migrate: $secret_name"
|
|
log_info " Path: $vault_path"
|
|
log_info " Description: $description"
|
|
echo ""
|
|
return 0
|
|
fi
|
|
|
|
log_info "Migrating $secret_name to $vault_path..."
|
|
|
|
# Create the secret in Vault
|
|
if vault kv put "$vault_path" \
|
|
value="$secret_value" \
|
|
name="$secret_name" \
|
|
description="$description" \
|
|
migrated_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
migrated_by="$(whoami)" 2>/dev/null; then
|
|
log_success "Migrated $secret_name"
|
|
return 0
|
|
else
|
|
log_error "Failed to migrate $secret_name"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to read secret from .env file
|
|
read_env_secret() {
|
|
local env_file="$1"
|
|
local secret_name="$2"
|
|
|
|
if [ ! -f "$env_file" ]; then
|
|
return 1
|
|
fi
|
|
|
|
# Try to read the secret (handles both KEY=value and KEY="value" formats)
|
|
grep -E "^${secret_name}=" "$env_file" 2>/dev/null | cut -d'=' -f2- | sed 's/^"//;s/"$//' | head -1
|
|
}
|
|
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
echo " Secrets Migration to Vault"
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
echo ""
|
|
log_info "Mode: $([ "$DRY_RUN" = "true" ] && echo "DRY RUN" || echo "LIVE")"
|
|
log_info "Vault Address: $VAULT_ADDR"
|
|
log_info "Project Root: $PROJECT_ROOT"
|
|
echo ""
|
|
|
|
# Phase 1: Critical Secrets - Private Keys
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "Phase 1: Critical Secrets - Private Keys"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
PRIVATE_KEY_FILES=(
|
|
"$PROJECT_ROOT/proxmox/smom-dbis-138/.env"
|
|
"$PROJECT_ROOT/no_five/.env"
|
|
"$PROJECT_ROOT/loc_az_hci/smom-dbis-138/.env"
|
|
"$PROJECT_ROOT/237-combo/.env"
|
|
)
|
|
|
|
for env_file in "${PRIVATE_KEY_FILES[@]}"; do
|
|
if [ -f "$env_file" ]; then
|
|
private_key=$(read_env_secret "$env_file" "PRIVATE_KEY")
|
|
if [ -n "$private_key" ] && [ "$private_key" != "your_private_key_here" ]; then
|
|
project_name=$(basename "$(dirname "$env_file")")
|
|
migrate_secret \
|
|
"secret/blockchain/private-keys/$project_name" \
|
|
"PRIVATE_KEY" \
|
|
"$private_key" \
|
|
"Private key from $env_file"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Phase 2: Cloudflare Secrets
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "Phase 2: Cloudflare Secrets"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
CLOUDFLARE_ENV_FILES=(
|
|
"$PROJECT_ROOT/proxmox/.env"
|
|
"$PROJECT_ROOT/loc_az_hci/.env"
|
|
"$PROJECT_ROOT/loc_az_hci/smom-dbis-138/.env"
|
|
)
|
|
|
|
for env_file in "${CLOUDFLARE_ENV_FILES[@]}"; do
|
|
if [ -f "$env_file" ]; then
|
|
# API Token
|
|
api_token=$(read_env_secret "$env_file" "CLOUDFLARE_API_TOKEN")
|
|
if [ -n "$api_token" ]; then
|
|
migrate_secret \
|
|
"secret/cloudflare/api-tokens/main" \
|
|
"CLOUDFLARE_API_TOKEN" \
|
|
"$api_token" \
|
|
"Cloudflare API token from $env_file"
|
|
fi
|
|
|
|
# API Key (legacy)
|
|
api_key=$(read_env_secret "$env_file" "CLOUDFLARE_API_KEY")
|
|
if [ -n "$api_key" ]; then
|
|
migrate_secret \
|
|
"secret/cloudflare/api-keys/legacy" \
|
|
"CLOUDFLARE_API_KEY" \
|
|
"$api_key" \
|
|
"Cloudflare API key (legacy) from $env_file"
|
|
fi
|
|
|
|
# Tunnel Token
|
|
tunnel_token=$(read_env_secret "$env_file" "CLOUDFLARE_TUNNEL_TOKEN")
|
|
if [ -n "$tunnel_token" ]; then
|
|
migrate_secret \
|
|
"secret/cloudflare/tunnel-tokens/shared" \
|
|
"CLOUDFLARE_TUNNEL_TOKEN" \
|
|
"$tunnel_token" \
|
|
"Cloudflare tunnel token from $env_file"
|
|
fi
|
|
|
|
# Origin CA Key
|
|
origin_ca=$(read_env_secret "$env_file" "CLOUDFLARE_ORIGIN_CA_KEY")
|
|
if [ -n "$origin_ca" ]; then
|
|
migrate_secret \
|
|
"secret/cloudflare/origin-ca/main" \
|
|
"CLOUDFLARE_ORIGIN_CA_KEY" \
|
|
"$origin_ca" \
|
|
"Cloudflare Origin CA key from $env_file"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Phase 3: Infrastructure Secrets
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "Phase 3: Infrastructure Secrets"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# NPM Password
|
|
npm_env="$PROJECT_ROOT/proxmox/.env"
|
|
if [ -f "$npm_env" ]; then
|
|
npm_password=$(read_env_secret "$npm_env" "NPM_PASSWORD")
|
|
if [ -n "$npm_password" ]; then
|
|
migrate_secret \
|
|
"secret/infrastructure/npm/password" \
|
|
"NPM_PASSWORD" \
|
|
"$npm_password" \
|
|
"NPM password from $npm_env"
|
|
fi
|
|
|
|
npm_email=$(read_env_secret "$npm_env" "NPM_EMAIL")
|
|
if [ -n "$npm_email" ]; then
|
|
migrate_secret \
|
|
"secret/infrastructure/npm/email" \
|
|
"NPM_EMAIL" \
|
|
"$npm_email" \
|
|
"NPM email from $npm_env"
|
|
fi
|
|
fi
|
|
|
|
# Database URL
|
|
dbis_env="$PROJECT_ROOT/proxmox/dbis_core/.env"
|
|
if [ -f "$dbis_env" ]; then
|
|
db_url=$(read_env_secret "$dbis_env" "DATABASE_URL")
|
|
if [ -n "$db_url" ]; then
|
|
migrate_secret \
|
|
"secret/databases/postgres/main" \
|
|
"DATABASE_URL" \
|
|
"$db_url" \
|
|
"Database URL from $dbis_env"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
log_info "DRY RUN complete. Review the output above."
|
|
log_info "To perform actual migration, run:"
|
|
log_info " DRY_RUN=false ./migrate-secrets-to-vault.sh"
|
|
else
|
|
log_success "Migration complete!"
|
|
log_info "Next steps:"
|
|
log_info " 1. Verify secrets in Vault: vault kv list secret/"
|
|
log_info " 2. Update applications to use Vault"
|
|
log_info " 3. Remove secrets from .env files"
|
|
log_info " 4. Update scripts to use Vault"
|
|
fi
|
|
echo "═══════════════════════════════════════════════════════════"
|