deploy/set-edge-script-secrets.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p curl jq openssl
# Script to manage secrets for Bunny CDN edge scripts (tickets-*)
# Uses .env file for API key and some secret values
set -euo pipefail
# Colors for nice output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m' # No Color
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env"
# Pretty print functions
print_header() {
echo ""
echo -e "${BOLD}${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BOLD}${BLUE} $1${NC}"
echo -e "${BOLD}${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
}
print_success() { echo -e " ${GREEN}✓${NC} $1"; }
print_error() { echo -e " ${RED}✗${NC} $1"; }
print_info() { echo -e " ${CYAN}→${NC} $1"; }
print_skip() { echo -e " ${DIM}○${NC} $1"; }
print_step() { echo -e "${YELLOW}▶${NC} $1"; }
# Load environment variables
if [[ ! -f "$ENV_FILE" ]]; then
print_header "Configuration Error"
print_error ".env file not found at $ENV_FILE"
echo ""
echo " Please create a .env file with:"
echo -e " ${CYAN}BUNNY_API_KEY=your_api_key${NC}"
echo -e " ${CYAN}ADMIN_EMAIL_ADDRESS=...${NC}"
echo -e " ${CYAN}STORAGE_ZONE_NAME=...${NC}"
echo -e " ${CYAN}STORAGE_ZONE_KEY=...${NC}"
echo -e " ${CYAN}HOST_EMAIL_PROVIDER=...${NC}"
echo -e " ${CYAN}HOST_EMAIL_API_KEY=...${NC}"
echo -e " ${CYAN}HOST_EMAIL_FROM_ADDRESS=...${NC}"
echo -e " ${CYAN}APPLE_WALLET_PASS_TYPE_ID=...${NC}"
echo -e " ${CYAN}APPLE_WALLET_TEAM_ID=...${NC}"
echo -e " ${CYAN}APPLE_WALLET_SIGNING_CERT=\$(cat ./deploy/certs/signing-cert.pem)${NC}"
echo -e " ${CYAN}APPLE_WALLET_SIGNING_KEY=\$(cat ./deploy/certs/signing-key.pem)${NC}"
echo -e " ${CYAN}APPLE_WALLET_WWDR_CERT=\$(cat ./deploy/certs/wwdr-cert.pem)${NC}"
echo -e " ${CYAN}GOOGLE_WALLET_ISSUER_ID=...${NC}"
echo -e " ${CYAN}GOOGLE_WALLET_SERVICE_ACCOUNT_EMAIL=...${NC}"
echo -e " ${CYAN}GOOGLE_WALLET_SERVICE_ACCOUNT_KEY=\$(cat ./deploy/certs/google-key.pem)${NC}"
echo ""
exit 1
fi
source "$ENV_FILE"
if [[ -z "${BUNNY_API_KEY:-}" ]]; then
print_header "Configuration Error"
print_error "BUNNY_API_KEY not set in .env"
exit 1
fi
API_BASE="https://api.bunny.net"
print_header "Bunny Edge Script Secrets Manager"
# Accept script IDs as argument or prompt interactively
if [[ -n "${1:-}" ]]; then
SCRIPT_IDS_INPUT="$1"
else
echo -e -n " ${CYAN}→${NC} Enter edge script ID(s) separated by ${BOLD}|${NC}: "
read -r SCRIPT_IDS_INPUT
fi
# Validate all script IDs
IFS='|' read -ra SCRIPT_ID_LIST <<< "$SCRIPT_IDS_INPUT"
for sid in "${SCRIPT_ID_LIST[@]}"; do
if ! [[ "$sid" =~ ^[0-9]+$ ]]; then
print_error "Invalid script ID: $sid"
exit 1
fi
done
echo -e " ${DIM}Will process ${#SCRIPT_ID_LIST[@]} script(s): ${SCRIPT_IDS_INPUT}${NC}"
# Global totals
total_success=0
total_skip=0
total_fail=0
for SCRIPT_ID in "${SCRIPT_ID_LIST[@]}"; do
# Fetch existing secrets for this script
print_header "Script ${SCRIPT_ID} — Checking Existing Secrets"
echo -e " Edge Script ID: ${BOLD}${CYAN}$SCRIPT_ID${NC}"
echo ""
print_step "Fetching existing secrets..."
response=$(curl -s -w "\n%{http_code}" -X GET \
"${API_BASE}/compute/script/${SCRIPT_ID}/secrets" \
-H "AccessKey: ${BUNNY_API_KEY}" \
-H "Accept: application/json")
http_code=$(echo "$response" | tail -n1)
secrets_body=$(echo "$response" | sed '$d')
if [[ "$http_code" -lt 200 || "$http_code" -ge 300 ]]; then
print_error "Failed to fetch secrets (HTTP $http_code)"
echo "$secrets_body"
exit 1
fi
# Build a list of existing secret names
existing_secrets=$(echo "$secrets_body" | jq -r '.Secrets[].Name // empty')
secret_exists() {
echo "$existing_secrets" | grep -qx "$1"
}
# Function to set a secret via API
set_secret() {
local name="$1"
local value="$2"
local payload
payload=$(jq -n --arg n "$name" --arg s "$value" '{Name: $n, Secret: $s}')
local response
response=$(curl -s -w "\n%{http_code}" -X PUT \
"${API_BASE}/compute/script/${SCRIPT_ID}/secrets" \
-H "AccessKey: ${BUNNY_API_KEY}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "$payload")
local http_code
http_code=$(echo "$response" | tail -n1)
if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
print_success "${BOLD}$name${NC} set"
return 0
else
local resp_body
resp_body=$(echo "$response" | sed '$d')
print_error "${BOLD}$name${NC} failed (HTTP $http_code)"
echo -e " ${RED}$resp_body${NC}"
return 1
fi
}
# Counters (per script)
success_count=0
skip_count=0
fail_count=0
# Helper: set secret from .env variable (by name)
set_from_env() {
local name="$1"
local value="${!name:-}"
if secret_exists "$name"; then
print_skip "${BOLD}$name${NC} already exists, skipping"
skip_count=$((skip_count + 1))
elif [[ -z "$value" ]]; then
print_error "${BOLD}$name${NC} not found in .env, skipping"
fail_count=$((fail_count + 1))
else
print_info "Using ${BOLD}$name${NC} from .env"
if set_secret "$name" "$value"; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
fi
}
# Helper: set secret by prompting the user
set_from_prompt() {
local name="$1"
if secret_exists "$name"; then
print_skip "${BOLD}$name${NC} already exists, skipping"
skip_count=$((skip_count + 1))
else
echo -e -n " ${CYAN}→${NC} Enter ${BOLD}$name${NC}: "
read -r value
if [[ -z "$value" ]]; then
print_error "$name cannot be empty, skipping"
fail_count=$((fail_count + 1))
elif set_secret "$name" "$value"; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
fi
}
# Process each secret
print_header "Script ${SCRIPT_ID} — Setting Secrets"
echo -e " ${DIM}Existing secrets will be skipped (not overwritten).${NC}"
echo ""
# Prompted secrets
set_from_prompt "DB_URL"
set_from_prompt "DB_TOKEN"
# Auto-generated secrets
if secret_exists "DB_ENCRYPTION_KEY"; then
print_skip "${BOLD}DB_ENCRYPTION_KEY${NC} already exists, skipping"
skip_count=$((skip_count + 1))
else
encryption_key=$(openssl rand -base64 32)
print_info "Generated ${BOLD}DB_ENCRYPTION_KEY${NC}: ${DIM}$encryption_key${NC}"
if set_secret "DB_ENCRYPTION_KEY" "$encryption_key"; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
fi
# Script's own ID
if secret_exists "BUNNY_SCRIPT_ID"; then
print_skip "${BOLD}BUNNY_SCRIPT_ID${NC} already exists, skipping"
skip_count=$((skip_count + 1))
else
print_info "Setting ${BOLD}BUNNY_SCRIPT_ID${NC} to ${DIM}$SCRIPT_ID${NC}"
if set_secret "BUNNY_SCRIPT_ID" "$SCRIPT_ID"; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
fi
# Secrets from .env
set_from_env "NTFY_URL"
set_from_env "SENTRY_URL"
set_from_env "ADMIN_EMAIL_ADDRESS"
set_from_env "SUPPORT_PAGE_TEXT"
set_from_env "SUPPORT_FORM_NAG_DAYS"
set_from_env "STORAGE_ZONE_NAME"
set_from_env "STORAGE_ZONE_KEY"
set_from_env "HOST_EMAIL_PROVIDER"
set_from_env "HOST_EMAIL_API_KEY"
set_from_env "HOST_EMAIL_FROM_ADDRESS"
set_from_env "BUNNY_API_KEY"
set_from_env "BUNNY_DNS_ZONE_ID"
set_from_env "BUNNY_DNS_SUBDOMAIN_SUFFIX"
# Apple Wallet secrets (all from .env - certs use $(cat ...) in .env)
set_from_env "APPLE_WALLET_PASS_TYPE_ID"
set_from_env "APPLE_WALLET_TEAM_ID"
set_from_env "APPLE_WALLET_SIGNING_CERT"
set_from_env "APPLE_WALLET_SIGNING_KEY"
set_from_env "APPLE_WALLET_WWDR_CERT"
# Google Wallet secrets (key uses $(cat ...) in .env)
set_from_env "GOOGLE_WALLET_ISSUER_ID"
set_from_env "GOOGLE_WALLET_SERVICE_ACCOUNT_EMAIL"
set_from_env "GOOGLE_WALLET_SERVICE_ACCOUNT_KEY"
# Per-script summary
print_header "Script ${SCRIPT_ID} — Summary"
echo -e " Edge Script ID: ${BOLD}${CYAN}$SCRIPT_ID${NC}"
echo ""
if [[ $success_count -gt 0 ]]; then
echo -e " ${GREEN}✓${NC} $success_count secret(s) set"
fi
if [[ $skip_count -gt 0 ]]; then
echo -e " ${DIM}○${NC} $skip_count secret(s) already existed (skipped)"
fi
if [[ $fail_count -gt 0 ]]; then
echo -e " ${RED}✗${NC} $fail_count secret(s) failed"
fi
total_success=$((total_success + success_count))
total_skip=$((total_skip + skip_count))
total_fail=$((total_fail + fail_count))
done # end loop over SCRIPT_ID_LIST
# Overall summary (only if multiple scripts)
if [[ ${#SCRIPT_ID_LIST[@]} -gt 1 ]]; then
print_header "Overall Summary (${#SCRIPT_ID_LIST[@]} scripts)"
if [[ $total_success -gt 0 ]]; then
echo -e " ${GREEN}✓${NC} $total_success secret(s) set"
fi
if [[ $total_skip -gt 0 ]]; then
echo -e " ${DIM}○${NC} $total_skip secret(s) already existed (skipped)"
fi
if [[ $total_fail -gt 0 ]]; then
echo -e " ${RED}✗${NC} $total_fail secret(s) failed"
fi
fi
echo ""