Skip to content

Commit

Permalink
support multiple host network aliases for the same interface
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewChubatiuk authored Apr 13, 2021
1 parent 4a1a142 commit bab0d39
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 15 deletions.
36 changes: 21 additions & 15 deletions client/fingerprint/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
}
Expand All @@ -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 != "" {
Expand Down Expand Up @@ -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
Expand Down
49 changes: 49 additions & 0 deletions client/fingerprint/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
}

0 comments on commit bab0d39

Please sign in to comment.