feat: unify DOMAINS/HOSTNAMES into single TARGETS config
Replace DNSWATCHER_DOMAINS and DNSWATCHER_HOSTNAMES with a single DNSWATCHER_TARGETS env var. Names are automatically classified as apex domains or hostnames using the Public Suffix List (golang.org/x/net/publicsuffix). - ClassifyDNSName() uses EffectiveTLDPlusOne to determine type - Public suffixes themselves (e.g. co.uk) are rejected with an error - Old DOMAINS/HOSTNAMES vars removed entirely (pre-1.0, no compat needed) - README updated with pre-1.0 warning Closes #10
This commit is contained in:
83
internal/config/classify_test.go
Normal file
83
internal/config/classify_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package config_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"sneak.berlin/go/dnswatcher/internal/config"
|
||||
)
|
||||
|
||||
func TestClassifyDNSName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
want config.DNSNameType
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "apex domain simple", input: "example.com", want: config.DNSNameTypeDomain},
|
||||
{name: "hostname simple", input: "www.example.com", want: config.DNSNameTypeHostname},
|
||||
{name: "apex domain multi-part TLD", input: "example.co.uk", want: config.DNSNameTypeDomain},
|
||||
{name: "hostname multi-part TLD", input: "api.example.co.uk", want: config.DNSNameTypeHostname},
|
||||
{name: "public suffix itself", input: "co.uk", wantErr: true},
|
||||
{name: "empty string", input: "", wantErr: true},
|
||||
{name: "deeply nested hostname", input: "a.b.c.example.com", want: config.DNSNameTypeHostname},
|
||||
{name: "trailing dot stripped", input: "example.com.", want: config.DNSNameTypeDomain},
|
||||
{name: "uppercase normalized", input: "WWW.Example.COM", want: config.DNSNameTypeHostname},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, err := config.ClassifyDNSName(tt.input)
|
||||
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("ClassifyDNSName(%q) expected error, got %v", tt.input, got)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("ClassifyDNSName(%q) unexpected error: %v", tt.input, err)
|
||||
}
|
||||
|
||||
if got != tt.want {
|
||||
t.Errorf("ClassifyDNSName(%q) = %v, want %v", tt.input, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
domains, hostnames, err := config.ClassifyTargets([]string{
|
||||
"example.com",
|
||||
"www.example.com",
|
||||
"example.co.uk",
|
||||
"api.example.co.uk",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(domains) != 2 {
|
||||
t.Errorf("expected 2 domains, got %d: %v", len(domains), domains)
|
||||
}
|
||||
|
||||
if len(hostnames) != 2 {
|
||||
t.Errorf("expected 2 hostnames, got %d: %v", len(hostnames), hostnames)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifyTargetsRejectsPublicSuffix(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, _, err := config.ClassifyTargets([]string{"co.uk"})
|
||||
if err == nil {
|
||||
t.Error("expected error for public suffix, got nil")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user