coredns: auto-bump SOA serial (NN counter) on every make prep

Previously: `SERIAL=$(date +%Y%m%d)01` — same-day re-runs produced the
same serial. HE polled, saw no change, never pulled the update.

Now: scan zones-prepared/ for the highest `YYYYMMDDNN` matching today's
date and increment the NN counter. First run of the day starts at NN=01.
Caps at NN=99 with a clear error message (set SERIAL manually if you
genuinely need >99 changes per day).

`SERIAL=<value> make prep` still overrides the auto-detection, useful
for forcing a specific serial during recovery or for testing.

Verified end-to-end on dell01: prep bumped 2026051601 → 2026051602,
CoreDNS auto-reload picked it up within 30s, all queried zones serve
the new serial. HE will pull on its next refresh poll (SOA refresh
= 3600s, so worst case 1 hour).
This commit is contained in:
Ryan Malloy 2026-05-16 16:25:53 -06:00
parent 57c8366b7f
commit 87eaa27c4c

View File

@ -17,9 +17,37 @@ set -euo pipefail
SRC_DIR="${SRC_DIR:-zones}"
DST_DIR="${DST_DIR:-zones-prepared}"
SERIAL="${SERIAL:-$(date +%Y%m%d)01}"
ADMIN_EMAIL="${ADMIN_EMAIL:-admin}" # becomes admin.<zone>.
# Serial number generation — YYYYMMDDNN format (RFC 1912 §2.2).
#
# Strategy: every `make prep` run produces a strictly-increasing serial
# so that HE slaves notice the change on their next poll. If today's
# previous serials exist in zones-prepared/, increment the 2-digit
# counter. Otherwise start at NN=01.
#
# Honors an explicit override: `SERIAL=2026051699 make prep` skips the
# auto-detection.
TODAY=$(date +%Y%m%d)
if [[ -z "${SERIAL:-}" ]]; then
# Pull the highest YYYYMMDDNN serial from currently-prepared zones
# that starts with today's date. If none, default to NN=01.
highest=$(grep -hE '^[[:space:]]+'"${TODAY}"'[0-9]{2}[[:space:]]+;' "$DST_DIR"/*.zone 2>/dev/null \
| awk '{print $1}' | sort -un | tail -1)
if [[ -n "$highest" ]]; then
nn=$((10#${highest:8:2}))
next_nn=$((nn + 1))
if (( next_nn > 99 )); then
echo "ERROR: serial counter exhausted for ${TODAY} (NN=99 reached)." >&2
echo "Set SERIAL manually or wait until tomorrow." >&2
exit 1
fi
SERIAL=$(printf "%s%02d" "$TODAY" "$next_nn")
else
SERIAL="${TODAY}01"
fi
fi
# Public-facing nameservers (Hurricane Electric free secondary service).
# These appear in NS records inside every zone so that recursive
# resolvers fetching the zone learn the correct delegation.