watcher: a removed nameserver is an NS Change, not an NS Failure (closes #262)
check / check (push) Canceled after 0s

A nameserver that left a domain's delegation was reported twice: as the
domain's NS Change, and by the check of the domain's own records as an
error-level NS Failure saying it disappeared. That check now sends
nothing for a domain. For a hostname, the nameservers that leave its
zone are sent as one NS Change at warning level, with a Hostname: line
and a Removed: line, as decided on the issue; nothing is sent for one
that joins. The README says what each case gets.

A nameserver that was failing before it left is now listed too; the
NS Failure skipped it.
A domain with no delegation of its own gets nothing when a nameserver
leaves the zone it is in.

Model: opus-5-5
This commit is contained in:
2026-10-13 11:27:04 +00:00
parent e8b40062da
commit 79ab40a87b
5 changed files with 89 additions and 30 deletions
+3 -3
View File
@@ -1049,7 +1049,7 @@ func TestSendTestNotification_Disabled(t *testing.T) {
}
}
func TestNSFailureAndRecovery(t *testing.T) {
func TestNSChangeAndRecovery(t *testing.T) {
t.Parallel()
cfg := defaultTestConfig(t)
@@ -1059,7 +1059,7 @@ func TestNSFailureAndRecovery(t *testing.T) {
// The saved state has every nameserver live DNS lists as one that
// did not answer, and, as answering, one that live DNS does not
// list, which then disappears.
// list, which the check then finds removed.
_, deps := runChecks(t, cfg, func(deps *testDeps) {
byNameserver := map[string]*state.NameserverRecordState{
oldNS1: answered(map[string][]string{"A": {oldIP}}),
@@ -1071,7 +1071,7 @@ func TestNSFailureAndRecovery(t *testing.T) {
deps.state.SetHostnameState(testHost, saved(byNameserver))
})
assertNotified(t, deps, "NS Failure: "+testHost, "error")
assertNotified(t, deps, "NS Change: "+testHost, "warning")
assertNotified(t, deps, "NS Recovery: "+testHost, "success")
// A nameserver that did not answer has no records to compare, so