mirror of
https://github.com/inspec/inspec
synced 2024-11-26 22:50:36 +00:00
Merge pull request #5036 from inspec/cw/interface-improvements
Additions to the interface resource
This commit is contained in:
commit
af5fd7bd03
13 changed files with 393 additions and 22 deletions
|
@ -5,10 +5,11 @@ platform: os
|
|||
|
||||
# interface
|
||||
|
||||
Use the `interface` Chef InSpec audit resource to test basic network adapter properties, such as name, status, and link speed (in MB/sec).
|
||||
Use the `interface` Chef InSpec audit resource to test basic network adapter properties, such as name, status, IP addresses, and link speed (in MB/sec).
|
||||
|
||||
* On Linux platforms, `/sys/class/net/#{iface}` is used as source
|
||||
* On the Windows platform, the `Get-NetAdapter` cmdlet is used as source
|
||||
* On BSD and MacOS platforms, the `ifconfig` command is used as source. Link speed may not be available.
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -20,7 +21,7 @@ This resource is distributed along with Chef InSpec itself. You can use it autom
|
|||
|
||||
### Version
|
||||
|
||||
This resource first became available in v1.0.0 of InSpec.
|
||||
This resource first became available in v1.0.0 of Chef InSpec.
|
||||
|
||||
## Syntax
|
||||
|
||||
|
@ -30,61 +31,71 @@ An `interface` resource block declares network interface properties to be tested
|
|||
it { should be_up }
|
||||
its('speed') { should eq 1000 }
|
||||
its('name') { should eq eth0 }
|
||||
its('ipv4_addresses') { should include '10.0.0.5' }
|
||||
end
|
||||
|
||||
<br>
|
||||
|
||||
## Properties
|
||||
|
||||
`name`, `speed`
|
||||
`ipv4_address`, `ipv4_addresses`, `ipv4_addresses_netmask`, `ipv4_cidrs`, `ipv6_addresses`, `ipv6_cidrs`, `name`, `speed`
|
||||
|
||||
<br>
|
||||
|
||||
## Resource Property Examples
|
||||
|
||||
### name
|
||||
### ipv4_address
|
||||
|
||||
The `name` property tests if the named network interface exists:
|
||||
Returns the first `ipv4_addresses` entry as a String. Note: this property is incompatible with ServerSpec, which returns the value including the CIDR range, such as '10.0.0.5/32'.
|
||||
|
||||
its('name') { should eq eth0 }
|
||||
|
||||
### speed
|
||||
|
||||
The `speed` property tests the speed of the network interface, in MB/sec:
|
||||
|
||||
its('speed') { should eq 1000 }
|
||||
its('ipv4_address') { should eq '10.0.0.5' }
|
||||
|
||||
### ipv4_addresses
|
||||
|
||||
The `ipv4_addresses` property tests if the specified address exists on the named network interface:
|
||||
The `ipv4_addresses` property returns an Array of IPv4 addresses as Strings. You may then test if the specified address exists on the named network interface:
|
||||
|
||||
its('ipv4_addresses') { should include '127.0.0.1' }
|
||||
|
||||
### ipv4_addresses_netmask
|
||||
### ipv4\_addresses\_netmask
|
||||
|
||||
The `ipv4_addresses_netmask` property tests if the specified address and netmask exists on the named network interface:
|
||||
The `ipv4_addresses_netmask` property returns an Array of Strings with each containing the IPv4 address, a slash, and the netmask. You may then test if the specified address and netmask exists on the named network interface:
|
||||
|
||||
its('ipv4_addresses_netmask') { should include '127.0.0.1/255.0.0.0' }
|
||||
|
||||
### ipv6_address
|
||||
|
||||
Returns the first `ipv6_address` entry. Note: this property is incompatible with ServerSpec, which returns the value including the CIDR range.
|
||||
|
||||
its('ipv6_address') { should eq '2089:98b::faeb' }
|
||||
|
||||
### ipv6_addresses
|
||||
|
||||
The `ipv6_addresses` property tests if the specified address exists on the named network interface:
|
||||
The `ipv6_addresses` property returns an Array of Strings and tests if the specified address exists on the named network interface:
|
||||
|
||||
its('ipv6_addresses') { should include '::1' }
|
||||
|
||||
### ipv4_cidrs
|
||||
|
||||
The `ipv4_cidrs` property tests if the specified address and netmask combination exists on the named network interface:
|
||||
The `ipv4_cidrs` property returns an Array of Strings and tests if the specified address and netmask combination exists on the named network interface:
|
||||
|
||||
its('ipv4_cidrs') { should include '127.0.0.1/8' }
|
||||
|
||||
### ipv6_cidrs
|
||||
|
||||
The `ipv6_cidrs` property tests if the specified address and netmask combination exists on the named network interface:
|
||||
The `ipv6_cidrs` property returns an Array of Strings and tests if the specified address and netmask combination exists on the named network interface:
|
||||
|
||||
its('ipv6_cidrs') { should include '::1/128' }
|
||||
|
||||
<br>
|
||||
### name
|
||||
|
||||
The `name` property returns the name of the interface:
|
||||
|
||||
its('name') { should eq 'eth0' }
|
||||
|
||||
### speed
|
||||
|
||||
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 }
|
||||
|
||||
## Matchers
|
||||
|
||||
|
@ -96,13 +107,19 @@ The `be_up` matcher tests if the network interface is available:
|
|||
|
||||
it { should be_up }
|
||||
|
||||
### have_an_ipv4_address
|
||||
### exist
|
||||
|
||||
The `exist` matcher tests if the network interface exists:
|
||||
|
||||
it { should exist }
|
||||
|
||||
### have\_an\_ipv4\_address
|
||||
|
||||
The `have_an_ipv4_address` matcher tests if the network interface has any IPv4 addresses assigned:
|
||||
|
||||
it { should have_an_ipv4_address }
|
||||
|
||||
### have_an_ipv6_address
|
||||
### have\_an\_ipv6\_address
|
||||
|
||||
The `have_an_ipv6_address` matcher tests if the network interface has any IPv6 addresses assigned:
|
||||
|
||||
|
|
72
docs/resources/interfaces.md.erb
Normal file
72
docs/resources/interfaces.md.erb
Normal file
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
title: About the interfaces Resource
|
||||
platform: os
|
||||
---
|
||||
|
||||
# interfaces
|
||||
|
||||
Use the `interfaces` Chef InSpec audit resource to test the properties of multiple network interfaces on the system.
|
||||
|
||||
## Syntax
|
||||
|
||||
An `interfaces` resource block may take no arguments, in which case it will list all interfaces:
|
||||
|
||||
describe interfaces do
|
||||
its('names') { should include 'eth0' }
|
||||
end
|
||||
|
||||
An `interfaces` resource block may take a where clause, filtering on a Filter Criterion:
|
||||
|
||||
# All eth- interfaces
|
||||
describe interfaces.where(name: /^eth\d+/)
|
||||
its('names') { should include 'eth0' }
|
||||
end
|
||||
|
||||
Like any Chef InSpec resource, you may also use it for data lookup instead of testing:
|
||||
|
||||
# We are an IPv6 shop
|
||||
interfaces.where(name: /^eth/).names do |name|
|
||||
describe interface(name) do
|
||||
it { should have_ipv6_address }
|
||||
end
|
||||
end
|
||||
|
||||
# Obtain the machine's main IP address
|
||||
my_ip = interfaces.ipv4_address
|
||||
|
||||
## Filter Criteria
|
||||
|
||||
### name
|
||||
|
||||
String. The name of an interface.
|
||||
|
||||
## Properties
|
||||
|
||||
### count
|
||||
|
||||
The `count` property returns an Integer describing how many interfaces matched.
|
||||
|
||||
its("count") { should eq 6 }
|
||||
|
||||
### ipv4_address
|
||||
|
||||
Attempts to guess the "first" "real" IPv4 address on any interface. Looks for interfaces that are up and have IPv4 addresses assigned, then tries to filter out loopback, management (10/8) and local (192.168/16) IP addresses, returning the best of of those that it can; you may still get nil, or a loopback address. Note that if the machine is behind NAT this will not be the external IP address; use the `http` resource to query an IP lookup service for that.
|
||||
|
||||
its('ipv4_address') { should_not eq '127.0.0.1' }
|
||||
|
||||
### names
|
||||
|
||||
The `names` property returns an Array of Strings representing the names of the interfaces.
|
||||
|
||||
its("names") { should include "eth0" }
|
||||
|
||||
## Matchers
|
||||
|
||||
For a full list of available universal matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/).
|
||||
|
||||
### exist
|
||||
|
||||
The `exist` matcher tests true if at least one interface exists on the system. This is almost always the case.
|
||||
|
||||
it { should exist }
|
||||
|
|
@ -47,10 +47,18 @@ module Inspec::Resources
|
|||
ipv6_addresses && !ipv6_addresses.empty?
|
||||
end
|
||||
|
||||
def ipv4_address
|
||||
ipv4_addresses.first
|
||||
end
|
||||
|
||||
def ipv4_addresses
|
||||
ipv4_cidrs.map { |i| i.split("/")[0] }
|
||||
end
|
||||
|
||||
def ipv6_address
|
||||
ipv6_addresses.first
|
||||
end
|
||||
|
||||
def ipv6_addresses
|
||||
ipv6_cidrs.map { |i| i.split("/")[0] }
|
||||
end
|
||||
|
@ -85,6 +93,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 +107,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"
|
||||
|
|
119
lib/inspec/resources/interfaces.rb
Normal file
119
lib/inspec/resources/interfaces.rb
Normal file
|
@ -0,0 +1,119 @@
|
|||
require "inspec/utils/filter"
|
||||
require "inspec/resources/command"
|
||||
|
||||
module Inspec::Resources
|
||||
class Interfaces < Inspec.resource(1)
|
||||
name "interfaces"
|
||||
supports platform: "unix"
|
||||
supports platform: "windows"
|
||||
desc "Use the interfaces InSpec audit resource to test properties for multiple network interfaces installed on the system"
|
||||
example <<~EXAMPLE
|
||||
describe interfaces do
|
||||
its('names') { should include 'eth0' }
|
||||
end
|
||||
EXAMPLE
|
||||
|
||||
attr_reader :iface_data
|
||||
|
||||
def to_s
|
||||
"Interfaces"
|
||||
end
|
||||
|
||||
filter = FilterTable.create
|
||||
filter.register_column(:names, field: "name")
|
||||
.install_filter_methods_on_resource(self, :scan_interfaces)
|
||||
|
||||
def ipv4_address
|
||||
require "ipaddr"
|
||||
|
||||
# Loop over interface names
|
||||
# Select those that are up and have an ipv4 address
|
||||
interfaces = names.map { |n| inspec.interface(n) }.select do |i|
|
||||
i.ipv4_address? && i.up?
|
||||
end
|
||||
|
||||
addrs = interfaces.map(&:ipv4_addresses).flatten.map { |a| IPAddr.new(a) }
|
||||
|
||||
# Look for progressively "better" IP addresses
|
||||
[
|
||||
# Loopback and private IP ranges
|
||||
IPAddr.new("127.0.0.0/8"),
|
||||
IPAddr.new("192.168.0.0/16"),
|
||||
IPAddr.new("172.16.0.0/12"),
|
||||
IPAddr.new("10.0.0.0/8"),
|
||||
].each do |private_range|
|
||||
filtered_addrs = addrs.reject { |a| private_range.include?(a) }
|
||||
if filtered_addrs.empty?
|
||||
# Everything we had was a private or loopback IP. Return the "best" thing we were left with.
|
||||
return addrs.first.to_s
|
||||
end
|
||||
|
||||
addrs = filtered_addrs
|
||||
end
|
||||
addrs.first.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scan_interfaces
|
||||
@iface_data ||= begin
|
||||
provider = LinuxInterfaceLister.new(inspec) if inspec.os.linux?
|
||||
provider = WindowsInterfaceLister.new(inspec) if inspec.os.windows?
|
||||
provider = BsdInterfaceLister.new(inspec) if inspec.os.bsd? # includes macOS
|
||||
Array(provider && provider.scan_interfaces)
|
||||
end
|
||||
end
|
||||
|
||||
class InterfaceLister
|
||||
attr_reader :inspec
|
||||
def initialize(inspec)
|
||||
@inspec = inspec
|
||||
end
|
||||
end
|
||||
|
||||
class BsdInterfaceLister < InterfaceLister
|
||||
def scan_interfaces
|
||||
iface_data = []
|
||||
cmd = inspec.command("ifconfig -a")
|
||||
cmd.stdout.split("\n").each do |line|
|
||||
# lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
|
||||
m = line.match(/^(\S+):/)
|
||||
if m
|
||||
iface_data << { "name" => m[1] }
|
||||
end
|
||||
end
|
||||
iface_data
|
||||
end
|
||||
end
|
||||
|
||||
class LinuxInterfaceLister < InterfaceLister
|
||||
def scan_interfaces
|
||||
iface_data = []
|
||||
cmd = inspec.command("ls /sys/class/net")
|
||||
cmd.stdout.split("\n").each do |iface|
|
||||
iface_data << { "name" => iface }
|
||||
end
|
||||
iface_data
|
||||
end
|
||||
end
|
||||
|
||||
class WindowsInterfaceLister < InterfaceLister
|
||||
def scan_interfaces
|
||||
iface_data = []
|
||||
cmd = inspec.command("Get-NetAdapter | Select-Object -Property Name | ConvertTo-Json")
|
||||
begin
|
||||
adapter_info = JSON.parse(cmd.stdout)
|
||||
# May be a Hash if only one, or Array if multiple - normalize to Array
|
||||
adapter_info = [ adapter_info ] if adapter_info.is_a? Hash
|
||||
rescue JSON::ParserError => _e
|
||||
return nil
|
||||
end
|
||||
adapter_info.each do |info|
|
||||
iface_data << { "name" => info["Name"] }
|
||||
end
|
||||
iface_data
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
8
test/fixtures/cmd/Get-NetAdapter-Name
vendored
Normal file
8
test/fixtures/cmd/Get-NetAdapter-Name
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"Name": "vEthernet (Intel(R) PRO 1000 MT Network Connection - Virtual Switch)"
|
||||
},
|
||||
{
|
||||
"Name": "Ethernet0"
|
||||
}
|
||||
]
|
15
test/fixtures/cmd/ifconfig-a
vendored
Normal file
15
test/fixtures/cmd/ifconfig-a
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
|
||||
options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
|
||||
ether 08:00:27:5f:9d:3b
|
||||
hwaddr 08:00:27:5f:9d:3b
|
||||
inet 10.0.2.15 netmask 0xffffff00 broadcast 10.0.2.255
|
||||
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
|
||||
media: Ethernet autoselect (1000baseT <full-duplex>)
|
||||
status: active
|
||||
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
|
||||
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
|
||||
inet6 ::1 prefixlen 128
|
||||
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
|
||||
inet 127.0.0.1 netmask 0xff000000
|
||||
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
|
||||
groups: lo
|
7
test/fixtures/cmd/ifconfig-em0
vendored
Normal file
7
test/fixtures/cmd/ifconfig-em0
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
em0: 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 1.2.3.4 netmask 0xffffff00 broadcast 1.2.3.255
|
||||
nd6 options=201<PERFORMNUD,DAD>
|
||||
media: Ethernet autoselect (1000baseT <full-duplex>)
|
||||
status: active
|
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
|
7
test/fixtures/cmd/ifconfig-lo0
vendored
Normal file
7
test/fixtures/cmd/ifconfig-lo0
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
|
||||
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
|
||||
inet6 ::1 prefixlen 128
|
||||
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
|
||||
inet 127.0.0.1 netmask 0xff000000
|
||||
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
|
||||
groups: lo
|
2
test/fixtures/cmd/ls-sys-class-net
vendored
Normal file
2
test/fixtures/cmd/ls-sys-class-net
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
eth0
|
||||
lo
|
|
@ -314,6 +314,13 @@ 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"),
|
||||
# network interfaces
|
||||
"ls /sys/class/net" => cmd.call("ls-sys-class-net"),
|
||||
"ifconfig -a" => cmd.call("ifconfig-a"),
|
||||
"ifconfig em0" => cmd.call("ifconfig-em0"),
|
||||
"ifconfig lo0" => cmd.call("ifconfig-lo0"),
|
||||
"Get-NetAdapter | Select-Object -Property Name | ConvertTo-Json" => cmd.call("Get-NetAdapter-Name"),
|
||||
# bridge on linux
|
||||
"ls -1 /sys/class/net/br0/brif/" => cmd.call("ls-sys-class-net-br"),
|
||||
# bridge on Windows
|
||||
|
|
|
@ -12,9 +12,11 @@ describe "Inspec::Resources::Interface" do
|
|||
_(resource.speed).must_equal 10000
|
||||
_(resource.name).must_equal "eth0"
|
||||
_(resource.ipv4_cidrs).must_include "127.0.0.1/8"
|
||||
_(resource.ipv4_address).must_equal "127.0.0.1"
|
||||
_(resource.ipv4_addresses).must_include "127.0.0.1"
|
||||
_(resource.ipv4_addresses_netmask).must_include "127.0.0.1/255.0.0.0"
|
||||
_(resource.ipv6_cidrs).must_include "::1/128"
|
||||
_(resource.ipv6_address).must_equal "::1"
|
||||
_(resource.ipv6_addresses).must_include "::1"
|
||||
_(resource.ipv4_address?).must_equal true
|
||||
_(resource.ipv6_address?).must_equal true
|
||||
|
@ -27,8 +29,10 @@ describe "Inspec::Resources::Interface" do
|
|||
_(resource.name).must_be_nil
|
||||
_(resource.speed).must_be_nil
|
||||
_(resource.ipv4_cidrs).must_be_empty
|
||||
_(resource.ipv4_address).must_be_nil
|
||||
_(resource.ipv4_addresses).must_be_empty
|
||||
_(resource.ipv4_addresses_netmask).must_be_empty
|
||||
_(resource.ipv6_address).must_be_nil
|
||||
_(resource.ipv6_cidrs).must_be_empty
|
||||
_(resource.ipv6_addresses).must_be_empty
|
||||
_(resource.ipv4_address?).must_equal false
|
||||
|
@ -42,10 +46,12 @@ describe "Inspec::Resources::Interface" do
|
|||
_(resource.up?).must_equal false
|
||||
_(resource.name).must_equal "Ethernet0"
|
||||
_(resource.speed).must_equal 0
|
||||
_(resource.ipv4_address).must_be_nil
|
||||
_(resource.ipv4_address?).must_equal false
|
||||
_(resource.ipv6_address?).must_equal false
|
||||
_(resource.ipv4_addresses).must_be_empty
|
||||
_(resource.ipv4_addresses_netmask).must_be_empty
|
||||
_(resource.ipv6_address).must_be_nil
|
||||
_(resource.ipv6_addresses).must_be_empty
|
||||
_(resource.ipv4_cidrs).must_be_empty
|
||||
_(resource.ipv6_cidrs).must_be_empty
|
||||
|
@ -58,9 +64,11 @@ describe "Inspec::Resources::Interface" do
|
|||
_(resource.name).must_equal "vEthernet (Intel(R) PRO 1000 MT Network Connection - Virtual Switch)"
|
||||
_(resource.speed).must_equal 10000000
|
||||
_(resource.ipv4_cidrs).must_include "127.0.0.1/8"
|
||||
_(resource.ipv4_address).must_equal "127.0.0.1"
|
||||
_(resource.ipv4_addresses).must_include "127.0.0.1"
|
||||
_(resource.ipv4_addresses_netmask).must_include "127.0.0.1/255.0.0.0"
|
||||
_(resource.ipv6_cidrs).must_include "::1/128"
|
||||
_(resource.ipv6_address).must_equal "::1"
|
||||
_(resource.ipv6_addresses).must_include "::1"
|
||||
_(resource.ipv4_address?).must_equal true
|
||||
_(resource.ipv6_address?).must_equal true
|
||||
|
@ -81,6 +89,23 @@ 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_address).must_equal "192.168.1.2"
|
||||
_(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_address).must_equal "fe80::8b6:c2cc:2928:3b61"
|
||||
_(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")
|
||||
|
|
30
test/unit/resources/interfaces_test.rb
Normal file
30
test/unit/resources/interfaces_test.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
require "helper"
|
||||
require "inspec/resource"
|
||||
require "inspec/resources/interfaces"
|
||||
|
||||
describe "Inspec::Resources::Interfaces" do
|
||||
|
||||
# ubuntu 16.04
|
||||
it "verify interface on ubuntu" do
|
||||
resource = MockLoader.new(:ubuntu1604).load_resource("interfaces")
|
||||
_(resource.exist?).must_equal true
|
||||
_(resource.names).must_equal %w{eth0 lo}
|
||||
_(resource.ipv4_address).must_equal "127.0.0.1"
|
||||
end
|
||||
|
||||
# freebsd / macos
|
||||
it "verify interface on freebsd" do
|
||||
resource = MockLoader.new(:freebsd12).load_resource("interfaces")
|
||||
_(resource.exist?).must_equal true
|
||||
_(resource.names).must_equal %w{em0 lo0}
|
||||
_(resource.ipv4_address).must_equal "1.2.3.4"
|
||||
end
|
||||
|
||||
# windows
|
||||
it "verify interfaces on windows" do
|
||||
resource = MockLoader.new(:windows).load_resource("interfaces")
|
||||
_(resource.exist?).must_equal true
|
||||
_(resource.names).must_equal ["vEthernet (Intel(R) PRO 1000 MT Network Connection - Virtual Switch)", "Ethernet0"]
|
||||
_(resource.ipv4_address).must_equal "127.0.0.1"
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue