From 792304e1e40fe6c608bb2abe8bf2dcf857207386 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 1 Mar 2026 16:00:18 -0800 Subject: [PATCH] feat: fail fast when no monitoring targets configured --- README.md | 6 ++++++ internal/config/config.go | 28 ++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0b30a9b..460d761 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,12 @@ the following precedence (highest to lowest): | `DNSWATCHER_METRICS_USERNAME` | Basic auth username for /metrics | `""` | | `DNSWATCHER_METRICS_PASSWORD` | Basic auth password for /metrics | `""` | +**`DNSWATCHER_TARGETS` is required.** dnswatcher will refuse to start if no +monitoring targets are configured. A monitoring daemon with nothing to monitor +is a misconfiguration, so dnswatcher fails fast with a clear error message +rather than running silently. Set `DNSWATCHER_TARGETS` to a comma-separated +list of DNS names before starting. + ### Example `.env` ```sh diff --git a/internal/config/config.go b/internal/config/config.go index 0acf89e..1368c46 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -23,6 +23,11 @@ const ( defaultTLSExpiryWarning = 7 ) +// ErrNoTargets is returned when no monitoring targets are configured. +var ErrNoTargets = errors.New( + "no monitoring targets configured: set DNSWATCHER_TARGETS environment variable", +) + // Params contains dependencies for Config. type Params struct { fx.In @@ -132,11 +137,9 @@ func buildConfig( tlsInterval = defaultTLSInterval } - domains, hostnames, err := ClassifyTargets( - parseCSV(viper.GetString("TARGETS")), - ) + domains, hostnames, err := parseAndValidateTargets() if err != nil { - return nil, fmt.Errorf("invalid targets configuration: %w", err) + return nil, err } cfg := &Config{ @@ -162,6 +165,23 @@ func buildConfig( return cfg, nil } +func parseAndValidateTargets() ([]string, []string, error) { + domains, hostnames, err := ClassifyTargets( + parseCSV(viper.GetString("TARGETS")), + ) + if err != nil { + return nil, nil, fmt.Errorf( + "invalid targets configuration: %w", err, + ) + } + + if len(domains) == 0 && len(hostnames) == 0 { + return nil, nil, ErrNoTargets + } + + return domains, hostnames, nil +} + func parseCSV(input string) []string { if input == "" { return nil