Files
Sankofa/scripts/setup-dns-records.sh
defiQUG 9daf1fd378 Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- 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
2025-12-12 18:01:35 -08:00

285 lines
8.6 KiB
Bash
Executable File

#!/bin/bash
# setup-dns-records.sh
# Creates DNS records for Proxmox instances using Cloudflare API
set -euo pipefail
# Load environment variables from .env if it exists
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "${SCRIPT_DIR}/../.env" ]; then
source "${SCRIPT_DIR}/../.env"
fi
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
DOMAIN="${DOMAIN:-sankofa.nexus}"
ZONE_ID="${CLOUDFLARE_ZONE_ID:-}"
# Support both API Token and Global API Key + Email
API_TOKEN="${CLOUDFLARE_API_TOKEN:-}"
API_KEY="${CLOUDFLARE_API_KEY:-}"
API_EMAIL="${CLOUDFLARE_EMAIL:-}"
# Instance configurations
declare -A INSTANCES=(
["ml110-01"]="192.168.11.10"
["r630-01"]="192.168.11.11"
)
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
exit 1
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
check_requirements() {
# Check if we have either API Token or Global API Key + Email
if [ -z "$API_TOKEN" ] && [ -z "$API_KEY" ]; then
error "Either CLOUDFLARE_API_TOKEN or CLOUDFLARE_API_KEY must be set"
fi
if [ -z "$API_TOKEN" ] && [ -z "$API_EMAIL" ]; then
error "If using CLOUDFLARE_API_KEY, CLOUDFLARE_EMAIL must also be set"
fi
if ! command -v curl &> /dev/null; then
error "curl is required but not installed"
fi
if ! command -v jq &> /dev/null; then
error "jq is required but not installed"
fi
# Try to get zone ID if not provided
if [ -z "$ZONE_ID" ]; then
get_zone_id
fi
}
get_zone_id() {
if [ -z "$ZONE_ID" ]; then
log "Getting zone ID for ${DOMAIN}..."
if [ -n "$API_TOKEN" ]; then
# Use API Token
ZONE_ID=$(curl -s -X GET \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones?name=${DOMAIN}" | \
jq -r '.result[0].id')
elif [ -n "$API_KEY" ] && [ -n "$API_EMAIL" ]; then
# Use Global API Key + Email
ZONE_ID=$(curl -s -X GET \
-H "X-Auth-Email: ${API_EMAIL}" \
-H "X-Auth-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones?name=${DOMAIN}" | \
jq -r '.result[0].id')
else
error "Cannot get Zone ID: No authentication method available"
fi
if [ "$ZONE_ID" == "null" ] || [ -z "$ZONE_ID" ]; then
error "Failed to get zone ID for ${DOMAIN}"
fi
log "Zone ID: ${ZONE_ID}"
export CLOUDFLARE_ZONE_ID="$ZONE_ID"
fi
}
create_a_record() {
local name=$1
local ip=$2
local comment=$3
log "Creating A record: ${name}.${DOMAIN}${ip}"
local response
if [ -n "$API_TOKEN" ]; then
response=$(curl -s -X POST \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-d "{
\"type\": \"A\",
\"name\": \"${name}\",
\"content\": \"${ip}\",
\"ttl\": 300,
\"comment\": \"${comment}\",
\"proxied\": false
}")
else
response=$(curl -s -X POST \
-H "X-Auth-Email: ${API_EMAIL}" \
-H "X-Auth-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-d "{
\"type\": \"A\",
\"name\": \"${name}\",
\"content\": \"${ip}\",
\"ttl\": 300,
\"comment\": \"${comment}\",
\"proxied\": false
}")
fi
local success=$(echo "$response" | jq -r '.success')
local record_id=$(echo "$response" | jq -r '.result.id // empty')
if [ "$success" == "true" ] && [ -n "$record_id" ]; then
log "✓ A record created: ${name}.${DOMAIN} (ID: ${record_id})"
return 0
else
local errors=$(echo "$response" | jq -r '.errors[].message // "Unknown error"' | head -1)
warn "Failed to create A record: ${errors}"
return 1
fi
}
create_cname_record() {
local name=$1
local target=$2
local comment=$3
log "Creating CNAME record: ${name}.${DOMAIN}${target}"
local response
if [ -n "$API_TOKEN" ]; then
response=$(curl -s -X POST \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-d "{
\"type\": \"CNAME\",
\"name\": \"${name}\",
\"content\": \"${target}\",
\"ttl\": 300,
\"comment\": \"${comment}\",
\"proxied\": false
}")
else
response=$(curl -s -X POST \
-H "X-Auth-Email: ${API_EMAIL}" \
-H "X-Auth-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-d "{
\"type\": \"CNAME\",
\"name\": \"${name}\",
\"content\": \"${target}\",
\"ttl\": 300,
\"comment\": \"${comment}\",
\"proxied\": false
}")
fi
local success=$(echo "$response" | jq -r '.success')
local record_id=$(echo "$response" | jq -r '.result.id // empty')
if [ "$success" == "true" ] && [ -n "$record_id" ]; then
log "✓ CNAME record created: ${name}.${DOMAIN} (ID: ${record_id})"
return 0
else
local errors=$(echo "$response" | jq -r '.errors[].message // "Unknown error"' | head -1)
warn "Failed to create CNAME record: ${errors}"
return 1
fi
}
check_record_exists() {
local name=$1
local type=$2
local response
if [ -n "$API_TOKEN" ]; then
response=$(curl -s -X GET \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${name}.${DOMAIN}&type=${type}")
else
response=$(curl -s -X GET \
-H "X-Auth-Email: ${API_EMAIL}" \
-H "X-Auth-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${name}.${DOMAIN}&type=${type}")
fi
local count=$(echo "$response" | jq -r '.result | length')
if [ "$count" -gt 0 ]; then
return 0 # Record exists
else
return 1 # Record does not exist
fi
}
setup_instance_dns() {
local instance_name=$1
local ip=$2
local fqdn="${instance_name}.${DOMAIN}"
# Create A record
if check_record_exists "$instance_name" "A"; then
warn "A record for ${fqdn} already exists, skipping..."
else
create_a_record "$instance_name" "$ip" "Proxmox Instance - ${instance_name}"
fi
# Create API CNAME
if check_record_exists "${instance_name}-api" "CNAME"; then
warn "CNAME record for ${instance_name}-api.${DOMAIN} already exists, skipping..."
else
create_cname_record "${instance_name}-api" "$fqdn" "Proxmox ${instance_name} API endpoint"
fi
# Create metrics CNAME
if check_record_exists "${instance_name}-metrics" "CNAME"; then
warn "CNAME record for ${instance_name}-metrics.${DOMAIN} already exists, skipping..."
else
create_cname_record "${instance_name}-metrics" "$fqdn" "Proxmox ${instance_name} metrics endpoint"
fi
}
main() {
log "Setting up DNS records for Proxmox instances"
log "Domain: ${DOMAIN}"
check_requirements
get_zone_id
log ""
log "Creating DNS records for ${#INSTANCES[@]} instances..."
log ""
for instance_name in "${!INSTANCES[@]}"; do
setup_instance_dns "$instance_name" "${INSTANCES[$instance_name]}"
echo ""
done
log "DNS setup complete!"
log ""
log "Created records:"
for instance_name in "${!INSTANCES[@]}"; do
echo "${instance_name}.${DOMAIN}${INSTANCES[$instance_name]}"
echo "${instance_name}-api.${DOMAIN}${instance_name}.${DOMAIN}"
echo "${instance_name}-metrics.${DOMAIN}${instance_name}.${DOMAIN}"
done
}
main "$@"