Publish DHCP clients' names in DNS
router-webui leases-dns reads Kea's leases and publishes <name>.<domain> with reverse records in the running Unbound (router.dns.dynamicLeases). Names the configuration publishes are never taken over; a client's name is cut to its first label and kept inside the local domain; of two clients the newer lease wins. The DNS page switches it on and shows what is published and what was skipped; router-setup enables it with a domain. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func withDomain(t *testing.T) Settings {
|
||||
@@ -145,3 +146,53 @@ func TestDNSPage(t *testing.T) {
|
||||
t.Error("the network form dropped the DNS records")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDynamicLeasesOnThePage(t *testing.T) {
|
||||
a, sys := newTestApp(t)
|
||||
a.sys.LeasesDNSDir = t.TempDir()
|
||||
h := a.routes()
|
||||
cookie := do(h, "POST", "/login", url.Values{"password": {"hunter2hunter2"}}, nil).Result().Cookies()[0]
|
||||
token := func() string {
|
||||
body := do(h, "GET", "/dns", nil, cookie).Body.String()
|
||||
return regexp.MustCompile(`name="csrf" value="([^"]+)"`).FindStringSubmatch(body)[1]
|
||||
}
|
||||
save := func(extra ...string) {
|
||||
form := url.Values{"csrf": {token()}, "recs": {"0"}, "zones": {"0"}}
|
||||
for i := 0; i < len(extra); i += 2 {
|
||||
form.Set(extra[i], extra[i+1])
|
||||
}
|
||||
if rec := do(h, "POST", "/dns", form, cookie); rec.Code != http.StatusSeeOther {
|
||||
t.Fatalf("save: %d\n%s", rec.Code, rec.Body)
|
||||
}
|
||||
}
|
||||
|
||||
save("dynamic", "on")
|
||||
if s, _ := loadSettings(sys.settingsPath()); !s.dynamicLeases() {
|
||||
t.Fatal("not switched on")
|
||||
}
|
||||
body := do(h, "GET", "/dns", nil, cookie).Body.String()
|
||||
if !strings.Contains(body, `name="dynamic" checked`) || !strings.Contains(body, "apply the settings so the service starts") {
|
||||
t.Errorf("the page after switching on:\n%s", body)
|
||||
}
|
||||
|
||||
// What the running service reports is shown.
|
||||
writeDynStatus(a.sys.LeasesDNSDir, dynStatus{
|
||||
Published: []DynRecord{{Name: "phone.home.example.org", Address: "192.168.1.101"}},
|
||||
Skipped: []DynSkip{{Hostname: "nas", Address: "192.168.1.102", Reason: "the configuration has a record with this name"}},
|
||||
Updated: time.Now(),
|
||||
})
|
||||
body = do(h, "GET", "/dns", nil, cookie).Body.String()
|
||||
for _, want := range []string{"phone.home.example.org", "192.168.1.101", "the configuration has a record with this name"} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Errorf("status lacks %q", want)
|
||||
}
|
||||
}
|
||||
|
||||
save() // unticked
|
||||
if s, _ := loadSettings(sys.settingsPath()); s.dynamicLeases() {
|
||||
t.Error("not switched off")
|
||||
}
|
||||
if _, ok := obj(obj(mustLoad(sys), "router"), "dns")["dynamicLeases"]; ok {
|
||||
t.Error("the key stays after switching off")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user