mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 01:15:43 +03:00
Client config param added to specify net iface to use for fingerprinting. Added a Golang-native method for determining the interface IP address.
This commit is contained in:
@@ -31,6 +31,9 @@ type Config struct {
|
||||
// Region is the clients region
|
||||
Region string
|
||||
|
||||
// Network interface to be used in network fingerprinting
|
||||
Iface string
|
||||
|
||||
// Servers is a list of known server addresses. These are as "host:port"
|
||||
Servers []string
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package fingerprint
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@@ -38,10 +39,13 @@ func (f *NetworkFingerprint) Fingerprint(cfg *config.Config, node *structs.Node)
|
||||
if "darwin" == runtime.GOOS {
|
||||
defaultDevice = "en0"
|
||||
}
|
||||
if cfg.Iface != "" {
|
||||
defaultDevice = cfg.Iface
|
||||
}
|
||||
|
||||
newNetwork.Device = defaultDevice
|
||||
|
||||
if ip := f.ifConfig(defaultDevice); ip != "" {
|
||||
if ip := f.ipAddress(defaultDevice); ip != "" {
|
||||
node.Attributes["network.ip-address"] = ip
|
||||
newNetwork.IP = ip
|
||||
newNetwork.CIDR = newNetwork.IP + "/32"
|
||||
@@ -129,6 +133,50 @@ func (f *NetworkFingerprint) linkSpeedEthtool(path, device string) int {
|
||||
return mbs
|
||||
}
|
||||
|
||||
// ipAddress returns the first IPv4 address on the configured default interface
|
||||
// Tries Golang native functions and falls back onto ifconfig
|
||||
func (f *NetworkFingerprint) ipAddress(device string) string {
|
||||
if ip, err := f.nativeIpAddress(device); err == nil {
|
||||
return ip
|
||||
}
|
||||
|
||||
return f.ifConfig(device)
|
||||
}
|
||||
|
||||
func (f *NetworkFingerprint) nativeIpAddress(device string) (string, error) {
|
||||
// Find IP address on configured interface
|
||||
var ip string
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "", errors.New("could not retrieve interface list")
|
||||
}
|
||||
|
||||
// TODO: should we handle IPv6 here? How do we determine precedence?
|
||||
for _, i := range ifaces {
|
||||
if i.Name == device {
|
||||
addrs, _ := i.Addrs()
|
||||
for _, a := range addrs {
|
||||
switch v := a.(type) {
|
||||
case *net.IPNet:
|
||||
if v.IP.To4() != nil {
|
||||
ip = v.IP.String()
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if v.IP.To4() != nil {
|
||||
ip = v.IP.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if net.ParseIP(ip) == nil {
|
||||
return "", errors.New(fmt.Sprintf("could not parse IP address `%s`", ip))
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
// ifConfig returns the IP Address for this node according to ifConfig, for the
|
||||
// specified device.
|
||||
func (f *NetworkFingerprint) ifConfig(device string) string {
|
||||
|
||||
@@ -192,6 +192,9 @@ func (a *Agent) setupClient() error {
|
||||
conf.AllocDir = a.config.Client.AllocDir
|
||||
}
|
||||
conf.Servers = a.config.Client.Servers
|
||||
if a.config.Client.Iface != "" {
|
||||
conf.Iface = a.config.Client.Iface
|
||||
}
|
||||
|
||||
// Setup the node
|
||||
conf.Node = new(structs.Node)
|
||||
|
||||
@@ -139,6 +139,9 @@ type ClientConfig struct {
|
||||
|
||||
// Metadata associated with the node
|
||||
Meta map[string]string `hcl:"meta"`
|
||||
|
||||
// Interface to use for network fingerprinting
|
||||
Iface string `hcl:"iface"`
|
||||
}
|
||||
|
||||
// ServerConfig is configuration specific to the server mode
|
||||
@@ -384,6 +387,9 @@ func (a *ClientConfig) Merge(b *ClientConfig) *ClientConfig {
|
||||
if b.NodeClass != "" {
|
||||
result.NodeClass = b.NodeClass
|
||||
}
|
||||
if b.Iface != "" {
|
||||
result.Iface = b.Iface
|
||||
}
|
||||
|
||||
// Add the servers
|
||||
result.Servers = append(result.Servers, b.Servers...)
|
||||
|
||||
Reference in New Issue
Block a user