From 38a94b3d740b0d4bf82b622a066504a56e73c797 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Thu, 13 Nov 2025 13:03:52 +0200 Subject: [PATCH] dns: simplify newStaticClientConfig implementation Signed-off-by: Oleksandr Redko --- pkg/hostagent/dns/dns.go | 9 +-- pkg/hostagent/dns/dns_test.go | 108 ++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 7 deletions(-) diff --git a/pkg/hostagent/dns/dns.go b/pkg/hostagent/dns/dns.go index 6347580e6ae..ee77c7b9ce3 100644 --- a/pkg/hostagent/dns/dns.go +++ b/pkg/hostagent/dns/dns.go @@ -7,7 +7,6 @@ package dns import ( "context" - "fmt" "net" "runtime" "strconv" @@ -69,12 +68,8 @@ func (s *Server) Shutdown() { func newStaticClientConfig(ips []string) (*dns.ClientConfig, error) { logrus.Tracef("newStaticClientConfig creating config for the following IPs: %v", ips) - s := `` - for _, ip := range ips { - s += fmt.Sprintf("nameserver %s\n", ip) - } - r := strings.NewReader(s) - return dns.ClientConfigFromReader(r) + config := "nameserver " + strings.Join(ips, "\nnameserver ") + "\n" + return dns.ClientConfigFromReader(strings.NewReader(config)) } func (h *Handler) lookupCnameToHost(cname string) string { diff --git a/pkg/hostagent/dns/dns_test.go b/pkg/hostagent/dns/dns_test.go index c32db6773c7..8f63e7e25b4 100644 --- a/pkg/hostagent/dns/dns_test.go +++ b/pkg/hostagent/dns/dns_test.go @@ -20,6 +20,114 @@ import ( var dnsResult *dns.Msg +func TestNewHandler(t *testing.T) { + t.Run("with upstream servers", func(t *testing.T) { + upstreamServers := []string{"8.8.4.4", "1.1.1.1", "9.9.9.9"} + opts := HandlerOptions{ + IPv6: true, + UpstreamServers: upstreamServers, + StaticHosts: map[string]string{ + "test.local": "192.168.1.1", + "alias.local": "test.local", + }, + } + h, err := NewHandler(opts) + assert.NilError(t, err) + assert.Assert(t, h != nil) + + handler := h.(*Handler) + assert.Equal(t, handler.ipv6, true) + assert.Equal(t, len(handler.clients), 2) + assert.DeepEqual(t, handler.clientConfig.Servers, upstreamServers) + assert.Equal(t, handler.hostToIP["test.local."].String(), "192.168.1.1") + assert.Equal(t, handler.cnameToHost["alias.local."], "test.local.") + }) + + t.Run("without upstream servers on non-Windows", func(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Skipping on Windows") + } + opts := HandlerOptions{ + IPv6: false, + StaticHosts: map[string]string{}, + } + h, err := NewHandler(opts) + assert.NilError(t, err) + assert.Assert(t, h != nil) + + handler := h.(*Handler) + assert.Equal(t, handler.ipv6, false) + assert.Assert(t, handler.clientConfig != nil) + }) + + t.Run("without upstream servers on Windows", func(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("Skipping on non-Windows") + } + opts := HandlerOptions{ + IPv6: false, + StaticHosts: map[string]string{}, + } + h, err := NewHandler(opts) + assert.NilError(t, err) + assert.Assert(t, h != nil) + + handler := h.(*Handler) + assert.Equal(t, handler.ipv6, false) + assert.Assert(t, handler.clientConfig != nil) + // Should use default fallback IPs on Windows + assert.Assert(t, len(handler.clientConfig.Servers) > 0) + }) + + t.Run("with invalid upstream servers fallback", func(t *testing.T) { + opts := HandlerOptions{ + IPv6: true, + UpstreamServers: []string{}, // empty should trigger default behavior + StaticHosts: map[string]string{}, + } + h, err := NewHandler(opts) + assert.NilError(t, err) + assert.Assert(t, h != nil) + }) + + t.Run("with static hosts IP and CNAME", func(t *testing.T) { + opts := HandlerOptions{ + IPv6: true, + UpstreamServers: []string{"8.8.8.8"}, + StaticHosts: map[string]string{ + "host1.local": "10.0.0.1", + "host2.local": "10.0.0.2", + "cname1": "host1.local", + "cname2": "cname1", + }, + } + h, err := NewHandler(opts) + assert.NilError(t, err) + assert.Assert(t, h != nil) + + handler := h.(*Handler) + assert.Equal(t, handler.hostToIP["host1.local."].String(), "10.0.0.1") + assert.Equal(t, handler.hostToIP["host2.local."].String(), "10.0.0.2") + assert.Equal(t, handler.cnameToHost["cname1."], "host1.local.") + assert.Equal(t, handler.cnameToHost["cname2."], "cname1.") + }) + + t.Run("with truncate option", func(t *testing.T) { + opts := HandlerOptions{ + IPv6: false, + UpstreamServers: []string{"1.1.1.1"}, + TruncateReply: true, + StaticHosts: map[string]string{}, + } + h, err := NewHandler(opts) + assert.NilError(t, err) + assert.Assert(t, h != nil) + + handler := h.(*Handler) + assert.Equal(t, handler.truncate, true) + }) +} + func TestDNSRecords(t *testing.T) { if runtime.GOOS == "windows" { // "On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery."