diff --git a/scripts/cloudflare/purge-cybersecur-d-bis-edge-cache.sh b/scripts/cloudflare/purge-cybersecur-d-bis-edge-cache.sh new file mode 100755 index 00000000..c79eb508 --- /dev/null +++ b/scripts/cloudflare/purge-cybersecur-d-bis-edge-cache.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Purge Cloudflare edge cache for cybersecur.d-bis.org static paths after deploy. +# Fixes stale HITs where HEAD returns 404 while GET is OK (robots.txt) or favicon cached as 404. +# +# Requires CLOUDFLARE_API_TOKEN with Zone → Cache Purge → Purge (same zone as DNS edits). +# DNS-only scoped tokens often fail here — extend token or purge once in Dashboard: +# Caching → Configuration → Purge Cache → Custom Purge → URL list. +# +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +if [[ -f "${PROJECT_ROOT}/.env" ]]; then set -a; source "${PROJECT_ROOT}/.env"; set +a; fi +TOKEN="${CLOUDFLARE_API_TOKEN:?Set CLOUDFLARE_API_TOKEN}" +ZONE="${CLOUDFLARE_ZONE_ID_D_BIS_ORG:-}" +if [[ -z "$ZONE" ]]; then + ZONE=$(curl -sS -H "Authorization: Bearer ${TOKEN}" \ + "https://api.cloudflare.com/client/v4/zones?name=d-bis.org" | jq -r '.result[0].id // empty') +fi +[[ -n "$ZONE" ]] || { echo "Could not resolve zone id for d-bis.org" >&2; exit 1; } + +BODY=$(jq -n --arg z "$ZONE" '{ + files: [ + "https://cybersecur.d-bis.org/", + "https://cybersecur.d-bis.org/robots.txt", + "https://cybersecur.d-bis.org/sitemap.xml", + "https://cybersecur.d-bis.org/favicon.ico", + "https://cybersecur.d-bis.org/index.html" + ] +}') +RESP=$(curl -sS -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE}/purge_cache" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d "$BODY") +echo "$RESP" | jq . + +if echo "$RESP" | jq -e '.success == true' >/dev/null 2>&1; then + echo "✓ Purged. Recheck: curl -sSI https://cybersecur.d-bis.org/robots.txt | head -1" + exit 0 +fi +echo "If authentication failed, add Cache Purge permission to the token or run Custom Purge in Cloudflare Dashboard for the URLs above." >&2 +exit 1 diff --git a/scripts/deployment/sync-cybersecur-global-to-ct7810.sh b/scripts/deployment/sync-cybersecur-global-to-ct7810.sh new file mode 100755 index 00000000..75d846cb --- /dev/null +++ b/scripts/deployment/sync-cybersecur-global-to-ct7810.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Deploy CyberSecur-Global static site to CT 7810 (no direct SSH to container IP required). +# Uses SSH to Proxmox host + pct exec (same pattern as operator workflows). +# +# Prerequisites: SSH key to root@PROXMOX_HOST (default r630-02); CT 7810 running nginx with +# root /var/www/cybersecur-d-bis (see deploy/nginx-cybersecur-d-bis.conf.example in repo). +# +# Usage: +# CYBERSECUR_REPO=/path/to/CyberSecur-Global ./scripts/deployment/sync-cybersecur-global-to-ct7810.sh +# +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +# shellcheck disable=1091 +source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true + +REPO="${CYBERSECUR_REPO:-${PROJECT_ROOT}/../CyberSecur-Global}" +REPO="$(cd "$REPO" && pwd)" +PROXMOX_HOST="${CYBERSECUR_PROXMOX_HOST:-${PROXMOX_HOST_R630_02:-192.168.11.12}}" +VMID="${CYBERSECUR_VMID:-7810}" +REMOTE="${CYBERSECUR_REMOTE_PATH:-/var/www/cybersecur-d-bis}" + +if [[ ! -f "$REPO/index.html" ]]; then + echo "❌ CYBERSECUR_REPO must point to CyberSecur-Global clone (missing index.html): $REPO" >&2 + exit 1 +fi + +echo "Packing $REPO → root@${PROXMOX_HOST} pct exec $VMID → ${REMOTE}/" +( + cd "$REPO" + tar czf - \ + --exclude=.git \ + --exclude='deploy/*.sh' \ + . +) | ssh -o BatchMode=yes "root@${PROXMOX_HOST}" \ + "pct exec ${VMID} -- bash -c 'set -euo pipefail; mkdir -p ${REMOTE}; tar xzf - -C ${REMOTE}; chown -R www-data:www-data ${REMOTE}; nginx -t && systemctl reload nginx'" + +echo "✓ Deployed. Verify: curl -sSI https://cybersecur.d-bis.org/robots.txt https://cybersecur.d-bis.org/sitemap.xml https://cybersecur.d-bis.org/favicon.ico | head"