support multiple host network aliases for the same interface

This commit is contained in:
Andrii Chubatiuk 2021-04-13 16:33:33 +03:00 committed by GitHub
parent 715460804a
commit d8df568f10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 15 deletions

View File

@ -168,17 +168,19 @@ func (f *NetworkFingerprint) createNodeNetworkResources(ifaces []net.Interface,
} else {
family = structs.NodeNetworkAF_IPv6
}
newAddr := structs.NodeNetworkAddress{
Address: ip.String(),
Family: family,
Alias: deriveAddressAlias(iface, ip, conf),
}
for _, alias := range deriveAddressAliases(iface, ip, conf) {
newAddr := structs.NodeNetworkAddress{
Address: ip.String(),
Family: family,
Alias: alias,
}
if newAddr.Alias != "" {
if ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
linkLocalAddrs = append(linkLocalAddrs, newAddr)
} else {
networkAddrs = append(networkAddrs, newAddr)
if newAddr.Alias != "" {
if ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
linkLocalAddrs = append(linkLocalAddrs, newAddr)
} else {
networkAddrs = append(networkAddrs, newAddr)
}
}
}
}
@ -200,7 +202,7 @@ func (f *NetworkFingerprint) createNodeNetworkResources(ifaces []net.Interface,
return nets, nil
}
func deriveAddressAlias(iface net.Interface, addr net.IP, config *config.Config) string {
func deriveAddressAliases(iface net.Interface, addr net.IP, config *config.Config) (aliases []string) {
for name, conf := range config.HostNetworks {
var cidrMatch, ifaceMatch bool
if conf.CIDR != "" {
@ -231,22 +233,26 @@ func deriveAddressAlias(iface net.Interface, addr net.IP, config *config.Config)
ifaceMatch = true
}
if cidrMatch && ifaceMatch {
return name
aliases = append(aliases, name)
}
}
if len(aliases) > 0 {
return
}
if config.NetworkInterface != "" {
if config.NetworkInterface == iface.Name {
return "default"
return []string{"default"}
}
} else if ri, err := sockaddr.NewRouteInfo(); err == nil {
defaultIface, err := ri.GetDefaultInterfaceName()
if err == nil && iface.Name == defaultIface {
return "default"
return []string{"default"}
}
}
return ""
return
}
// createNetworkResources creates network resources for every IP

View File

@ -4,11 +4,13 @@ import (
"fmt"
"net"
"os"
"sort"
"testing"
"github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/helper/testlog"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/stretchr/testify/require"
)
// Set skipOnlineTestEnvVar to a non-empty value to skip network tests. Useful
@ -437,3 +439,50 @@ func TestNetworkFingerPrint_LinkLocal_Disallowed(t *testing.T) {
t.Fatalf("should not apply attributes")
}
}
func TestNetworkFingerPrint_MultipleAliases(t *testing.T) {
f := &NetworkFingerprint{logger: testlog.HCLogger(t), interfaceDetector: &NetworkInterfaceDetectorMultipleInterfaces{}}
node := &structs.Node{
Attributes: make(map[string]string),
}
cfg := &config.Config{
NetworkSpeed: 100,
NetworkInterface: "eth3",
HostNetworks: map[string]*structs.ClientHostNetworkConfig{
"alias1": {
Name: "alias1",
Interface: "eth3",
CIDR: "169.254.155.20/32",
},
"alias2": {
Name: "alias2",
Interface: "eth3",
CIDR: "169.254.155.20/32",
},
"alias3": {
Name: "alias3",
Interface: "eth0",
CIDR: "100.64.0.11/10",
},
},
}
request := &FingerprintRequest{Config: cfg, Node: node}
var response FingerprintResponse
err := f.Fingerprint(request, &response)
require.NoError(t, err)
aliases := []string{}
for _, network := range response.NodeResources.NodeNetworks {
for _, address := range network.Addresses {
aliases = append(aliases, address.Alias)
}
}
expected := []string{}
for alias, _ := range cfg.HostNetworks {
expected = append(expected, alias)
}
sort.Strings(expected)
sort.Strings(aliases)
require.Equal(t, expected, aliases, "host networks should match aliases")
}