Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: automatically detect dns lookup family for cp cluster #4275

25 changes: 25 additions & 0 deletions pkg/xds/bootstrap/template_v3.go
@@ -1,6 +1,7 @@
package bootstrap

import (
"net"
"strconv"

"github.com/asaskevich/govalidator"
Expand Down Expand Up @@ -171,6 +172,7 @@ func genConfig(parameters configParameters) (*envoy_bootstrap_v3.Bootstrap, erro
},
},
ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: clusterTypeFromHost(parameters.XdsHost)},
DnsLookupFamily: dnsLookupFamilyFromXdsHost(parameters.XdsHost, net.LookupIP),
LoadAssignment: &envoy_config_endpoint_v3.ClusterLoadAssignment{
ClusterName: "ads_cluster",
Endpoints: []*envoy_config_endpoint_v3.LocalityLbEndpoints{
Expand Down Expand Up @@ -295,6 +297,29 @@ func genConfig(parameters configParameters) (*envoy_bootstrap_v3.Bootstrap, erro
return res, nil
}

func dnsLookupFamilyFromXdsHost(host string, lookupFn func(host string) ([]net.IP, error)) envoy_cluster_v3.Cluster_DnsLookupFamily {
if govalidator.IsDNSName(host) && host != "localhost" {
ips, err := lookupFn(host)
if err != nil {
log.Info("[WARNING] error looking up XDS host to determine DnsLookupFamily, falling back to AUTO", "hostname", host)
return envoy_cluster_v3.Cluster_AUTO
}
hasIPv6 := false

for _, ip := range ips {
if ip.To4() == nil {
hasIPv6 = true
}
}

if !hasIPv6 && len(ips) > 0 {
return envoy_cluster_v3.Cluster_V4_ONLY
}
slonka marked this conversation as resolved.
Show resolved Hide resolved
}

return envoy_cluster_v3.Cluster_AUTO // default
}

func clusterTypeFromHost(host string) envoy_cluster_v3.Cluster_DiscoveryType {
if govalidator.IsIP(host) {
return envoy_cluster_v3.Cluster_STATIC
Expand Down
90 changes: 90 additions & 0 deletions pkg/xds/bootstrap/template_v3_test.go
@@ -0,0 +1,90 @@
package bootstrap

import (
"errors"
"net"

envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("dnsLookupFamilyFromXdsHost", func() {
slonka marked this conversation as resolved.
Show resolved Hide resolved
It("should return AUTO when IPv6 found", func() {
// given
lookupFn := func(host string) ([]net.IP, error) {
return []net.IP{net.IPv6loopback}, nil
}

// when
result := dnsLookupFamilyFromXdsHost("example.com", lookupFn)

// then
Expect(result).To(Equal(envoy_cluster_v3.Cluster_AUTO))
})

It("should return AUTO for localhost", func() {
// given
lookupFn := func(host string) ([]net.IP, error) {
return []net.IP{net.IPv4(127, 0, 0, 1)}, nil
}

// when
result := dnsLookupFamilyFromXdsHost("localhost", lookupFn)

// then
Expect(result).To(Equal(envoy_cluster_v3.Cluster_AUTO))
})

It("should return AUTO when both IPv6 and IPv4 found", func() {
// given
lookupFn := func(host string) ([]net.IP, error) {
return []net.IP{net.IPv6loopback, net.IPv4(127, 0, 0, 1)}, nil
}

// when
result := dnsLookupFamilyFromXdsHost("example.com", lookupFn)

// then
Expect(result).To(Equal(envoy_cluster_v3.Cluster_AUTO))
})

It("should return IPV4 when only IPv4 found", func() {
// given
lookupFn := func(host string) ([]net.IP, error) {
return []net.IP{net.IPv4(127, 0, 0, 1)}, nil
}

// when
result := dnsLookupFamilyFromXdsHost("example.com", lookupFn)

// then
Expect(result).To(Equal(envoy_cluster_v3.Cluster_V4_ONLY))
})

It("should return AUTO (default) when no ips returned", func() {
// given
lookupFn := func(host string) ([]net.IP, error) {
return []net.IP{}, nil
}

// when
result := dnsLookupFamilyFromXdsHost("example.com", lookupFn)

// then
Expect(result).To(Equal(envoy_cluster_v3.Cluster_AUTO))
})

It("should return AUTO when error occurs", func() {
// given
lookupFn := func(host string) ([]net.IP, error) {
return nil, errors.New("could not resolve hostname")
}

// when
result := dnsLookupFamilyFromXdsHost("example.com", lookupFn)

// then
Expect(result).To(Equal(envoy_cluster_v3.Cluster_AUTO))
})
})