202 lines
5.3 KiB
Go
202 lines
5.3 KiB
Go
|
package libnetwork
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"net/netip"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/Microsoft/hcsshim"
|
||
|
"github.com/google/go-cmp/cmp"
|
||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||
|
"gotest.tools/v3/assert"
|
||
|
is "gotest.tools/v3/assert/cmp"
|
||
|
)
|
||
|
|
||
|
func TestAddEpToResolver(t *testing.T) {
|
||
|
const (
|
||
|
ep1v4 = "192.0.2.11"
|
||
|
ep2v4 = "192.0.2.12"
|
||
|
epFiveDNS = "192.0.2.13"
|
||
|
epNoIntDNS = "192.0.2.14"
|
||
|
ep1v6 = "2001:db8:aaaa::2"
|
||
|
gw1v4 = "192.0.2.1"
|
||
|
gw2v4 = "192.0.2.2"
|
||
|
gw1v6 = "2001:db8:aaaa::1"
|
||
|
dns1v4 = "198.51.100.1"
|
||
|
dns2v4 = "198.51.100.2"
|
||
|
dns3v4 = "198.51.100.3"
|
||
|
)
|
||
|
hnsEndpoints := map[string]hcsshim.HNSEndpoint{
|
||
|
ep1v4: {
|
||
|
IPAddress: net.ParseIP(ep1v4),
|
||
|
GatewayAddress: gw1v4,
|
||
|
DNSServerList: gw1v4 + "," + dns1v4,
|
||
|
EnableInternalDNS: true,
|
||
|
},
|
||
|
ep2v4: {
|
||
|
IPAddress: net.ParseIP(ep2v4),
|
||
|
GatewayAddress: gw1v4,
|
||
|
DNSServerList: gw1v4 + "," + dns2v4,
|
||
|
EnableInternalDNS: true,
|
||
|
},
|
||
|
epFiveDNS: {
|
||
|
IPAddress: net.ParseIP(epFiveDNS),
|
||
|
GatewayAddress: gw1v4,
|
||
|
DNSServerList: gw1v4 + "," + dns1v4 + "," + dns2v4 + "," + dns3v4 + ",198.51.100.4",
|
||
|
EnableInternalDNS: true,
|
||
|
},
|
||
|
epNoIntDNS: {
|
||
|
IPAddress: net.ParseIP(epNoIntDNS),
|
||
|
GatewayAddress: gw1v4,
|
||
|
DNSServerList: gw1v4 + "," + dns1v4,
|
||
|
//EnableInternalDNS: false,
|
||
|
},
|
||
|
ep1v6: {
|
||
|
IPv6Address: net.ParseIP(ep1v6),
|
||
|
GatewayAddressV6: gw1v6,
|
||
|
DNSServerList: gw1v6 + "," + dns1v4,
|
||
|
EnableInternalDNS: true,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
makeIPNet := func(addr, netmask string) *net.IPNet {
|
||
|
t.Helper()
|
||
|
ip, ipnet, err := net.ParseCIDR(addr + "/" + netmask)
|
||
|
assert.NilError(t, err)
|
||
|
return &net.IPNet{IP: ip, Mask: ipnet.Mask}
|
||
|
}
|
||
|
|
||
|
testcases := []struct {
|
||
|
name string
|
||
|
epToAdd *EndpointInterface
|
||
|
hnsEndpoints []hcsshim.HNSEndpoint
|
||
|
resolverLAs []string
|
||
|
expIPToExtDNS map[netip.Addr][maxExtDNS]extDNSEntry
|
||
|
expResolverIdx int
|
||
|
}{
|
||
|
{
|
||
|
name: "ipv4",
|
||
|
epToAdd: &EndpointInterface{
|
||
|
addr: makeIPNet(ep1v4, "32"),
|
||
|
},
|
||
|
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||
|
hnsEndpoints[ep1v4],
|
||
|
},
|
||
|
resolverLAs: []string{gw1v4},
|
||
|
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||
|
netip.MustParseAddr(ep1v4): {{IPStr: dns1v4}},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "limit of three dns servers",
|
||
|
epToAdd: &EndpointInterface{
|
||
|
addr: makeIPNet(epFiveDNS, "32"),
|
||
|
},
|
||
|
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||
|
hnsEndpoints[epFiveDNS],
|
||
|
},
|
||
|
resolverLAs: []string{gw1v4},
|
||
|
// Expect the internal resolver to keep the first three ext-servers.
|
||
|
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||
|
netip.MustParseAddr(epFiveDNS): {
|
||
|
{IPStr: dns1v4},
|
||
|
{IPStr: dns2v4},
|
||
|
{IPStr: dns3v4},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "disabled internal resolver",
|
||
|
epToAdd: &EndpointInterface{
|
||
|
addr: makeIPNet(epNoIntDNS, "32"),
|
||
|
},
|
||
|
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||
|
hnsEndpoints[epNoIntDNS],
|
||
|
hnsEndpoints[ep2v4],
|
||
|
},
|
||
|
resolverLAs: []string{gw1v4},
|
||
|
},
|
||
|
{
|
||
|
name: "missing internal resolver",
|
||
|
epToAdd: &EndpointInterface{
|
||
|
addr: makeIPNet(ep1v4, "32"),
|
||
|
},
|
||
|
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||
|
hnsEndpoints[ep1v4],
|
||
|
},
|
||
|
// The only resolver is for the gateway on a different network.
|
||
|
resolverLAs: []string{gw2v4},
|
||
|
},
|
||
|
{
|
||
|
name: "multiple resolvers and endpoints",
|
||
|
epToAdd: &EndpointInterface{
|
||
|
addr: makeIPNet(ep2v4, "32"),
|
||
|
},
|
||
|
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||
|
hnsEndpoints[ep1v4],
|
||
|
hnsEndpoints[ep2v4],
|
||
|
},
|
||
|
// Put the internal resolver for this network second in the list.
|
||
|
expResolverIdx: 1,
|
||
|
resolverLAs: []string{gw2v4, gw1v4},
|
||
|
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||
|
netip.MustParseAddr(ep2v4): {{IPStr: dns2v4}},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "ipv6",
|
||
|
epToAdd: &EndpointInterface{
|
||
|
addrv6: makeIPNet(ep1v6, "80"),
|
||
|
},
|
||
|
hnsEndpoints: []hcsshim.HNSEndpoint{
|
||
|
hnsEndpoints[ep1v6],
|
||
|
},
|
||
|
resolverLAs: []string{gw1v6},
|
||
|
expIPToExtDNS: map[netip.Addr][maxExtDNS]extDNSEntry{
|
||
|
netip.MustParseAddr(ep1v6): {{IPStr: dns1v4}},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
eMapCmpOpts := []cmp.Option{
|
||
|
cmpopts.EquateEmpty(),
|
||
|
cmpopts.EquateComparable(netip.Addr{}),
|
||
|
cmpopts.IgnoreUnexported(extDNSEntry{}),
|
||
|
}
|
||
|
emptyEMap := map[netip.Addr][maxExtDNS]extDNSEntry{}
|
||
|
|
||
|
for _, tc := range testcases {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
// Set up resolvers with the required listen-addresses.
|
||
|
var resolvers []*Resolver
|
||
|
for _, la := range tc.resolverLAs {
|
||
|
resolvers = append(resolvers, NewResolver(la, true, nil))
|
||
|
}
|
||
|
|
||
|
// Add the endpoint and check expected results.
|
||
|
err := addEpToResolverImpl(context.TODO(),
|
||
|
"netname", "epname", tc.epToAdd, resolvers, tc.hnsEndpoints)
|
||
|
assert.Check(t, err)
|
||
|
for i, resolver := range resolvers {
|
||
|
if i == tc.expResolverIdx {
|
||
|
assert.Check(t, is.DeepEqual(resolver.ipToExtDNS.eMap, tc.expIPToExtDNS,
|
||
|
eMapCmpOpts...), fmt.Sprintf("resolveridx=%d", i))
|
||
|
} else {
|
||
|
assert.Check(t, is.DeepEqual(resolver.ipToExtDNS.eMap, emptyEMap,
|
||
|
eMapCmpOpts...), fmt.Sprintf("resolveridx=%d", i))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Delete the endpoint, check nothing got left behind.
|
||
|
err = deleteEpFromResolverImpl("epname", tc.epToAdd, resolvers, tc.hnsEndpoints)
|
||
|
assert.Check(t, err)
|
||
|
for i, resolver := range resolvers {
|
||
|
assert.Check(t, is.DeepEqual(resolver.ipToExtDNS.eMap, emptyEMap,
|
||
|
eMapCmpOpts...), fmt.Sprintf("resolveridx=%d", i))
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|