Replace InstanceConfig with DNSEntry for dnsmasq config generation
InstanceConfig was a ~50-field struct designed for Wild Cloud k8s instances,
but only 3 fields were ever read by dnsmasq (the sole consumer). The
reconciliation bridge constructed fake InstanceConfig objects from registered
domains just to satisfy this interface.
Replace with DNSEntry{Domain, IP} — a 2-field struct purpose-built for
dnsmasq. All domains get local=/ directives to prevent AAAA queries from
leaking to upstream DNS (Happy Eyeballs / RFC 8305 latency on LAN).
Removed dead code: InstanceConfig, NodeConfig, LoadCloudConfig,
SaveCloudConfig, DeepMerge, LoadMergedInstanceConfig, EnsureInstanceConfig,
instance path helpers, instanceLoadBalancerIP, GenerateInstanceConfig,
and all modular per-instance dnsmasq methods.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/wild-cloud/wild-central/internal/config"
|
||||
"github.com/wild-cloud/wild-central/internal/dnsmasq"
|
||||
"github.com/wild-cloud/wild-central/internal/domains"
|
||||
"github.com/wild-cloud/wild-central/internal/haproxy"
|
||||
)
|
||||
@@ -205,14 +206,14 @@ func TestReconciliation_DnsmasqConfigFromDomains(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Build dnsmasq instance configs the same way reconcileNetworking does
|
||||
// Build dnsmasq entries the same way reconcileNetworking does
|
||||
doms, err := api.domains.List()
|
||||
if err != nil {
|
||||
t.Fatalf("List failed: %v", err)
|
||||
}
|
||||
|
||||
globalCfg := &config.State{}
|
||||
var instanceConfigs []config.InstanceConfig
|
||||
var dnsEntries []dnsmasq.DNSEntry
|
||||
|
||||
for _, dom := range doms {
|
||||
if dom.DomainName == "" {
|
||||
@@ -224,19 +225,13 @@ func TestReconciliation_DnsmasqConfigFromDomains(t *testing.T) {
|
||||
dnsIP = extractHost(dom.Backend.Address)
|
||||
}
|
||||
|
||||
ic := config.InstanceConfig{}
|
||||
ic.Cluster.LoadBalancerIp = dnsIP
|
||||
|
||||
if !dom.Public {
|
||||
ic.Cloud.InternalDomain = dom.DomainName
|
||||
} else {
|
||||
ic.Cloud.Domain = dom.DomainName
|
||||
}
|
||||
|
||||
instanceConfigs = append(instanceConfigs, ic)
|
||||
dnsEntries = append(dnsEntries, dnsmasq.DNSEntry{
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
})
|
||||
}
|
||||
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, instanceConfigs)
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, dnsEntries)
|
||||
|
||||
// --- TCP passthrough (public) → backend IP ---
|
||||
if !strings.Contains(dnsmasqCfg, "address=/cloud.payne.io/192.168.8.240") {
|
||||
@@ -251,17 +246,15 @@ func TestReconciliation_DnsmasqConfigFromDomains(t *testing.T) {
|
||||
t.Errorf("http/public domain must point DNS to Central IP (192.168.8.151):\n%s", dnsmasqCfg)
|
||||
}
|
||||
|
||||
// --- internal → local=/ present ---
|
||||
// --- All domains get local=/ to prevent AAAA leaking upstream (Happy Eyeballs) ---
|
||||
if !strings.Contains(dnsmasqCfg, "local=/my-api.payne.io/") {
|
||||
t.Errorf("internal domain must have local=/ entry:\n%s", dnsmasqCfg)
|
||||
t.Errorf("domain must have local=/ entry:\n%s", dnsmasqCfg)
|
||||
}
|
||||
|
||||
// --- public → NO local=/ ---
|
||||
if strings.Contains(dnsmasqCfg, "local=/cloud.payne.io/") {
|
||||
t.Errorf("public domain must NOT have local=/ entry:\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("public domain must NOT have local=/ entry:\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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,24 +338,19 @@ func TestReconciliation_TCPPassthroughDNSTarget(t *testing.T) {
|
||||
doms, _ := api.domains.List()
|
||||
globalCfg := &config.State{}
|
||||
|
||||
var instanceConfigs []config.InstanceConfig
|
||||
var dnsEntries []dnsmasq.DNSEntry
|
||||
for _, dom := range doms {
|
||||
dnsIP := centralIP
|
||||
if dom.Backend.Type == domains.BackendTCPPassthrough {
|
||||
dnsIP = extractHost(dom.Backend.Address)
|
||||
}
|
||||
|
||||
ic := config.InstanceConfig{}
|
||||
ic.Cluster.LoadBalancerIp = dnsIP
|
||||
if !dom.Public {
|
||||
ic.Cloud.InternalDomain = dom.DomainName
|
||||
} else {
|
||||
ic.Cloud.Domain = dom.DomainName
|
||||
}
|
||||
instanceConfigs = append(instanceConfigs, ic)
|
||||
dnsEntries = append(dnsEntries, dnsmasq.DNSEntry{
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
})
|
||||
}
|
||||
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, instanceConfigs)
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, dnsEntries)
|
||||
|
||||
// TCP passthrough → DNS points to backend (k8s LB), NOT central
|
||||
if !strings.Contains(dnsmasqCfg, "address=/cloud.payne.io/192.168.8.240") {
|
||||
@@ -440,7 +428,7 @@ func TestReconciliation_DNSOnlyNoGateway(t *testing.T) {
|
||||
|
||||
// Build DNS config — dns-only should point to its backend IP
|
||||
globalCfg := &config.State{}
|
||||
var instanceConfigs []config.InstanceConfig
|
||||
var dnsEntries []dnsmasq.DNSEntry
|
||||
|
||||
for _, dom := range doms {
|
||||
dnsIP := centralIP
|
||||
@@ -448,18 +436,13 @@ func TestReconciliation_DNSOnlyNoGateway(t *testing.T) {
|
||||
if bt == domains.BackendTCPPassthrough || bt == domains.BackendDNSOnly {
|
||||
dnsIP = extractHost(dom.Backend.Address)
|
||||
}
|
||||
|
||||
ic := config.InstanceConfig{}
|
||||
ic.Cluster.LoadBalancerIp = dnsIP
|
||||
if !dom.Public {
|
||||
ic.Cloud.InternalDomain = dom.DomainName
|
||||
} else {
|
||||
ic.Cloud.Domain = dom.DomainName
|
||||
}
|
||||
instanceConfigs = append(instanceConfigs, ic)
|
||||
dnsEntries = append(dnsEntries, dnsmasq.DNSEntry{
|
||||
Domain: dom.DomainName,
|
||||
IP: dnsIP,
|
||||
})
|
||||
}
|
||||
|
||||
dnsmasqCfg := api.dnsmasq.Generate(globalCfg, instanceConfigs)
|
||||
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") {
|
||||
|
||||
Reference in New Issue
Block a user