watcher: a removed nameserver is an NS Change, not an NS Failure (closes #262)
check / check (push) Canceled after 0s
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. The check of a name's records now sends one NS Change at warning level, starting Hostname: or Domain:, listing the nameservers it was asked at before and not now. For a domain it leaves out those of its previous delegation, which the domain's own NS Change lists, so a domain's records are now checked before its new delegation is saved. Nothing is sent for a nameserver 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. Model: opus-5-5
This commit is contained in:
@@ -558,6 +558,9 @@ func TestDomainThatDoesNotExist(t *testing.T) {
|
||||
// nameservers and without nxdomain, and its records, asked at the
|
||||
// codeberg.page servers, are saved. Those are testSmallDomain's two
|
||||
// nameservers; github.io, the zone of the README's example, has eight.
|
||||
// The previous check saved a delegation to oldNS1, now withdrawn, and
|
||||
// records asked at oldNS1: the NS Change of its delegation removes
|
||||
// oldNS1, and no other NS Change lists it again.
|
||||
func TestDomainWithNoDelegationOfItsOwn(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -573,6 +576,15 @@ func TestDomainWithNoDelegationOfItsOwn(t *testing.T) {
|
||||
|
||||
w, deps = newTestWatcher(t, cfg)
|
||||
|
||||
deps.state.SetDomainState(domain, &state.DomainState{
|
||||
Nameservers: []string{oldNS1},
|
||||
})
|
||||
deps.state.SetHostnameState(domain, saved(
|
||||
map[string]*state.NameserverRecordState{
|
||||
oldNS1: answered(map[string][]string{"A": {oldIP}}),
|
||||
},
|
||||
))
|
||||
|
||||
err := checkOnce(ctx, w, deps)
|
||||
|
||||
// A domain saved as not existing has no records to wait for;
|
||||
@@ -593,6 +605,22 @@ func TestDomainWithNoDelegationOfItsOwn(t *testing.T) {
|
||||
if _, ok := deps.state.GetHostnameState(domain); !ok {
|
||||
t.Errorf("no records saved for %s", domain)
|
||||
}
|
||||
|
||||
title := "NS Change: " + domain
|
||||
want := "Domain: " + domain + "\nAdded: \nRemoved: " + oldNS1
|
||||
|
||||
var changes []notification
|
||||
|
||||
for _, n := range deps.notifier.getNotifications() {
|
||||
if n.Title == title {
|
||||
changes = append(changes, n)
|
||||
}
|
||||
}
|
||||
|
||||
if len(changes) != 1 || changes[0].Message != want {
|
||||
t.Errorf("sent %v, want one %q with message:\n%s",
|
||||
changes, title, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNSAddressChangeDetection(t *testing.T) {
|
||||
@@ -1049,7 +1077,7 @@ func TestSendTestNotification_Disabled(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNSFailureAndRecovery(t *testing.T) {
|
||||
func TestNSChangeAndRecovery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := defaultTestConfig(t)
|
||||
@@ -1059,7 +1087,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 +1099,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
|
||||
|
||||
Reference in New Issue
Block a user