diff --git a/client/config/config.go b/client/config/config.go index 185b31012c5..e5f868b7970 100644 --- a/client/config/config.go +++ b/client/config/config.go @@ -34,6 +34,10 @@ type Config struct { // Network interface to be used in network fingerprinting NetworkInterface string + // Network speed is the default speed of network interfaces if they can not + // be determined dynamically. + NetworkSpeed int + // Servers is a list of known server addresses. These are as "host:port" Servers []string diff --git a/client/fingerprint/env_aws_test.go b/client/fingerprint/env_aws_test.go index 1ea0020629f..acc70e689a1 100644 --- a/client/fingerprint/env_aws_test.go +++ b/client/fingerprint/env_aws_test.go @@ -70,7 +70,6 @@ func TestEnvAWSFingerprint_aws(t *testing.T) { "platform.aws.public-ipv4", "platform.aws.placement.availability-zone", "network.ip-address", - "network.internal-ip", } for _, k := range keys { diff --git a/client/fingerprint/network_test.go b/client/fingerprint/network_test.go index 142ad13eee2..077d5a57315 100644 --- a/client/fingerprint/network_test.go +++ b/client/fingerprint/network_test.go @@ -13,8 +13,9 @@ func TestNetworkFingerprint_basic(t *testing.T) { node := &structs.Node{ Attributes: make(map[string]string), } + cfg := &config.Config{NetworkSpeed: 100} - ok, err := f.Fingerprint(&config.Config{}, node) + ok, err := f.Fingerprint(cfg, node) if err != nil { t.Fatalf("err: %v", err) } @@ -45,4 +46,7 @@ func TestNetworkFingerprint_basic(t *testing.T) { if net.Device == "" { t.Fatal("Expected Network Resource to have a Device Name") } + if net.MBits == 0 { + t.Fatal("Expected Network Resource to have a non-zero bandwith") + } } diff --git a/client/fingerprint/network_unix.go b/client/fingerprint/network_unix.go index b74062848f2..6a792538451 100644 --- a/client/fingerprint/network_unix.go +++ b/client/fingerprint/network_unix.go @@ -50,10 +50,15 @@ func (f *NetworkFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) node.Attributes["network.ip-address"] = ip newNetwork.IP = ip newNetwork.CIDR = newNetwork.IP + "/32" + } else { + return false, fmt.Errorf("Unable to determine IP on network interface %v", defaultDevice) } if throughput := f.linkSpeed(defaultDevice); throughput > 0 { newNetwork.MBits = throughput + } else { + f.logger.Printf("[DEBUG] fingerprint.network: Unable to read link speed; setting to default %v", cfg.NetworkSpeed) + newNetwork.MBits = cfg.NetworkSpeed } if node.Resources == nil { diff --git a/command/agent/agent.go b/command/agent/agent.go index 47b36cab642..5ffc3e8b7e0 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -196,6 +196,9 @@ func (a *Agent) setupClient() error { conf.NetworkInterface = a.config.Client.NetworkInterface } conf.Options = a.config.Client.Options + if a.config.Client.NetworkSpeed != 0 { + conf.NetworkSpeed = a.config.Client.NetworkSpeed + } // Setup the node conf.Node = new(structs.Node) diff --git a/command/agent/command.go b/command/agent/command.go index a800425552d..ecae14d81a7 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -79,6 +79,8 @@ func (c *Command) readConfig() *Config { flags.StringVar(&cmdConfig.Client.NodeClass, "node-class", "", "") flags.StringVar(&servers, "servers", "", "") flags.Var((*sliceflag.StringFlag)(&meta), "meta", "") + flags.StringVar(&cmdConfig.Client.NetworkInterface, "network-interface", "", "") + flags.IntVar(&cmdConfig.Client.NetworkSpeed, "network-speed", 0, "") // General options flags.Var((*sliceflag.StringFlag)(&configPath), "config", "config") @@ -663,6 +665,13 @@ Client Options: parses a single KEY=VALUE pair. Repeat the meta flag for each key/value pair to be added. + -network-interface + Forces the network fingerprinter to use the specified network interface. + + -network-speed + The default speed for network interfaces in MBits if the link speed can not + be determined dynamically. + Atlas Options: -atlas= diff --git a/command/agent/config.go b/command/agent/config.go index 4f12dc99dac..24f45f95500 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -148,6 +148,9 @@ type ClientConfig struct { // Interface to use for network fingerprinting NetworkInterface string `hcl:"network_interface"` + + // The network link speed to use if it can not be determined dynamically. + NetworkSpeed int `hcl:"network_speed"` } // ServerConfig is configuration specific to the server mode @@ -236,7 +239,8 @@ func DefaultConfig() *Config { AdvertiseAddrs: &AdvertiseAddrs{}, Atlas: &AtlasConfig{}, Client: &ClientConfig{ - Enabled: false, + Enabled: false, + NetworkSpeed: 100, }, Server: &ServerConfig{ Enabled: false, @@ -396,6 +400,9 @@ func (a *ClientConfig) Merge(b *ClientConfig) *ClientConfig { if b.NetworkInterface != "" { result.NetworkInterface = b.NetworkInterface } + if b.NetworkSpeed != 0 { + result.NetworkSpeed = b.NetworkSpeed + } // Add the servers result.Servers = append(result.Servers, b.Servers...) diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 3faac3b6b61..530c4227dbc 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -39,6 +39,7 @@ func TestConfig_Merge(t *testing.T) { Options: map[string]string{ "foo": "bar", }, + NetworkSpeed: 100, }, Server: &ServerConfig{ Enabled: false, @@ -96,6 +97,7 @@ func TestConfig_Merge(t *testing.T) { "foo": "bar", "baz": "zip", }, + NetworkSpeed: 100, }, Server: &ServerConfig{ Enabled: true, @@ -358,6 +360,7 @@ func TestConfig_LoadConfigString(t *testing.T) { "foo": "bar", "baz": "zip", }, + NetworkSpeed: 100, }, Server: &ServerConfig{ Enabled: true, @@ -429,6 +432,7 @@ client { foo = "bar" baz = "zip" } + network_speed = 100 } server { enabled = true diff --git a/website/source/docs/agent/config.html.md b/website/source/docs/agent/config.html.md index 3eb5174f4a3..56532f921e4 100644 --- a/website/source/docs/agent/config.html.md +++ b/website/source/docs/agent/config.html.md @@ -207,10 +207,13 @@ configured on server nodes. option is not required and has no default. * `meta`: This is a key/value mapping of metadata pairs. This is a free-form map and can contain any string values. - * `network_interface`: This is a string to force network fingerprinting to use - a specific network interface * `options`: This is a key/value mapping of internal configuration for clients, such as for driver configuration. + * `network_interface`: This is a string to force + network fingerprinting to use a specific network interface + * `network_speed`: This is an int that sets the + default link speed of network interfaces, in megabytes, if their speed can + not be determined dynamically. ## Atlas Options @@ -257,6 +260,10 @@ via CLI arguments. The `agent` command accepts the following arguments: Nomad. No other configuration is required to start the agent in this mode. * `-log-level=`: Equivalent to the [log_level](#log_level) config option. * `-meta=`: Equivalent to the Client [meta](#meta) config option. +* `-network-interface`: Equivalent to the Client + [network_interface](#network_interface) config option. +* `-network-speed`: Equivalent to the Client + [network_speed](#network_speed) config option. * `-node=`: Equivalent to the [name](#name) config option. * `-node-class=`: Equivalent to the Client [node_class](#node_class) config option.