diff options
author | phreakocious <phreakocious@gmxxxx.com> | 2015-12-08 17:03:45 +0000 |
---|---|---|
committer | phreakocious <phreakocious@gmxxxx.com> | 2015-12-11 19:10:51 +0000 |
commit | afd42e9122f057ab00dd24357c28dc2ad6806434 (patch) | |
tree | 049f4aebd5c6e55718b972773c8489597e25caaf | |
parent | de20410be19e8b88a17d0a4a27b9e5c16875baeb (diff) | |
download | ohai-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.rb | 28 | ||||
-rw-r--r-- | spec/unit/plugins/linux/network_spec.rb | 48 |
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 |