Founder rule: every Technitium/DNS/DHCP change ends with a same-session SoR sync — zone-snapshot.sh then drift-check green, then commit. Added the tool (tar-pulls the DZ store from the primary via the chokepoint), wrote the rule into AGENTS.md (DNS change discipline + Key Scripts rows), refreshed 4 stale snapshots (knel.net, 1/3.168.192 reverse, 119.70.100 — incl. the deleted ultix-offstage PTR). drift-check: ALL IN SYNC. Also: last tsrouter mentions retired (AGENTS.md, setup.sh header).
This commit is contained in:
@@ -378,7 +378,7 @@ vendor/ Vendored KNELShellFramework
|
||||
through the chokepoint scripts — [`tests/remote.sh`](tests/remote.sh)
|
||||
(Proxmox hosts + all VMs) or
|
||||
[`netinfra/dns-cluster-setup/remote-dns.sh`](netinfra/dns-cluster-setup/remote-dns.sh)
|
||||
(DNS infra hosts: netinfra-01/02, tsrouter, netboot). NEVER call
|
||||
(DNS infra hosts: netinfra-01/02, netboot). NEVER call
|
||||
`ssh`/`scp` directly — the harness blocks raw ssh and the command scanner
|
||||
rejects it. There are no exceptions.
|
||||
- **DNS names ONLY (NON-NEGOTIABLE):** NEVER use IP address literals
|
||||
@@ -444,6 +444,19 @@ an AWX playbook item.** The fleet converges to 100% IaC (founder mandate,
|
||||
- New manual fixes during incidents: fix first, codify immediately after.
|
||||
- Playbooks live in this repo, tested through the `sectestbed-*` fleet.
|
||||
|
||||
## DNS change discipline (NON-NEGOTIABLE)
|
||||
|
||||
**Any change to Technitium records/zones (dns-cli or API), dhcpd, or the
|
||||
live DNS/DHCP configs MUST end with a same-session git SoR sync.**
|
||||
Founder rule, 2026-09-02 — drift-check exists because git went stale; do
|
||||
not reopen that gap:
|
||||
|
||||
1. Make the change (serial + health-gated across the redundant pair).
|
||||
2. `bash netinfra/dns/technitium/zone-snapshot.sh` — refresh the DZ
|
||||
snapshots from the primary.
|
||||
3. `bash netinfra/dns/drift-check.sh` — must print `ALL IN SYNC`.
|
||||
4. Commit + push the refreshed snapshots in the same session.
|
||||
|
||||
## Redmine Tracking Policy
|
||||
|
||||
**Redmine is the system of record for all work.** Do not track status,
|
||||
@@ -570,7 +583,9 @@ live in the centralized store at `~/.creds/discourse.env`.
|
||||
| [`scripts/check-rules.sh`](scripts/check-rules.sh) | Rule audit engine (shellcheck, image pinning, Discourse pointers, required files) |
|
||||
| [`scripts/setup-hooks.sh`](scripts/setup-hooks.sh) | Install git hooks (pre-commit, pre-push) |
|
||||
| [`tests/remote.sh`](tests/remote.sh) | **SSH chokepoint** — all Proxmox host + sandbox VM access routes here |
|
||||
| [`netinfra/dns-cluster-setup/remote-dns.sh`](netinfra/dns-cluster-setup/remote-dns.sh) | SSH chokepoint for DNS infra hosts (netinfra-01/02, tsrouter, netboot) |
|
||||
| [`netinfra/dns-cluster-setup/remote-dns.sh`](netinfra/dns-cluster-setup/remote-dns.sh) | SSH chokepoint for DNS infra hosts (netinfra-01/02, netboot) |
|
||||
| [`netinfra/dns/technitium/zone-snapshot.sh`](netinfra/dns/technitium/zone-snapshot.sh) | Refresh git SoR Technitium zone snapshots from the primary — **required after every DNS change** |
|
||||
| [`netinfra/dns/drift-check.sh`](netinfra/dns/drift-check.sh) | Live-vs-git drift audit for DHCP/DNS/NTP/zones — must be green before any DNS-adjacent push |
|
||||
| `redmine-cli` container | Redmine CLI (ticket read/write via `docker run`; see `tooling-cli/redmine/`) |
|
||||
| `discourse-cli` container | Discourse CLI (wiki topic read/write via `docker run`; see `tooling-cli/discourse/`) |
|
||||
| `dns-cli` container | Technitium DNS CLI (zones, list, add, delete, search, flush; see `tooling-cli/dns/`) |
|
||||
|
||||
@@ -116,7 +116,8 @@ api_call() {
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Step 1: Export production config (READ-ONLY on tailscale-router)
|
||||
# Step 1: Export production config (READ-ONLY on the primary; historically
|
||||
# the retired tailscale-router)
|
||||
# -----------------------------------------------------------------------------
|
||||
do_export() {
|
||||
log "=== STEP 1: Exporting production config from $PROD (READ-ONLY) ==="
|
||||
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/bash
|
||||
#
|
||||
# zone-snapshot.sh — refresh the git SoR snapshot of the Technitium zone
|
||||
# store [#630][#728]
|
||||
#
|
||||
# Pulls the binary DZ zone files from netinfra-01 (the replication primary)
|
||||
# into netinfra/dns/technitium/zones/ via the remote-dns.sh chokepoint, then
|
||||
# shows which snapshot files changed.
|
||||
#
|
||||
# RULE (founder, 2026-09-02): run this after EVERY Technitium record change
|
||||
# and commit the refreshed snapshots in the same session, so the git SoR
|
||||
# never goes stale. netinfra/dns/drift-check.sh verifies the result; the
|
||||
# pre-push rule audit fails on a stale questions file and drift-check is the
|
||||
# DNS counterpart: green before you push any DNS-adjacent change.
|
||||
#
|
||||
# Usage:
|
||||
# zone-snapshot.sh refresh snapshots from the primary
|
||||
# zone-snapshot.sh --check verify only (delegates to drift-check.sh)
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # netinfra/dns/technitium
|
||||
REPO="$(cd "$HERE/../../.." && pwd)"
|
||||
REMOTE_DNS="$HERE/../../dns-cluster-setup/remote-dns.sh"
|
||||
ZONES_DIR="$HERE/zones"
|
||||
REMOTE_ZONE_DIR="/home/localuser/services/technitium/config/zones"
|
||||
|
||||
if [ "${1:-}" = "--check" ]; then
|
||||
exec bash "$HERE/../drift-check.sh"
|
||||
fi
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
echo "Fetching zone store from netinfra-01 (primary)..."
|
||||
bash "$REMOTE_DNS" netinfra01-root "cd '$REMOTE_ZONE_DIR' && tar cf - *.zone" > "$tmp/zones.tar"
|
||||
|
||||
# Validate the archive before touching the tracked tree.
|
||||
tar -tf "$tmp/zones.tar" >/dev/null
|
||||
|
||||
mkdir -p "$ZONES_DIR"
|
||||
find "$ZONES_DIR" -maxdepth 1 -name '*.zone' -delete
|
||||
tar -xf "$tmp/zones.tar" -C "$ZONES_DIR"
|
||||
|
||||
count="$(find "$ZONES_DIR" -maxdepth 1 -name '*.zone' | wc -l)"
|
||||
echo "Snapshotted $count zone files into ${ZONES_DIR#"$REPO"/}"
|
||||
|
||||
echo "Changed snapshot files (git):"
|
||||
changed="$(git -C "$REPO" status --porcelain -- "$ZONES_DIR")"
|
||||
if [ -n "$changed" ]; then
|
||||
printf '%s\n' "$changed" | sed "s|^$REPO/||" | head -20
|
||||
printf '%s\n' "$changed" | wc -l | xargs -I{} echo "{} files changed — commit these in the same session (DNS sync rule)"
|
||||
else
|
||||
echo " (none — snapshots were already current)"
|
||||
fi
|
||||
|
||||
echo "Verify with: netinfra/dns/drift-check.sh"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user