check / check (push) Canceled after 0s
The resolver lists in FailedTypes each record type whose query to a nameserver got no usable reply (no reply, a code other than NOERROR or NXDOMAIN, a referral, or a truncated reply whose TCP retry failed) and logs it unless shutdown cut it short. A nameserver that answered no type has failed. The watcher saves such a type in failedTypes with the previous check's records, leaves it out of the comparison with other nameservers on that check, and compares it with the next answer. When the previous check did not know its records either, it is also in unknownTypes and not compared until it answers. A nameserver whose A, AAAA or CNAME query failed is no answer when following a CNAME or resolving addresses. Model: opus-5-5
128 lines
3.1 KiB
Go
128 lines
3.1 KiB
Go
package watcher
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"sneak.berlin/go/dnswatcher/internal/config"
|
|
"sneak.berlin/go/dnswatcher/internal/resolver"
|
|
"sneak.berlin/go/dnswatcher/internal/state"
|
|
)
|
|
|
|
// NewForTest creates a Watcher without fx for unit testing. A nil cfg
|
|
// is an empty configuration.
|
|
func NewForTest(
|
|
cfg *config.Config,
|
|
st *state.State,
|
|
res DNSResolver,
|
|
pc PortChecker,
|
|
tc TLSChecker,
|
|
n Notifier,
|
|
) *Watcher {
|
|
if cfg == nil {
|
|
cfg = &config.Config{}
|
|
}
|
|
|
|
return &Watcher{
|
|
log: slog.Default(),
|
|
config: cfg,
|
|
state: st,
|
|
resolver: res,
|
|
portCheck: pc,
|
|
tlsCheck: tc,
|
|
notify: n,
|
|
firstRun: true,
|
|
}
|
|
}
|
|
|
|
// SetLogger replaces the watcher's logger, so a test can read what it
|
|
// logs.
|
|
func (w *Watcher) SetLogger(log *slog.Logger) {
|
|
w.log = log
|
|
}
|
|
|
|
// NewlyDisagreeingPairs exports newlyDisagreeingPairs for testing.
|
|
func NewlyDisagreeingPairs(
|
|
prev, current *state.HostnameState,
|
|
) [][2]string {
|
|
return newlyDisagreeingPairs(prev, current)
|
|
}
|
|
|
|
// SetFirstRun sets whether the watcher is on its first check, in which
|
|
// nothing is compared with the previous check. NewForTest's watcher is.
|
|
func (w *Watcher) SetFirstRun(firstRun bool) {
|
|
w.firstRun = firstRun
|
|
}
|
|
|
|
// UpdateHostnameState exports updateHostnameState for testing.
|
|
func (w *Watcher) UpdateHostnameState(
|
|
ctx context.Context,
|
|
hostname string,
|
|
newState *state.HostnameState,
|
|
) {
|
|
w.updateHostnameState(ctx, hostname, newState)
|
|
}
|
|
|
|
// DetectHostnameChanges exports detectHostnameChanges for testing.
|
|
func (w *Watcher) DetectHostnameChanges(
|
|
ctx context.Context,
|
|
hostname string,
|
|
prev, current *state.HostnameState,
|
|
) {
|
|
w.detectHostnameChanges(ctx, hostname, prev, current)
|
|
}
|
|
|
|
// ResolveNameserverAddresses exports resolveNameserverAddresses for
|
|
// testing.
|
|
func (w *Watcher) ResolveNameserverAddresses(
|
|
ctx context.Context,
|
|
nameservers []string,
|
|
prev map[string][]string,
|
|
) map[string][]string {
|
|
return w.resolveNameserverAddresses(ctx, nameservers, prev)
|
|
}
|
|
|
|
// ResolveCNAMEAddresses exports resolveCNAMEAddresses for testing.
|
|
func (w *Watcher) ResolveCNAMEAddresses(
|
|
ctx context.Context,
|
|
hostname string,
|
|
current, prev *state.HostnameState,
|
|
) {
|
|
w.resolveCNAMEAddresses(ctx, hostname, current, prev)
|
|
}
|
|
|
|
// DetectNSAddressChanges exports detectNSAddressChanges for testing.
|
|
func (w *Watcher) DetectNSAddressChanges(
|
|
ctx context.Context,
|
|
domain string,
|
|
prev, current map[string][]string,
|
|
) {
|
|
w.detectNSAddressChanges(ctx, domain, prev, current)
|
|
}
|
|
|
|
// MaybeSendTestNotification exports maybeSendTestNotification for
|
|
// testing.
|
|
func (w *Watcher) MaybeSendTestNotification(ctx context.Context) {
|
|
w.maybeSendTestNotification(ctx)
|
|
}
|
|
|
|
// CheckAllPorts exports checkAllPorts for testing.
|
|
func (w *Watcher) CheckAllPorts(ctx context.Context) {
|
|
w.checkAllPorts(ctx)
|
|
}
|
|
|
|
// RunTLSChecks exports runTLSChecks for testing.
|
|
func (w *Watcher) RunTLSChecks(ctx context.Context) {
|
|
w.runTLSChecks(ctx)
|
|
}
|
|
|
|
// BuildHostnameState exports buildHostnameState for testing.
|
|
func BuildHostnameState(
|
|
results map[string]*resolver.NameserverResponse,
|
|
prev *state.HostnameState,
|
|
now time.Time,
|
|
) *state.HostnameState {
|
|
return buildHostnameState(results, prev, now)
|
|
}
|