diff --git a/tools/edge-control/install.sh b/tools/edge-control/install.sh index 68880ab..fcd33b9 100755 --- a/tools/edge-control/install.sh +++ b/tools/edge-control/install.sh @@ -225,8 +225,11 @@ EOF chmod 600 "$GANDI_ENV" # Create Caddyfile with admin API and wildcard cert +# Note: Caddy auto-generates server names (srv0, srv1, …). lib/caddy.sh +# discovers the server name dynamically via _discover_server_name() so we +# don't need to name the server here. CADDYFILE="/etc/caddy/Caddyfile" -cat > "$CADDYFILE" < "$CADDYFILE" <<'CADDYEOF' # Caddy configuration for edge control plane # Admin API enabled on 127.0.0.1:2019 @@ -240,7 +243,7 @@ cat > "$CADDYFILE" </dev/null || { diff --git a/tools/edge-control/lib/caddy.sh b/tools/edge-control/lib/caddy.sh index 69970cf..1e16cdc 100755 --- a/tools/edge-control/lib/caddy.sh +++ b/tools/edge-control/lib/caddy.sh @@ -19,6 +19,24 @@ CADDY_ADMIN_URL="${CADDY_ADMIN_URL:-http://127.0.0.1:2019}" # Domain suffix for projects DOMAIN_SUFFIX="${DOMAIN_SUFFIX:-disinto.ai}" +# Discover the Caddy server name that listens on :80/:443 +# Usage: _discover_server_name +_discover_server_name() { + local server_name + server_name=$(curl -sS "${CADDY_ADMIN_URL}/config/apps/http/servers" \ + | jq -r 'to_entries | map(select(.value.listen[]? | test(":(80|443)$"))) | .[0].key // empty') || { + echo "Error: could not query Caddy admin API for servers" >&2 + return 1 + } + + if [ -z "$server_name" ]; then + echo "Error: could not find a Caddy server listening on :80/:443" >&2 + return 1 + fi + + echo "$server_name" +} + # Add a route for a project # Usage: add_route add_route() { @@ -26,6 +44,9 @@ add_route() { local port="$2" local fqdn="${project}.${DOMAIN_SUFFIX}" + local server_name + server_name=$(_discover_server_name) || return 1 + # Build the route configuration (partial config) local route_config route_config=$(cat <&1) || { + -d "$route_config") || { echo "Error: failed to add route for ${fqdn}" >&2 - echo "Response: ${response}" >&2 return 1 } + status=$(echo "$response" | tail -n1) + body=$(echo "$response" | sed '$d') + if [ "$status" -ge 400 ]; then + echo "Error: Caddy admin API returned ${status}: ${body}" >&2 + return 1 + fi echo "Added route: ${fqdn} → 127.0.0.1:${port}" >&2 } @@ -78,31 +104,45 @@ remove_route() { local project="$1" local fqdn="${project}.${DOMAIN_SUFFIX}" - # First, get current routes - local routes_json - routes_json=$(curl -s "${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes" 2>&1) || { + local server_name + server_name=$(_discover_server_name) || return 1 + + # First, get current routes, checking HTTP status + local response status body + response=$(curl -sS -w '\n%{http_code}' \ + "${CADDY_ADMIN_URL}/config/apps/http/servers/${server_name}/routes") || { echo "Error: failed to get current routes" >&2 return 1 } + status=$(echo "$response" | tail -n1) + body=$(echo "$response" | sed '$d') + if [ "$status" -ge 400 ]; then + echo "Error: Caddy admin API returned ${status}: ${body}" >&2 + return 1 + fi # Find the route index that matches our fqdn using jq local route_index - route_index=$(echo "$routes_json" | jq -r "to_entries[] | select(.value.match[]?.host[]? == \"${fqdn}\") | .key" 2>/dev/null | head -1) + route_index=$(echo "$body" | jq -r "to_entries[] | select(.value.match[]?.host[]? == \"${fqdn}\") | .key" 2>/dev/null | head -1) if [ -z "$route_index" ] || [ "$route_index" = "null" ]; then echo "Warning: route for ${fqdn} not found" >&2 return 0 fi - # Delete the route at the found index - local response - response=$(curl -s -X DELETE \ - "${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes/${route_index}" \ - -H "Content-Type: application/json" 2>&1) || { + # Delete the route at the found index, checking HTTP status + response=$(curl -sS -w '\n%{http_code}' -X DELETE \ + "${CADDY_ADMIN_URL}/config/apps/http/servers/${server_name}/routes/${route_index}" \ + -H "Content-Type: application/json") || { echo "Error: failed to remove route for ${fqdn}" >&2 - echo "Response: ${response}" >&2 return 1 } + status=$(echo "$response" | tail -n1) + body=$(echo "$response" | sed '$d') + if [ "$status" -ge 400 ]; then + echo "Error: Caddy admin API returned ${status}: ${body}" >&2 + return 1 + fi echo "Removed route: ${fqdn}" >&2 } @@ -110,13 +150,18 @@ remove_route() { # Reload Caddy to apply configuration changes # Usage: reload_caddy reload_caddy() { - local response - response=$(curl -s -X POST \ - "${CADDY_ADMIN_URL}/reload" 2>&1) || { + local response status body + response=$(curl -sS -w '\n%{http_code}' -X POST \ + "${CADDY_ADMIN_URL}/reload") || { echo "Error: failed to reload Caddy" >&2 - echo "Response: ${response}" >&2 return 1 } + status=$(echo "$response" | tail -n1) + body=$(echo "$response" | sed '$d') + if [ "$status" -ge 400 ]; then + echo "Error: Caddy reload returned ${status}: ${body}" >&2 + return 1 + fi echo "Caddy reloaded" >&2 }