#!/bin/bash if [ "$EUID" -ne 0 ]; then echo "This script must be run as root. Try using 'sudo'." exit 1 fi source /home/sij/.zshrc source /home/sij/.GLOBAL_VARS ddns # Initialize variables full_domain=$1 shift # Shift the arguments to left so we can get remaining arguments as before caddyIP="" # Optional IP for Caddyfile port="" # Fixed IP for Cloudflare from ip.txt cloudflareIP=$(cat /home/sij/.services/ip.txt) api_key=$CF_API_KEY cf_domains_file=/home/sij/.services/cf_domains.json # Usage message usage() { echo "Usage: $0 [--ip ] --port " echo "Note: is required and can be a subdomain or a full domain." exit 1 } # Parse command-line arguments while [[ $# -gt 0 ]]; do case $1 in --ip|-i) caddyIP="$2" shift 2 ;; --port|-p) port="$2" shift 2 ;; *) usage ;; esac done # Check required parameter if [[ -z "$full_domain" ]] || [[ -z "$port" ]]; then usage fi # Extract subdomain and domain subdomain=$(echo "$full_domain" | awk -F"." '{print $1}') remaining_parts=$(echo "$full_domain" | awk -F"." '{print NF}') if [ "$remaining_parts" -eq 2 ]; then # Handle root domain (e.g., env.esq) domain=$full_domain subdomain="@" # Use "@" for root domain else # Handle subdomain (e.g., sub.env.esq) domain=$(echo "$full_domain" | sed "s/^$subdomain\.//") fi # Default to localhost for Caddyfile if IP is not provided via --ip if [[ -z "$caddyIP" ]]; then caddyIP="localhost" fi # Extract zone_id from JSON file zone_id=$(jq -r ".\"$domain\".zone_id" "$cf_domains_file") # Check if zone_id was successfully retrieved if [ "$zone_id" == "null" ] || [ -z "$zone_id" ]; then echo "Error: Zone ID for $domain could not be found." exit 1 fi # API call setup for Cloudflare A record using the fixed IP from ip.txt endpoint="https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records" data="{\"type\":\"A\",\"name\":\"$subdomain\",\"content\":\"$cloudflareIP\",\"ttl\":120,\"proxied\":true}" # Make API call response=$(curl -s -X POST "$endpoint" -H "Authorization: Bearer $api_key" -H "Content-Type: application/json" --data "$data") # Parse response record_id=$(echo "$response" | jq -r '.result.id') success=$(echo "$response" | jq -r '.success') error_message=$(echo "$response" | jq -r '.errors[0].message') error_code=$(echo "$response" | jq -r '.errors[0].code') # Function to update Caddyfile with correct indentation update_caddyfile() { echo "$full_domain { reverse_proxy $caddyIP:$port tls { dns cloudflare {env.CLOUDFLARE_API_TOKEN} } }" >> /etc/caddy/Caddyfile echo "Configuration appended to /etc/caddy/Caddyfile with correct formatting." } # Check for success or specific error to update Caddyfile if [ "$success" == "true" ]; then jq ".\"$domain\".subdomains[\"$full_domain\"] = \"$record_id\"" "$cf_domains_file" > temp.json && mv temp.json "$cf_domains_file" echo "A record created and cf_domains.json updated successfully." update_caddyfile elif [ "$error_message" == "Record already exists." ]; then echo "Record already exists. Updating Caddyfile anyway." update_caddyfile else echo "Failed to create A record. Error: $error_message (Code: $error_code)" fi echo "Restarting caddy!" sudo systemctl restart caddy