- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
195 lines
6.0 KiB
Bash
Executable File
195 lines
6.0 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Cloudflare Tunnel Configuration Script
|
|
|
|
# Load environment variables from .env if it exists
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
if [ -f "${SCRIPT_DIR}/../.env" ]; then
|
|
set -a
|
|
source <(grep -v '^#' "${SCRIPT_DIR}/../.env" | grep -v '^$' | sed 's/^/export /')
|
|
set +a
|
|
fi
|
|
|
|
CLOUDFLARE_API_TOKEN="${CLOUDFLARE_API_TOKEN:-}"
|
|
CLOUDFLARE_API_KEY="${CLOUDFLARE_API_KEY:-}"
|
|
CLOUDFLARE_EMAIL="${CLOUDFLARE_EMAIL:-}"
|
|
ZONE_ID="${CLOUDFLARE_ZONE_ID:-${ZONE_ID:-}}"
|
|
ACCOUNT_ID="${CLOUDFLARE_ACCOUNT_ID:-${ACCOUNT_ID:-}}"
|
|
|
|
log() {
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2
|
|
}
|
|
|
|
error() {
|
|
log "ERROR: $*"
|
|
exit 1
|
|
}
|
|
|
|
check_prerequisites() {
|
|
# Check authentication method
|
|
if [ -z "${CLOUDFLARE_API_TOKEN}" ] && [ -z "${CLOUDFLARE_API_KEY}" ]; then
|
|
error "Either CLOUDFLARE_API_TOKEN or CLOUDFLARE_API_KEY must be set"
|
|
fi
|
|
|
|
if [ -z "${CLOUDFLARE_API_TOKEN}" ] && [ -z "${CLOUDFLARE_EMAIL}" ]; then
|
|
error "If using CLOUDFLARE_API_KEY, CLOUDFLARE_EMAIL must also be set"
|
|
fi
|
|
|
|
if [ -z "${ACCOUNT_ID}" ]; then
|
|
warn "ACCOUNT_ID not set, attempting to get from API..."
|
|
get_account_id
|
|
fi
|
|
|
|
if ! command -v cloudflared &> /dev/null; then
|
|
error "cloudflared is not installed. Install it first."
|
|
fi
|
|
}
|
|
|
|
get_account_id() {
|
|
if [ -n "${CLOUDFLARE_API_TOKEN}" ]; then
|
|
ACCOUNT_ID=$(curl -s -X GET \
|
|
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/accounts" | \
|
|
jq -r '.result[0].id')
|
|
elif [ -n "${CLOUDFLARE_API_KEY}" ] && [ -n "${CLOUDFLARE_EMAIL}" ]; then
|
|
ACCOUNT_ID=$(curl -s -X GET \
|
|
-H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \
|
|
-H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \
|
|
-H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/accounts" | \
|
|
jq -r '.result[0].id')
|
|
fi
|
|
|
|
if [ -n "${ACCOUNT_ID}" ] && [ "${ACCOUNT_ID}" != "null" ]; then
|
|
log "Account ID: ${ACCOUNT_ID}"
|
|
export CLOUDFLARE_ACCOUNT_ID="${ACCOUNT_ID}"
|
|
else
|
|
error "Failed to get Account ID"
|
|
fi
|
|
}
|
|
|
|
create_tunnel() {
|
|
local tunnel_name=$1
|
|
|
|
log "Creating Cloudflare tunnel: ${tunnel_name}"
|
|
|
|
# Create tunnel via API
|
|
local auth_header
|
|
if [ -n "${CLOUDFLARE_API_TOKEN}" ]; then
|
|
TUNNEL_ID=$(curl -s -X POST \
|
|
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cfd_tunnel" \
|
|
-d "{\"name\":\"${tunnel_name}\",\"config_src\":\"local\"}" \
|
|
| jq -r '.result.id')
|
|
else
|
|
TUNNEL_ID=$(curl -s -X POST \
|
|
-H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \
|
|
-H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \
|
|
-H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cfd_tunnel" \
|
|
-d "{\"name\":\"${tunnel_name}\",\"config_src\":\"local\"}" \
|
|
| jq -r '.result.id')
|
|
fi
|
|
|
|
if [ -z "${TUNNEL_ID}" ] || [ "${TUNNEL_ID}" = "null" ]; then
|
|
error "Failed to create tunnel ${tunnel_name}"
|
|
fi
|
|
|
|
log "Tunnel created with ID: ${TUNNEL_ID}"
|
|
echo "${TUNNEL_ID}"
|
|
}
|
|
|
|
get_tunnel_token() {
|
|
local tunnel_id=$1
|
|
|
|
log "Getting tunnel token for ${tunnel_id}..."
|
|
|
|
TOKEN=$(curl -s -X GET \
|
|
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
|
|
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cfd_tunnel/${tunnel_id}/token" \
|
|
| jq -r '.result.token')
|
|
|
|
if [ -z "${TOKEN}" ] || [ "${TOKEN}" = "null" ]; then
|
|
error "Failed to get tunnel token"
|
|
fi
|
|
|
|
echo "${TOKEN}"
|
|
}
|
|
|
|
configure_dns() {
|
|
local hostname=$1
|
|
local tunnel_id=$2
|
|
|
|
log "Configuring DNS for ${hostname}..."
|
|
|
|
# Create CNAME record
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
|
|
-d "{
|
|
\"type\": \"CNAME\",
|
|
\"name\": \"${hostname}\",
|
|
\"content\": \"${tunnel_id}.cfargotunnel.com\",
|
|
\"ttl\": 1,
|
|
\"proxied\": true
|
|
}" > /dev/null
|
|
|
|
log "DNS record created for ${hostname}"
|
|
}
|
|
|
|
setup_control_plane_tunnel() {
|
|
log "Setting up control plane tunnel..."
|
|
|
|
TUNNEL_ID=$(create_tunnel "control-plane-tunnel")
|
|
TUNNEL_TOKEN=$(get_tunnel_token "${TUNNEL_ID}")
|
|
|
|
log "Control plane tunnel token: ${TUNNEL_TOKEN}"
|
|
log "Save this token securely and use it when running cloudflared on control plane nodes"
|
|
|
|
# Configure DNS for control plane services
|
|
configure_dns "portal" "${TUNNEL_ID}"
|
|
configure_dns "rancher" "${TUNNEL_ID}"
|
|
configure_dns "argocd" "${TUNNEL_ID}"
|
|
configure_dns "grafana" "${TUNNEL_ID}"
|
|
configure_dns "vault" "${TUNNEL_ID}"
|
|
configure_dns "keycloak" "${TUNNEL_ID}"
|
|
}
|
|
|
|
setup_proxmox_tunnels() {
|
|
local sites=("site-1" "site-2" "site-3")
|
|
|
|
for site in "${sites[@]}"; do
|
|
log "Setting up tunnel for ${site}..."
|
|
|
|
TUNNEL_ID=$(create_tunnel "proxmox-${site}-tunnel")
|
|
TUNNEL_TOKEN=$(get_tunnel_token "${TUNNEL_ID}")
|
|
|
|
log "${site} tunnel token: ${TUNNEL_TOKEN}"
|
|
log "Save this token and use it when running setup-proxmox-agents.sh on ${site} nodes"
|
|
done
|
|
}
|
|
|
|
main() {
|
|
log "Starting Cloudflare tunnel configuration..."
|
|
|
|
check_prerequisites
|
|
setup_control_plane_tunnel
|
|
setup_proxmox_tunnels
|
|
|
|
log ""
|
|
log "Cloudflare tunnel configuration completed!"
|
|
log ""
|
|
log "Next steps:"
|
|
log "1. Save all tunnel tokens securely"
|
|
log "2. Use tokens when running cloudflared on respective nodes"
|
|
log "3. Verify DNS records are created correctly"
|
|
log "4. Test tunnel connectivity"
|
|
}
|
|
|
|
main "$@"
|
|
|