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:
Antoine POPINEAU
2015-10-01 17:31:47 +02:00
parent 6adc958a27
commit 7fc3f83672
4 changed files with 61 additions and 1 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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...)