summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorphreakocious <phreakocious@gmxxxx.com>2015-12-08 17:03:45 +0000
committerphreakocious <phreakocious@gmxxxx.com>2015-12-11 19:10:51 +0000
commitafd42e9122f057ab00dd24357c28dc2ad6806434 (patch)
tree049f4aebd5c6e55718b972773c8489597e25caaf
parentde20410be19e8b88a17d0a4a27b9e5c16875baeb (diff)
downloadohai-afd42e9122f057ab00dd24357c28dc2ad6806434.tar.gz
Add support for collecting ethernet layer one information from ethtool on linux.
Add test for find_ethtool_binary function and verify results match what is expected need to return what we pass in or things will break... add faking detection of ethtool.. make wording consistent.. clarify that speed is link speed and make it an integer
-rw-r--r--lib/ohai/plugins/linux/network.rb28
-rw-r--r--spec/unit/plugins/linux/network_spec.rb48
2 files changed, 76 insertions, 0 deletions
diff --git a/lib/ohai/plugins/linux/network.rb b/lib/ohai/plugins/linux/network.rb
index 51eff9dd..94bcc7a3 100644
--- a/lib/ohai/plugins/linux/network.rb
+++ b/lib/ohai/plugins/linux/network.rb
@@ -41,6 +41,10 @@ Ohai.plugin(:Network) do
["/sbin/ip", "/usr/bin/ip", "/bin/ip"].any? { |path| File.exist?(path) }
end
+ def find_ethtool_binary
+ ["/sbin/ethtool", "/usr/sbin/ethtool"].find { |path| File.exist?(path) }
+ end
+
def is_openvz?
::File.directory?('/proc/vz')
end
@@ -134,6 +138,28 @@ Ohai.plugin(:Network) do
end.compact.flatten
end
+ def ethernet_layer_one(iface)
+ return iface unless ethtool_binary = find_ethtool_binary
+ keys = %w[ Speed Duplex Port Transceiver Auto-negotiation MDI-X ]
+ iface.each_key do |tmp_int|
+ next unless iface[tmp_int][:encapsulation] == 'Ethernet'
+ so = shell_out("#{ethtool_binary} #{tmp_int}")
+ so.stdout.lines do |line|
+ line.chomp!
+ Ohai::Log.debug("Parsing ethtool output: #{line}")
+ line.lstrip!
+ k, v = line.split(': ')
+ next unless keys.include? k
+ k.downcase!
+ if k == 'speed'
+ k = 'link_speed' # This is not necessarily the maximum speed the NIC supports
+ v = v[/\d+/].to_i
+ end
+ iface[tmp_int][k] = v
+ end
+ end
+ iface
+ end
def link_statistics(iface, net_counters)
so = shell_out("ip -d -s link")
@@ -477,6 +503,8 @@ Ohai.plugin(:Network) do
end
end
end
+
+ iface = ethernet_layer_one(iface)
counters[:network][:interfaces] = net_counters
network["interfaces"] = iface
end
diff --git a/spec/unit/plugins/linux/network_spec.rb b/spec/unit/plugins/linux/network_spec.rb
index 7b5dcbde..2efe05aa 100644
--- a/spec/unit/plugins/linux/network_spec.rb
+++ b/spec/unit/plugins/linux/network_spec.rb
@@ -298,6 +298,31 @@ fe80::21c:eff:fe12:3456 dev eth0.153 lladdr 00:1c:0e:30:28:00 router REACHABLE
'
}
+ let(:linux_ethtool) {
+'Settings for eth0:
+ Supported ports: [ FIBRE ]
+ Supported link modes: 1000baseT/Full
+ 10000baseT/Full
+ Supported pause frame use: No
+ Supports auto-negotiation: Yes
+ Advertised link modes: 1000baseT/Full
+ 10000baseT/Full
+ Advertised pause frame use: No
+ Advertised auto-negotiation: Yes
+ Speed: 10000Mb/s
+ Duplex: Full
+ Port: FIBRE
+ PHYAD: 0
+ Transceiver: external
+ Auto-negotiation: on
+ Supports Wake-on: d
+ Wake-on: d
+ Current message level: 0x00000007 (7)
+ drv probe link
+ Link detected: yes
+'
+ }
+
before(:each) do
allow(plugin).to receive(:collect_os).and_return(:linux)
@@ -311,6 +336,7 @@ fe80::21c:eff:fe12:3456 dev eth0.153 lladdr 00:1c:0e:30:28:00 router REACHABLE
allow(plugin).to receive(:shell_out).with("route -n").and_return(mock_shell_out(0, linux_route_n, ""))
allow(plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, linux_ifconfig, ""))
allow(plugin).to receive(:shell_out).with("arp -an").and_return(mock_shell_out(0, linux_arp_an, ""))
+ allow(plugin).to receive(:shell_out).with(/ethtool/).and_return(mock_shell_out(0, linux_ethtool, ""))
end
describe "#iproute2_binary_available?" do
@@ -323,11 +349,23 @@ fe80::21c:eff:fe12:3456 dev eth0.153 lladdr 00:1c:0e:30:28:00 router REACHABLE
end
end
+ describe "#find_ethtool_binary" do
+ ["/sbin/ethtool", "/usr/sbin/ethtool"].each do |path|
+ it "accepts #{path}" do
+ allow(File).to receive(:exist?).and_return(false)
+ allow(File).to receive(:exist?).with(path).and_return(true)
+ expect(plugin.find_ethtool_binary).to end_with("/ethtool")
+ end
+ end
+ end
+
+
["ifconfig","iproute2"].each do |network_method|
describe "gathering IP layer address info via #{network_method}" do
before(:each) do
allow(plugin).to receive(:iproute2_binary_available?).and_return( network_method == "iproute2" )
+ allow(plugin).to receive(:find_ethtool_binary).and_return( '/sbin/ethtool' )
plugin.run
end
@@ -340,6 +378,15 @@ fe80::21c:eff:fe12:3456 dev eth0.153 lladdr 00:1c:0e:30:28:00 router REACHABLE
expect(plugin['network']['interfaces'].keys.sort).to eq(["eth0", "eth0.11", "eth0.151", "eth0.152", "eth0.153", "eth0:5", "eth3", "foo:veth0@eth0", "lo", "ovs-system", "tun0", "venet0", "venet0:0", "xapi1"])
end
+ it "detects the layer one details of an ethernet interface" do
+ expect(plugin['network']['interfaces']['eth0']['link_speed']).to eq(10000)
+ expect(plugin['network']['interfaces']['eth0']['duplex']).to eq('Full')
+ expect(plugin['network']['interfaces']['eth0']['port']).to eq('FIBRE')
+ expect(plugin['network']['interfaces']['eth0']['transceiver']).to eq('external')
+ expect(plugin['network']['interfaces']['eth0']['auto-negotiation']).to eq('on')
+ expect(plugin['network']['interfaces']['eth0']['mdi-x']).to be_nil
+ end
+
it "detects the ipv4 addresses of the ethernet interface" do
expect(plugin['network']['interfaces']['eth0']['addresses'].keys).to include('10.116.201.76')
expect(plugin['network']['interfaces']['eth0']['addresses']['10.116.201.76']['netmask']).to eq('255.255.255.0')
@@ -547,6 +594,7 @@ Destination Gateway Genmask Flags Metric Ref Use Iface
before(:each) do
allow(File).to receive(:exist?).with("/sbin/ip").and_return(true) # iproute2 only
allow(File).to receive(:exist?).with("/proc/net/if_inet6").and_return(true) # ipv6 is enabled
+ allow(File).to receive(:exist?).with("/sbin/ethtool").and_return(true) # ethtool is available
plugin.run
end