Support custom domains. Fix host-record/address resolution.
This commit is contained in:
@@ -168,17 +168,18 @@ func TestReconciliation_HAProxyConfigFromDomains(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestReconciliation_DnsmasqConfigFromDomains verifies that reconciliation
|
||||
// correctly generates dnsmasq config from registered domains, including
|
||||
// the critical reach-based local=/ directives.
|
||||
// correctly generates dnsmasq config from registered domains. Wildcard
|
||||
// domains (subdomains:true) get address=/, exact-match domains get
|
||||
// host-record=. No local=/ directives — AAAA is handled by filter-AAAA.
|
||||
func TestReconciliation_DnsmasqConfigFromDomains(t *testing.T) {
|
||||
api, _ := setupTestAPI(t)
|
||||
|
||||
centralIP := "192.168.8.151"
|
||||
|
||||
// Register domains with different reach and backend types
|
||||
// Register domains with different backend types and subdomain settings
|
||||
testDomains := []domains.Domain{
|
||||
{
|
||||
// tcp-passthrough, public → DNS points to k8s LB IP, no local=/
|
||||
// tcp-passthrough, wildcard → address=/ with backend IP
|
||||
DomainName: "cloud.payne.io",
|
||||
Source: "wild-cloud",
|
||||
Backend: domains.Backend{Address: "192.168.8.240:443", Type: domains.BackendTCPPassthrough},
|
||||
@@ -186,13 +187,13 @@ func TestReconciliation_DnsmasqConfigFromDomains(t *testing.T) {
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
// http, internal → DNS points to Central IP, has local=/
|
||||
// http, exact → host-record= with Central IP
|
||||
DomainName: "my-api.payne.io",
|
||||
Source: "wild-works",
|
||||
Backend: domains.Backend{Address: "192.168.8.60:9001", Type: domains.BackendHTTP},
|
||||
},
|
||||
{
|
||||
// http, public → DNS points to Central IP, NO local=/
|
||||
// http, exact → host-record= with Central IP
|
||||
DomainName: "public-app.payne.io",
|
||||
Source: "wild-works",
|
||||
Backend: domains.Backend{Address: "192.168.8.60:8080", Type: domains.BackendHTTP},
|
||||
@@ -226,35 +227,35 @@ func TestReconciliation_DnsmasqConfigFromDomains(t *testing.T) {
|
||||
}
|
||||
|
||||
dnsEntries = append(dnsEntries, dnsmasq.DNSEntry{
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
Wildcard: dom.Subdomains,
|
||||
})
|
||||
}
|
||||
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, dnsEntries)
|
||||
|
||||
// --- TCP passthrough (public) → backend IP ---
|
||||
// --- Wildcard (subdomains:true) → address=/ with backend IP ---
|
||||
if !strings.Contains(dnsmasqCfg, "address=/cloud.payne.io/192.168.8.240") {
|
||||
t.Errorf("tcp-passthrough domain must point DNS to backend IP (192.168.8.240):\n%s", dnsmasqCfg)
|
||||
t.Errorf("wildcard domain must use address=/ with backend IP:\n%s", dnsmasqCfg)
|
||||
}
|
||||
|
||||
// --- HTTP domains → Central IP ---
|
||||
if !strings.Contains(dnsmasqCfg, "address=/my-api.payne.io/192.168.8.151") {
|
||||
t.Errorf("http/internal domain must point DNS to Central IP (192.168.8.151):\n%s", dnsmasqCfg)
|
||||
// --- Exact-match HTTP domains → host-record= with Central IP ---
|
||||
if !strings.Contains(dnsmasqCfg, "host-record=my-api.payne.io,192.168.8.151") {
|
||||
t.Errorf("exact-match http domain must use host-record= with Central IP:\n%s", dnsmasqCfg)
|
||||
}
|
||||
if !strings.Contains(dnsmasqCfg, "address=/public-app.payne.io/192.168.8.151") {
|
||||
t.Errorf("http/public domain must point DNS to Central IP (192.168.8.151):\n%s", dnsmasqCfg)
|
||||
if !strings.Contains(dnsmasqCfg, "host-record=public-app.payne.io,192.168.8.151") {
|
||||
t.Errorf("exact-match http domain must use host-record= with Central IP:\n%s", dnsmasqCfg)
|
||||
}
|
||||
|
||||
// --- All domains get local=/ to prevent AAAA leaking upstream (Happy Eyeballs) ---
|
||||
if !strings.Contains(dnsmasqCfg, "local=/my-api.payne.io/") {
|
||||
t.Errorf("domain must have local=/ entry:\n%s", dnsmasqCfg)
|
||||
// --- No local=/ directives (AAAA handled by filter-AAAA) ---
|
||||
if strings.Contains(dnsmasqCfg, "local=/") {
|
||||
t.Errorf("must not produce local=/ directives:\n%s", dnsmasqCfg)
|
||||
}
|
||||
if !strings.Contains(dnsmasqCfg, "local=/cloud.payne.io/") {
|
||||
t.Errorf("domain must have local=/ entry (prevents AAAA leaking):\n%s", dnsmasqCfg)
|
||||
}
|
||||
if !strings.Contains(dnsmasqCfg, "local=/public-app.payne.io/") {
|
||||
t.Errorf("domain must have local=/ entry (prevents AAAA leaking):\n%s", dnsmasqCfg)
|
||||
|
||||
// --- filter-AAAA present ---
|
||||
if !strings.Contains(dnsmasqCfg, "filter-AAAA") {
|
||||
t.Errorf("must include filter-AAAA directive:\n%s", dnsmasqCfg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,19 +346,20 @@ func TestReconciliation_TCPPassthroughDNSTarget(t *testing.T) {
|
||||
dnsIP = extractHost(dom.Backend.Address)
|
||||
}
|
||||
dnsEntries = append(dnsEntries, dnsmasq.DNSEntry{
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
Wildcard: dom.Subdomains,
|
||||
})
|
||||
}
|
||||
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, dnsEntries)
|
||||
|
||||
// TCP passthrough → DNS points to backend (k8s LB), NOT central
|
||||
// TCP passthrough with subdomains → address=/ to backend (k8s LB), NOT central
|
||||
if !strings.Contains(dnsmasqCfg, "address=/cloud.payne.io/192.168.8.240") {
|
||||
t.Errorf("tcp-passthrough DNS must point to backend IP 192.168.8.240:\n%s", dnsmasqCfg)
|
||||
t.Errorf("wildcard tcp-passthrough DNS must use address=/ to backend IP 192.168.8.240:\n%s", dnsmasqCfg)
|
||||
}
|
||||
if strings.Contains(dnsmasqCfg, "address=/cloud.payne.io/192.168.8.151") {
|
||||
t.Errorf("tcp-passthrough DNS must NOT point to Central IP:\n%s", dnsmasqCfg)
|
||||
if strings.Contains(dnsmasqCfg, "host-record=cloud.payne.io,192.168.8.151") {
|
||||
t.Errorf("wildcard tcp-passthrough DNS must NOT use host-record= to Central IP:\n%s", dnsmasqCfg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,20 +439,21 @@ func TestReconciliation_DNSOnlyNoGateway(t *testing.T) {
|
||||
dnsIP = extractHost(dom.Backend.Address)
|
||||
}
|
||||
dnsEntries = append(dnsEntries, dnsmasq.DNSEntry{
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
Wildcard: dom.Subdomains,
|
||||
})
|
||||
}
|
||||
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, dnsEntries)
|
||||
|
||||
// dns-only domain should resolve to its backend IP (192.168.8.222)
|
||||
if !strings.Contains(dnsmasqCfg, "address=/dev.payne.io/192.168.8.222") {
|
||||
t.Errorf("dns-only domain must point DNS to backend IP:\n%s", dnsmasqCfg)
|
||||
// dns-only domain (public, no subdomains) → host-record= with backend IP
|
||||
if !strings.Contains(dnsmasqCfg, "host-record=dev.payne.io,192.168.8.222") {
|
||||
t.Errorf("dns-only domain must use host-record= with backend IP:\n%s", dnsmasqCfg)
|
||||
}
|
||||
// HTTP domain should resolve to Central IP
|
||||
if !strings.Contains(dnsmasqCfg, "address=/app.payne.io/192.168.8.151") {
|
||||
t.Errorf("http domain must point DNS to Central IP:\n%s", dnsmasqCfg)
|
||||
// HTTP domain (no subdomains) → host-record= with Central IP
|
||||
if !strings.Contains(dnsmasqCfg, "host-record=app.payne.io,192.168.8.151") {
|
||||
t.Errorf("http domain must use host-record= with Central IP:\n%s", dnsmasqCfg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user