mirror of
https://github.com/inspec/inspec
synced 2024-11-30 08:30:39 +00:00
7b0b98edac
Signed-off-by: Nikita Mathur <nikita.mathur@chef.io>
396 lines
16 KiB
Ruby
396 lines
16 KiB
Ruby
require "helper"
|
|
require "inspec/resource"
|
|
require "inspec/resources/host"
|
|
|
|
describe "Inspec::Resources::Host" do
|
|
|
|
it "check host ping on ubuntu with dig" do
|
|
resource = MockLoader.new(:ubuntu).load_resource("host", "example.com")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com"
|
|
_(resource.resource_id).must_equal "example.com"
|
|
end
|
|
|
|
it "check host ping on centos 7" do
|
|
resource = MockLoader.new(:centos7).load_resource("host", "example.com")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com"
|
|
_(resource.resource_id).must_equal "example.com"
|
|
end
|
|
|
|
it "check host ping on darwin" do
|
|
resource = MockLoader.new(:macos10_10).load_resource("host", "example.com")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com"
|
|
_(resource.resource_id).must_equal "example.com"
|
|
end
|
|
|
|
it "check host ping on windows" do
|
|
resource = MockLoader.new(:windows).load_resource("host", "microsoft.com")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal false
|
|
_(resource.ipaddress).must_equal ["134.170.188.221", "2404:6800:4009:827::200e"]
|
|
_(resource.to_s).must_equal "Host microsoft.com"
|
|
_(resource.resource_id).must_equal "microsoft.com"
|
|
end
|
|
|
|
it "check host ping on unsupported os" do
|
|
resource = MockLoader.new(:undefined).load_resource("host", "example.com")
|
|
_(resource.resolvable?).must_equal false
|
|
_(resource.reachable?).must_equal false
|
|
_(resource.ipaddress).must_be_nil
|
|
_(resource.to_s).must_equal "Host example.com"
|
|
_(resource.resource_id).must_equal "example.com"
|
|
end
|
|
|
|
it "check host tcp on ubuntu" do
|
|
resource = MockLoader.new(:ubuntu).load_resource("host", "example.com", port: 1234, protocol: "tcp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto tcp"
|
|
_(resource.resource_id).must_equal "example.com-1234-tcp"
|
|
end
|
|
|
|
it "check host udp on ubuntu" do
|
|
resource = MockLoader.new(:ubuntu).load_resource("host", "example.com", port: 1234, protocol: "udp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto udp"
|
|
_(resource.resource_id).must_equal "example.com-1234-udp"
|
|
end
|
|
|
|
it "check host tcp on centos 7" do
|
|
resource = MockLoader.new(:centos7).load_resource("host", "example.com", port: 1234, protocol: "tcp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto tcp"
|
|
_(resource.resource_id).must_equal "example.com-1234-tcp"
|
|
end
|
|
|
|
it "check host udp on centos 7" do
|
|
resource = MockLoader.new(:centos7).load_resource("host", "example.com", port: 1234, protocol: "udp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto udp"
|
|
_(resource.resource_id).must_equal "example.com-1234-udp"
|
|
end
|
|
|
|
it "check host tcp on darwin" do
|
|
resource = MockLoader.new(:macos10_10).load_resource("host", "example.com", port: 1234, protocol: "tcp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto tcp"
|
|
_(resource.resource_id).must_equal "example.com-1234-tcp"
|
|
end
|
|
|
|
it "check host udp on darwin" do
|
|
resource = MockLoader.new(:macos10_10).load_resource("host", "example.com", port: 1234, protocol: "udp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["12.34.56.78", "2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto udp"
|
|
_(resource.resource_id).must_equal "example.com-1234-udp"
|
|
end
|
|
|
|
it "check host tcp on windows" do
|
|
resource = MockLoader.new(:windows).load_resource("host", "microsoft.com", port: 1234, protocol: "tcp")
|
|
_(resource.resolvable?).must_equal true
|
|
_(resource.reachable?).must_equal true
|
|
_(resource.ipaddress).must_equal ["134.170.188.221", "2404:6800:4009:827::200e"]
|
|
_(resource.to_s).must_equal "Host microsoft.com port 1234 proto tcp"
|
|
_(resource.resource_id).must_equal "microsoft.com-1234-tcp"
|
|
end
|
|
|
|
it "check host tcp on unsupported os" do
|
|
resource = MockLoader.new(:undefined).load_resource("host", "example.com", port: 1234, protocol: "tcp")
|
|
_(resource.resolvable?).must_equal false
|
|
_(resource.reachable?).must_equal false
|
|
_(resource.ipaddress).must_be_nil
|
|
_(resource.to_s).must_equal "Host example.com port 1234 proto tcp"
|
|
_(resource.resource_id).must_equal "example.com-1234-tcp"
|
|
end
|
|
end
|
|
|
|
describe Inspec::Resources::UnixHostProvider do
|
|
let(:provider) { Inspec::Resources::UnixHostProvider.new(inspec) }
|
|
let(:inspec) { mock("inspec-backend") }
|
|
let(:nc_command) { mock("nc-command") }
|
|
let(:ncat_command) { mock("ncat-command") }
|
|
let(:timeout_command) { mock("timeout-command") }
|
|
let(:strings_command) { mock("strings-command") }
|
|
|
|
before do
|
|
inspec.stubs(:command).with("nc").returns(nc_command)
|
|
inspec.stubs(:command).with("ncat").returns(ncat_command)
|
|
inspec.stubs(:command).with("timeout").returns(timeout_command)
|
|
inspec.stubs(:command).with("gtimeout").returns(timeout_command)
|
|
inspec.stubs(:command).with("strings `which bash` | grep -qE '/dev/(tcp|udp)/'").returns(strings_command)
|
|
end
|
|
|
|
describe "#resolve_with_dig" do
|
|
let(:v4_command) { mock("v4_command") }
|
|
let(:v6_command) { mock("v6_command") }
|
|
|
|
before do
|
|
strings_command.stubs(:exit_status).returns(0)
|
|
nc_command.stubs(:exist?).returns(false)
|
|
ncat_command.stubs(:exist?).returns(false)
|
|
end
|
|
|
|
it "returns an array of IP addresses" do
|
|
ipv4_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
12.34.56.78
|
|
EOL
|
|
ipv6_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
2A03:2880:F112:83:FACE:B00C::25DE
|
|
EOL
|
|
|
|
v4_command.stubs(:stdout).returns(ipv4_command_output)
|
|
v6_command.stubs(:stdout).returns(ipv6_command_output)
|
|
inspec.stubs(:command).with("dig +short AAAA testdomain.com").returns(v6_command)
|
|
inspec.stubs(:command).with("dig +short A testdomain.com").returns(v4_command)
|
|
_(provider.resolve_with_dig("testdomain.com")).must_equal(["12.34.56.78", "2A03:2880:F112:83:FACE:B00C::25DE"])
|
|
end
|
|
|
|
it "returns only v4 addresses if no v6 addresses are available" do
|
|
ipv4_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
12.34.56.78
|
|
EOL
|
|
ipv6_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
EOL
|
|
|
|
v4_command.stubs(:stdout).returns(ipv4_command_output)
|
|
v6_command.stubs(:stdout).returns(ipv6_command_output)
|
|
inspec.stubs(:command).with("dig +short AAAA testdomain.com").returns(v6_command)
|
|
inspec.stubs(:command).with("dig +short A testdomain.com").returns(v4_command)
|
|
_(provider.resolve_with_dig("testdomain.com")).must_equal(["12.34.56.78"])
|
|
end
|
|
|
|
it "returns only v6 addresses if no v4 addresses are available" do
|
|
ipv4_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
EOL
|
|
ipv6_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
2A03:2880:F112:83:FACE:B00C::25DE
|
|
EOL
|
|
|
|
v4_command.stubs(:stdout).returns(ipv4_command_output)
|
|
v6_command.stubs(:stdout).returns(ipv6_command_output)
|
|
inspec.stubs(:command).with("dig +short AAAA testdomain.com").returns(v6_command)
|
|
inspec.stubs(:command).with("dig +short A testdomain.com").returns(v4_command)
|
|
_(provider.resolve_with_dig("testdomain.com")).must_equal(["2A03:2880:F112:83:FACE:B00C::25DE"])
|
|
end
|
|
|
|
it "returns nil if no addresses are available" do
|
|
ipv4_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
EOL
|
|
ipv6_command_output = <<~EOL
|
|
a.cname.goes.here
|
|
another.cname.cool
|
|
EOL
|
|
|
|
v4_command.stubs(:stdout).returns(ipv4_command_output)
|
|
v6_command.stubs(:stdout).returns(ipv6_command_output)
|
|
inspec.stubs(:command).with("dig +short AAAA testdomain.com").returns(v6_command)
|
|
inspec.stubs(:command).with("dig +short A testdomain.com").returns(v4_command)
|
|
_(provider.resolve_with_dig("testdomain.com")).must_be_nil
|
|
end
|
|
end
|
|
|
|
describe "#resolve_with_getent" do
|
|
before do
|
|
strings_command.stubs(:exit_status).returns(0)
|
|
nc_command.stubs(:exist?).returns(false)
|
|
ncat_command.stubs(:exist?).returns(false)
|
|
end
|
|
|
|
it "returns an array of IP addresses when successful" do
|
|
command_output = "123.123.123.123 STREAM testdomain.com\n2607:f8b0:4004:805::200e STREAM\n"
|
|
command = mock("getent_command")
|
|
command.stubs(:stdout).returns(command_output)
|
|
command.stubs(:exit_status).returns(0)
|
|
|
|
inspec.stubs(:command).with("getent ahosts testdomain.com").returns(command)
|
|
|
|
_(provider.resolve_with_getent("testdomain.com")).must_equal(["123.123.123.123", "2607:f8b0:4004:805::200e"])
|
|
end
|
|
|
|
it "returns nil if command is not successful" do
|
|
command = mock("getent_command")
|
|
command.stubs(:exit_status).returns(1)
|
|
|
|
inspec.stubs(:command).with("getent ahosts testdomain.com").returns(command)
|
|
|
|
_(provider.resolve_with_getent("testdomain.com")).must_be_nil
|
|
end
|
|
end
|
|
|
|
describe "#ping" do
|
|
let(:command_response) { mock("response") }
|
|
|
|
before do
|
|
strings_command.stubs(:exit_status).returns(0)
|
|
ncat_command.stubs(:exist?).returns(false)
|
|
|
|
command_response.stubs(:exit_status).returns("0")
|
|
command_response.stubs(:stdout).returns("foo")
|
|
command_response.stubs(:stderr).returns("bar")
|
|
end
|
|
|
|
it "calls netcat if available" do
|
|
nc_command.stubs(:exist?).returns(true)
|
|
inspec.expects(:command).with("echo | nc -v -w 1 example.com 1234").returns(command_response)
|
|
|
|
provider.ping("example.com", "1234", "tcp")
|
|
end
|
|
|
|
it "uses bash if netcat not available" do
|
|
nc_command.stubs(:exist?).returns(false)
|
|
inspec.expects(:command).with('timeout 1 bash -c "< /dev/tcp/example.com/1234"').returns(command_response)
|
|
|
|
provider.ping("example.com", "1234", "tcp")
|
|
end
|
|
|
|
it "uses bash if netcat not available on Darwin" do
|
|
nc_command.stubs(:exist?).returns(false)
|
|
inspec.expects(:command).with('gtimeout 1 bash -c "< /dev/tcp/example.com/1234"').returns(command_response)
|
|
|
|
darwin_provider = Inspec::Resources::DarwinHostProvider.new(inspec)
|
|
darwin_provider.ping("example.com", "1234", "tcp")
|
|
end
|
|
end
|
|
|
|
describe "#missing_requirements" do
|
|
describe "bash with net redirects and no netcat" do
|
|
before do
|
|
strings_command.stubs(:exit_status).returns(0)
|
|
nc_command.stubs(:exist?).returns(false)
|
|
ncat_command.stubs(:exist?).returns(false)
|
|
end
|
|
|
|
it "returns an empty array if timeout is available" do
|
|
timeout_command.stubs(:exist?).returns(true)
|
|
_(provider.missing_requirements("tcp")).must_equal([])
|
|
end
|
|
|
|
it "returns a missing requirement when timeout is missing" do
|
|
timeout_command.stubs(:exist?).returns(false)
|
|
_(provider.missing_requirements("tcp")).must_equal(["timeout (part of coreutils) or netcat must be installed"])
|
|
end
|
|
end
|
|
|
|
describe "bash without net redirects" do
|
|
before do
|
|
strings_command.stubs(:exit_status).returns(1)
|
|
end
|
|
|
|
it "returns an empty array if nc is installed but ncat is not installed" do
|
|
nc_command.stubs(:exist?).returns(true)
|
|
ncat_command.stubs(:exist?).returns(false)
|
|
_(provider.missing_requirements("tcp")).must_equal([])
|
|
end
|
|
|
|
it "returns an empty array if nc is not installed but ncat is installed" do
|
|
nc_command.stubs(:exist?).returns(false)
|
|
ncat_command.stubs(:exist?).returns(true)
|
|
_(provider.missing_requirements("tcp")).must_equal([])
|
|
end
|
|
|
|
it "returns an empty array if both nc and ncat are installed" do
|
|
nc_command.stubs(:exist?).returns(true)
|
|
ncat_command.stubs(:exist?).returns(true)
|
|
_(provider.missing_requirements("tcp")).must_equal([])
|
|
end
|
|
|
|
it "returns a missing requirement when neither nc nor ncat are installed" do
|
|
nc_command.stubs(:exist?).returns(false)
|
|
ncat_command.stubs(:exist?).returns(false)
|
|
_(provider.missing_requirements("tcp")).must_equal(["netcat must be installed"])
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#netcat_check_command" do
|
|
before do
|
|
strings_command.stubs(:exit_status).returns(1)
|
|
end
|
|
|
|
it "returns an nc command when nc exists tcp" do
|
|
nc_command.expects(:exist?).returns(true)
|
|
ncat_command.expects(:exist?).returns(false)
|
|
_(provider.netcat_check_command("foo", 1234, "tcp")).must_equal "echo | nc -v -w 1 foo 1234"
|
|
end
|
|
|
|
it "returns an nc command when nc exists udp" do
|
|
nc_command.expects(:exist?).returns(true)
|
|
ncat_command.expects(:exist?).returns(false)
|
|
_(provider.netcat_check_command("foo", 1234, "udp")).must_equal "echo | nc -v -w 1 -u foo 1234"
|
|
end
|
|
|
|
it "returns an ncat command when nc does not exist but ncat exists tcp" do
|
|
nc_command.expects(:exist?).returns(false)
|
|
ncat_command.expects(:exist?).returns(true)
|
|
_(provider.netcat_check_command("foo", 1234, "tcp")).must_equal "echo | ncat -v -w 1 foo 1234"
|
|
end
|
|
|
|
it "returns an ncat command when nc does not exist but ncat exists udp" do
|
|
nc_command.expects(:exist?).returns(false)
|
|
ncat_command.expects(:exist?).returns(true)
|
|
_(provider.netcat_check_command("foo", 1234, "udp")).must_equal "echo | ncat -v -w 1 -u foo 1234"
|
|
end
|
|
|
|
it "returns nil if neither nc or ncat exist" do
|
|
nc_command.expects(:exist?).returns(false)
|
|
ncat_command.expects(:exist?).returns(false)
|
|
_(provider.netcat_check_command("foo", 1234, "tcp")).must_be_nil
|
|
end
|
|
|
|
it "checks ipv4_address and ipv6_address properties on ubuntu" do
|
|
resource = MockLoader.new(:ubuntu).load_resource("host", "example.com")
|
|
_(resource.ipv4_address).must_equal ["12.34.56.78"]
|
|
_(resource.ipv4_address).must_include "12.34.56.78"
|
|
_(resource.ipv6_address).must_equal ["2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.ipv6_address).must_include "2606:2800:220:1:248:1893:25c8:1946"
|
|
end
|
|
|
|
it "checks ipv4_address and ipv6_address properties on windows" do
|
|
resource = MockLoader.new(:windows).load_resource("host", "microsoft.com")
|
|
_(resource.ipv4_address).must_equal ["134.170.188.221"]
|
|
_(resource.ipv4_address).must_include "134.170.188.221"
|
|
_(resource.ipv6_address).must_equal ["2404:6800:4009:827::200e"]
|
|
_(resource.ipv6_address).must_include "2404:6800:4009:827::200e"
|
|
end
|
|
|
|
it "checks ipv4_address and ipv6_address properties on darwin" do
|
|
resource = MockLoader.new(:macos10_10).load_resource("host", "example.com")
|
|
_(resource.ipv4_address).must_equal ["12.34.56.78"]
|
|
_(resource.ipv4_address).must_include "12.34.56.78"
|
|
_(resource.ipv6_address).must_equal ["2606:2800:220:1:248:1893:25c8:1946"]
|
|
_(resource.ipv6_address).must_include "2606:2800:220:1:248:1893:25c8:1946"
|
|
end
|
|
end
|
|
end
|