mirror of
https://github.com/inspec/inspec
synced 2024-11-22 20:53:11 +00:00
Adds support for interface on BSD and MacOS
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
This commit is contained in:
parent
9109864fe2
commit
a4000d6912
5 changed files with 72 additions and 2 deletions
|
@ -9,7 +9,7 @@ Use the `interface` Chef InSpec audit resource to test basic network adapter pro
|
|||
|
||||
* On Linux platforms, `/sys/class/net/#{iface}` is used as source
|
||||
* On the Windows platform, the `Get-NetAdapter` cmdlet is used as source
|
||||
* The MacOS platform is not currently supported.
|
||||
* On BSD and MacOS platforms, the `ifconfig` command is used as source. Link speed may not be available.
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -81,7 +81,7 @@ The `name` property returns the name of the interface:
|
|||
|
||||
### speed
|
||||
|
||||
The `speed` property tests the speed of the network interface, in MB/sec:
|
||||
The `speed` property tests the speed of the network interface, in MB/sec. Note: On BSD and MacOS platforms, this value may be nil, because it difficult to obtain reliably.
|
||||
|
||||
its('speed') { should eq 1000 }
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ module Inspec::Resources
|
|||
@cache ||= begin
|
||||
provider = LinuxInterface.new(inspec) if inspec.os.linux?
|
||||
provider = WindowsInterface.new(inspec) if inspec.os.windows?
|
||||
provider = BsdInterface.new(inspec) if inspec.os.bsd? # includes macOS
|
||||
Hash(provider && provider.interface_info(@iface))
|
||||
end
|
||||
end
|
||||
|
@ -98,6 +99,52 @@ module Inspec::Resources
|
|||
end
|
||||
end
|
||||
|
||||
class BsdInterface < InterfaceInfo
|
||||
def interface_info(iface)
|
||||
cmd = inspec.command("ifconfig #{iface}")
|
||||
return nil if cmd.exit_status.to_i != 0
|
||||
|
||||
lines = cmd.stdout.split("\n")
|
||||
iface_info = {
|
||||
name: iface,
|
||||
ipv4_addresses: [], # Actually CIDRs
|
||||
ipv6_addresses: [], # are expected to go here
|
||||
}
|
||||
|
||||
iface_info[:up] = lines[0].include?("UP")
|
||||
lines.each do |line|
|
||||
# IPv4 case
|
||||
m = line.match(/^\s+inet\s+((?:\d{1,3}\.){3}\d{1,3})\s+netmask\s+(0x[a-f0-9]{8})/)
|
||||
if m
|
||||
ip = m[1]
|
||||
hex_mask = m[2]
|
||||
cidr = hex_mask.to_i(16).to_s(2).count("1")
|
||||
iface_info[:ipv4_addresses] << "#{ip}/#{cidr}"
|
||||
next
|
||||
end
|
||||
|
||||
# IPv6 case
|
||||
m = line.match(/^\s+inet6\s+([a-f0-9:]+)%#{iface}\s+prefixlen\s+(\d+)/)
|
||||
if m
|
||||
ip = m[1]
|
||||
cidr = m[2]
|
||||
iface_info[:ipv6_addresses] << "#{ip}/#{cidr}"
|
||||
next
|
||||
end
|
||||
|
||||
# Speed detect, crummy - can't detect wifi, finds any number in the string
|
||||
# Ethernet autoselect (1000baseT <full-duplex>)
|
||||
m = line.match(/^\s+media:\D+(\d+)/)
|
||||
if m
|
||||
iface_info[:speed] = m[1].to_i
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
iface_info
|
||||
end
|
||||
end
|
||||
|
||||
class LinuxInterface < InterfaceInfo
|
||||
def interface_info(iface)
|
||||
# will return "[mtu]\n1500\n[type]\n1"
|
||||
|
|
7
test/fixtures/cmd/ifconfig-en0
vendored
Normal file
7
test/fixtures/cmd/ifconfig-en0
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
ether ac:bc:32:c7:30:e7
|
||||
inet6 fe80::8b6:c2cc:2928:3b61%en0 prefixlen 64 secured scopeid 0x5
|
||||
inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
|
||||
nd6 options=201<PERFORMNUD,DAD>
|
||||
media: Ethernet autoselect (1000baseT <full-duplex>)
|
||||
status: active
|
|
@ -314,6 +314,7 @@ class MockLoader
|
|||
"/sbin/ip -br -6 address show dev eth0" => cmd.call("interface-addresses-6"),
|
||||
"Get-NetAdapter | Select-Object -Property Name, InterfaceDescription, Status, State, MacAddress, LinkSpeed, ReceiveLinkSpeed, TransmitLinkSpeed, Virtual | ConvertTo-Json" => cmd.call("Get-NetAdapter"),
|
||||
"Get-NetIPAddress | Select-Object -Property IPv6Address, IPv4Address, InterfaceAlias, PrefixLength | ConvertTo-Json" => cmd.call("Get-NetIPAddress"),
|
||||
"ifconfig en0" => cmd.call("ifconfig-en0"),
|
||||
# bridge on linux
|
||||
"ls -1 /sys/class/net/br0/brif/" => cmd.call("ls-sys-class-net-br"),
|
||||
# bridge on Windows
|
||||
|
|
|
@ -81,6 +81,21 @@ describe "Inspec::Resources::Interface" do
|
|||
_(resource.ipv6_cidrs).must_be_empty
|
||||
end
|
||||
|
||||
it "verify interface on macos" do
|
||||
resource = MockLoader.new(:osx104).load_resource("interface", "en0")
|
||||
_(resource.exists?).must_equal true
|
||||
_(resource.up?).must_equal true
|
||||
_(resource.speed).must_equal 1000
|
||||
_(resource.name).must_equal "en0"
|
||||
_(resource.ipv4_cidrs).must_include "192.168.1.2/24"
|
||||
_(resource.ipv4_addresses).must_include "192.168.1.2"
|
||||
_(resource.ipv4_addresses_netmask).must_include "192.168.1.2/255.255.255.0"
|
||||
_(resource.ipv6_cidrs).must_include "fe80::8b6:c2cc:2928:3b61/64"
|
||||
_(resource.ipv6_addresses).must_include "fe80::8b6:c2cc:2928:3b61"
|
||||
_(resource.ipv4_address?).must_equal true
|
||||
_(resource.ipv6_address?).must_equal true
|
||||
end
|
||||
|
||||
# undefined
|
||||
it "verify interface on unsupported os" do
|
||||
resource = MockLoader.new(:undefined).load_resource("interface", "eth0")
|
||||
|
|
Loading…
Reference in a new issue