Commit e7c5b5420d06
Changed files (1)
tools
tools/update-gandi-dns.sh
@@ -85,21 +85,23 @@ fi
echo -e "${GREEN}Found $(echo "$RECORDS" | wc -l) A records to process${RESET}"
echo
-# Get current DNS records from Gandi
-if [[ "$DRY_RUN" == "false" ]]; then
- echo -e "${CYAN}Fetching current DNS records from Gandi...${RESET}"
- CURRENT_RECORDS=$(curl -s \
- -H "Authorization: Bearer $GANDIV5_PERSONAL_TOKEN" \
- "$API_URL" || echo "[]")
+# Get current DNS records from Gandi (needed for both update and removal detection)
+echo -e "${CYAN}Fetching current DNS records from Gandi...${RESET}"
+CURRENT_RECORDS=$(curl -s \
+ -H "Authorization: Bearer $GANDIV5_PERSONAL_TOKEN" \
+ "$API_URL" || echo "[]")
- echo -e "${GREEN}Current records fetched${RESET}"
- echo
-fi
+echo -e "${GREEN}Current records fetched${RESET}"
+echo
# Process each record
UPDATED=0
SKIPPED=0
FAILED=0
+DELETED=0
+
+# Track all desired A record names from Nix config
+declare -A DESIRED_NAMES
while IFS= read -r line; do
# Parse the line to extract: name, TTL, and value
@@ -121,15 +123,20 @@ while IFS= read -r line; do
VALUE=$(echo "$line" | awk '{print $4}')
fi
- # Remove .sbr.pm. suffix and convert to Gandi format
- NAME="${FULL_NAME%.sbr.pm.}"
-
- # Convert wildcard format: *.name -> *.name (Gandi uses this format)
- # Convert root wildcard: * -> @ (Gandi's root wildcard)
- if [[ "$NAME" == "*" ]]; then
+ # Convert FQDN to Gandi record name
+ # - "sbr.pm." (apex) → "@"
+ # - "name.sbr.pm." → "name"
+ # - "*.sbr.pm." → "*"
+ # - "*.name.sbr.pm." → "*.name"
+ if [[ "$FULL_NAME" == "sbr.pm." ]]; then
NAME="@"
+ else
+ NAME="${FULL_NAME%.sbr.pm.}"
fi
+ # Track this name as desired
+ DESIRED_NAMES["$NAME"]=1
+
echo -e "${BLUE}Processing: ${RESET}$NAME.$DOMAIN A $VALUE (TTL: $TTL)"
if [[ "$DRY_RUN" == "true" ]]; then
@@ -178,11 +185,55 @@ while IFS= read -r line; do
echo
done <<< "$RECORDS"
+# Remove stale A records from Gandi that are no longer in Nix config
+echo -e "${BOLD}${BLUE}Checking for stale A records to remove...${RESET}"
+echo
+
+GANDI_A_NAMES=$(echo "$CURRENT_RECORDS" | jq -r '.[] | select(.rrset_type == "A") | .rrset_name' 2>/dev/null || true)
+
+while IFS= read -r gandi_name; do
+ [[ -z "$gandi_name" ]] && continue
+
+ if [[ -z "${DESIRED_NAMES[$gandi_name]+_}" ]]; then
+ GANDI_VALUE=$(echo "$CURRENT_RECORDS" | jq -r \
+ --arg name "$gandi_name" \
+ '.[] | select(.rrset_name == $name and .rrset_type == "A") | .rrset_values | join(", ")' \
+ 2>/dev/null || echo "unknown")
+
+ echo -e "${RED}Stale record: ${RESET}$gandi_name.$DOMAIN A $GANDI_VALUE"
+
+ if [[ "$DRY_RUN" == "true" ]]; then
+ echo -e " ${CYAN}[DRY RUN] Would delete record${RESET}"
+ DELETED=$((DELETED + 1))
+ else
+ RESPONSE=$(curl -s -w "\n%{http_code}" \
+ -X DELETE \
+ -H "Authorization: Bearer $GANDIV5_PERSONAL_TOKEN" \
+ "$API_URL/$gandi_name/A")
+
+ HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
+ BODY=$(echo "$RESPONSE" | sed '$d')
+
+ if [[ "$HTTP_CODE" == "204" ]] || [[ "$HTTP_CODE" == "200" ]]; then
+ echo -e " ${GREEN}✓ Record deleted successfully${RESET}"
+ DELETED=$((DELETED + 1))
+ else
+ echo -e " ${RED}✗ Failed to delete record (HTTP $HTTP_CODE)${RESET}"
+ echo -e " ${RED}Response: $BODY${RESET}"
+ FAILED=$((FAILED + 1))
+ fi
+ fi
+
+ echo
+ fi
+done <<< "$GANDI_A_NAMES"
+
echo -e "${BOLD}${GREEN}DNS update complete!${RESET}"
echo
echo -e "${CYAN}Summary:${RESET}"
echo -e " Updated: $UPDATED"
echo -e " Skipped (unchanged): $SKIPPED"
+echo -e " Deleted: $DELETED"
if [[ $FAILED -gt 0 ]]; then
echo -e " ${RED}Failed: $FAILED${RESET}"
fi