Add identity: whois resolver, checker, header mode, middleware; config for wake, peers, identity

Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
2026-09-25 10:16:51 -07:00
parent bddf6c93f2
commit a942e336d8
9 changed files with 666 additions and 5 deletions
+75
View File
@@ -0,0 +1,75 @@
package config_test
import (
"strings"
"testing"
"time"
"git.wntrmute.dev/kyle/crossbar/internal/config"
)
const v2Base = `
listen = "127.0.0.1:1"
[hosts.a]
base_url = "http://a:1"
models = { "m" = { } }
[hosts.b]
base_url = "http://b:1"
models = { "m" = { } }
[hosts.b.wake]
mac = "aa:bb:cc:dd:ee:ff"
broadcast = "192.168.1.255:9"
wait = "45s"
[routes.r]
hosts = ["a", "b"]
peers = ["talos", "imladris"]
`
func TestV2Defaults(t *testing.T) {
c, err := config.Parse(strings.NewReader(v2Base))
if err != nil {
t.Fatal(err)
}
if c.Identity != "off" {
t.Errorf("identity default = %q, want off", c.Identity)
}
if c.Hosts["a"].Wake != nil {
t.Errorf("host without [wake] must have nil Wake")
}
w := c.Hosts["b"].Wake
if w == nil || w.MAC != "aa:bb:cc:dd:ee:ff" || w.Broadcast != "192.168.1.255:9" || w.Wait.Duration != 45*time.Second {
t.Errorf("wake = %+v", w)
}
if p := c.Routes["r"].Peers; len(p) != 2 || p[0] != "talos" {
t.Errorf("peers = %v", p)
}
}
func TestV2Validation(t *testing.T) {
good := v2Base
for _, tc := range []struct{ name, text, field string }{
{"bad identity", "identity = \"maybe\"\n" + good, "identity"},
{"peers without identity", "identity = \"off\"\n" + good, "routes.r.peers"},
{"bad mac", strings.Replace(good, `mac = "aa:bb:cc:dd:ee:ff"`, `mac = "nope"`, 1), "hosts.b.wake.mac"},
{"no broadcast", strings.Replace(good, `broadcast = "192.168.1.255:9"`, `broadcast = ""`, 1), "hosts.b.wake.broadcast"},
{"wait too short", strings.Replace(good, `wait = "45s"`, `wait = "2s"`, 1), "hosts.b.wake.wait"},
{"peers on unknown route field", "identity = \"tailscale\"\n" + strings.Replace(good, `peers = ["talos", "imladris"]`, `peers = []`, 1), "routes.r.peers"},
} {
_, err := config.Parse(strings.NewReader(tc.text))
e, ok := config.IsError(err)
if !ok || e.Field != tc.field {
t.Errorf("%s: %v, want *Error on %s", tc.name, err, tc.field)
}
}
// identity = "header" is the test/smoke mode; "tailscale" the real one; both accept peers.
for _, mode := range []string{"header", "tailscale"} {
if _, err := config.Parse(strings.NewReader("identity = \"" + mode + "\"\n" + good)); err != nil {
t.Errorf("identity=%s with peers: %v", mode, err)
}
}
// wait defaults to 45s when the [wake] table omits it
c, err := config.Parse(strings.NewReader("identity = \"header\"\n" + strings.Replace(good, "wait = \"45s\"\n", "", 1)))
if err != nil || c.Hosts["b"].Wake == nil || c.Hosts["b"].Wake.Wait.Duration != 45*time.Second {
t.Errorf("wake.wait default: %v %+v", err, c.Hosts["b"].Wake)
}
}