inspec 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -8
  3. data/README.md +8 -39
  4. data/Rakefile +74 -9
  5. data/bin/inspec +66 -10
  6. data/docs/ctl_inspec.rst +7 -1
  7. data/docs/inspec_and_friends.rst +1 -1
  8. data/docs/resources.rst +51 -45
  9. data/examples/README.md +7 -0
  10. data/examples/kitchen-ansible/.kitchen.yml +25 -0
  11. data/examples/kitchen-ansible/Gemfile +20 -0
  12. data/examples/kitchen-ansible/README.md +53 -0
  13. data/examples/kitchen-ansible/files/nginx.repo +6 -0
  14. data/examples/kitchen-ansible/tasks/main.yml +16 -0
  15. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -0
  16. data/examples/{test-kitchen → kitchen-ansible}/test/integration/default/web_spec.rb +0 -0
  17. data/examples/{test-kitchen → kitchen-chef}/.kitchen.yml +1 -1
  18. data/examples/{test-kitchen → kitchen-chef}/Berksfile +0 -0
  19. data/examples/{test-kitchen → kitchen-chef}/Gemfile +1 -2
  20. data/examples/{test-kitchen → kitchen-chef}/README.md +1 -1
  21. data/examples/{test-kitchen → kitchen-chef}/metadata.rb +0 -0
  22. data/examples/{test-kitchen → kitchen-chef}/recipes/default.rb +0 -0
  23. data/examples/{test-kitchen → kitchen-chef}/recipes/nginx.rb +0 -0
  24. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -0
  25. data/examples/kitchen-puppet/.kitchen.yml +22 -0
  26. data/examples/kitchen-puppet/Gemfile +21 -0
  27. data/examples/kitchen-puppet/Puppetfile +25 -0
  28. data/examples/kitchen-puppet/README.md +53 -0
  29. data/examples/kitchen-puppet/manifests/site.pp +33 -0
  30. data/examples/kitchen-puppet/metadata.json +11 -0
  31. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -0
  32. data/inspec.gemspec +2 -0
  33. data/lib/inspec/plugins/resource.rb +21 -0
  34. data/lib/inspec/shell.rb +73 -11
  35. data/lib/inspec/version.rb +1 -1
  36. data/lib/matchers/matchers.rb +43 -0
  37. data/lib/resources/apache_conf.rb +12 -9
  38. data/lib/resources/apt.rb +7 -0
  39. data/lib/resources/audit_policy.rb +6 -6
  40. data/lib/resources/auditd_conf.rb +6 -7
  41. data/lib/resources/auditd_rules.rb +9 -8
  42. data/lib/resources/bond.rb +6 -6
  43. data/lib/resources/bridge.rb +7 -0
  44. data/lib/resources/command.rb +10 -8
  45. data/lib/resources/csv.rb +6 -5
  46. data/lib/resources/directory.rb +6 -0
  47. data/lib/resources/etc_group.rb +9 -1
  48. data/lib/resources/file.rb +72 -61
  49. data/lib/resources/gem.rb +6 -4
  50. data/lib/resources/group.rb +7 -0
  51. data/lib/resources/host.rb +6 -0
  52. data/lib/resources/inetd_conf.rb +8 -8
  53. data/lib/resources/ini.rb +6 -6
  54. data/lib/resources/interface.rb +8 -8
  55. data/lib/resources/iptables.rb +6 -0
  56. data/lib/resources/json.rb +6 -5
  57. data/lib/resources/kernel_module.rb +6 -5
  58. data/lib/resources/kernel_parameter.rb +6 -4
  59. data/lib/resources/limits_conf.rb +6 -6
  60. data/lib/resources/login_def.rb +6 -0
  61. data/lib/resources/mysql_conf.rb +6 -0
  62. data/lib/resources/mysql_session.rb +7 -0
  63. data/lib/resources/npm.rb +6 -4
  64. data/lib/resources/ntp_conf.rb +7 -7
  65. data/lib/resources/oneget.rb +6 -0
  66. data/lib/resources/os.rb +8 -0
  67. data/lib/resources/os_env.rb +6 -0
  68. data/lib/resources/package.rb +8 -1
  69. data/lib/resources/parse_config.rb +14 -0
  70. data/lib/resources/passwd.rb +7 -0
  71. data/lib/resources/pip.rb +6 -0
  72. data/lib/resources/port.rb +22 -11
  73. data/lib/resources/postgres_conf.rb +6 -0
  74. data/lib/resources/postgres_session.rb +8 -0
  75. data/lib/resources/processes.rb +17 -1
  76. data/lib/resources/registry_key.rb +7 -0
  77. data/lib/resources/script.rb +11 -0
  78. data/lib/resources/security_policy.rb +6 -1
  79. data/lib/resources/service.rb +10 -0
  80. data/lib/resources/ssh_conf.rb +6 -0
  81. data/lib/resources/user.rb +9 -2
  82. data/lib/resources/windows_feature.rb +6 -0
  83. data/lib/resources/yaml.rb +6 -0
  84. data/lib/resources/yum.rb +7 -0
  85. data/lib/utils/find_files.rb +15 -7
  86. data/test/helper.rb +9 -0
  87. data/test/integration/.kitchen.yml +3 -0
  88. data/test/integration/test/integration/default/compare_matcher_spec.rb +19 -0
  89. data/test/integration/test/integration/default/etc_group.rb +13 -0
  90. data/test/integration/test/integration/default/os_spec.rb +13 -0
  91. data/test/integration/test/integration/default/port_spec.rb +1 -1
  92. data/test/unit/mock/cmd/find-apache2-conf-enabled +1 -0
  93. data/test/unit/mock/cmd/find-apache2-ports-conf +1 -0
  94. data/test/unit/mock/cmd/ps-aux +2 -0
  95. data/test/unit/mock/files/apache2.conf +14 -0
  96. data/test/unit/mock/files/ports.conf +6 -0
  97. data/test/unit/mock/files/serve-cgi-bin.conf +20 -0
  98. data/test/unit/resources/apache_conf_test.rb +31 -0
  99. data/test/unit/resources/file_test.rb +181 -0
  100. data/test/unit/resources/package_test.rb +9 -0
  101. data/test/unit/resources/port_test.rb +33 -13
  102. data/test/unit/resources/processes_test.rb +6 -0
  103. data/test/unit/resources/service_test.rb +10 -0
  104. data/test/unit/resources/user_test.rb +12 -0
  105. data/test/unit/utils/find_files_test.rb +23 -0
  106. metadata +61 -16
  107. data/bin/inspec.orig +0 -115
  108. data/lib/resources/.service.rb.swp +0 -0
  109. data/test/unit/mock/profiles/rules/metadata.rb +0 -2
  110. data/test/unit/mock/profiles/rules/test/test.rb +0 -6
@@ -2,12 +2,14 @@
2
2
  # author: Christoph Hartmann
3
3
  # author: Dominik Richter
4
4
 
5
- # Usage:
6
- # describe gem('rubocop') do
7
- # it { should be_installed }
8
- # end
9
5
  class GemPackage < Inspec.resource(1)
10
6
  name 'gem'
7
+ desc 'Use the gem InSpec audit resource to test if a global gem package is installed.'
8
+ example "
9
+ describe gem('rubocop') do
10
+ it { should be_installed }
11
+ end
12
+ "
11
13
 
12
14
  def initialize(package_name)
13
15
  @package_name = package_name
@@ -15,6 +15,13 @@
15
15
 
16
16
  class Group < Inspec.resource(1)
17
17
  name 'group'
18
+ desc 'Use the group InSpec audit resource to test groups on the system.'
19
+ example "
20
+ describe group('root') do
21
+ it { should exist }
22
+ its('gid') { should eq 0 }
23
+ end
24
+ "
18
25
 
19
26
  def initialize(groupname, domain = nil)
20
27
  @group = groupname.downcase
@@ -26,6 +26,12 @@
26
26
 
27
27
  class Host < Inspec.resource(1)
28
28
  name 'host'
29
+ desc 'Use the host InSpec audit resource to test the name used to refer to a specific host and its availability, including the Internet protocols and ports over which that host name should be available.'
30
+ example "
31
+ describe host('example.com') do
32
+ it { should be_reachable }
33
+ end
34
+ "
29
35
 
30
36
  def initialize(hostname, params = {})
31
37
  @hostname = hostname
@@ -6,16 +6,16 @@
6
6
 
7
7
  require 'utils/simpleconfig'
8
8
 
9
- # Usage:
10
- #
11
- # describe inetd_conf do
12
- # its('shell') { should eq nil }
13
- # its('login') { should eq nil }
14
- # its('exec') { should eq nil }
15
- # end
16
-
17
9
  class InetdConf < Inspec.resource(1)
18
10
  name 'inetd_conf'
11
+ desc 'Use the inetd_conf InSpec audit resource to test if a service is enabled in the inetd.conf file on Linux and UNIX platforms. inetd---the Internet service daemon---listens on dedicated ports, and then loads the appropriate program based on a request. The inetd.conf file is typically located at /etc/inetd.conf and contains a list of Internet services associated to the ports on which that service will listen. Only enabled services may handle a request; only services that are required by the system should be enabled.'
12
+ example "
13
+ describe inetd_conf do
14
+ its('shell') { should eq nil }
15
+ its('login') { should eq nil }
16
+ its('exec') { should eq nil }
17
+ end
18
+ "
19
19
 
20
20
  def initialize(path = nil)
21
21
  @conf_path = path || '/etc/inetd.conf'
@@ -4,14 +4,14 @@
4
4
 
5
5
  require 'utils/simpleconfig'
6
6
 
7
- # Parses a ini file
8
- # Usage:
9
- # descibe ini do
10
- # its("auth_protocol") { should eq "https" }
11
- # end
12
7
  class IniConfig < JsonConfig
13
8
  name 'ini'
14
-
9
+ desc 'Use the ini InSpec audit resource to test data in a INI file.'
10
+ example "
11
+ descibe ini do
12
+ its('auth_protocol') { should eq 'https' }
13
+ end
14
+ "
15
15
  # override file load and parse hash with simple config
16
16
  def parse(content)
17
17
  SimpleConfig.new(content).params
@@ -2,18 +2,18 @@
2
2
  # author: Christoph Hartmann
3
3
  # author: Dominik Richter
4
4
 
5
- # Usage:
6
- # describe interface('eth0') do
7
- # it { should exist }
8
- # it { should be_up }
9
- # its(:speed) { should eq 1000 }
10
- # end
11
-
12
5
  require 'utils/convert'
13
6
 
14
7
  class NetworkInterface < Inspec.resource(1)
15
8
  name 'interface'
16
-
9
+ desc 'Use the interface InSpec audit resource to test basic network adapter properties, such as name, status, state, address, and link speed (in MB/sec).'
10
+ example "
11
+ describe interface('eth0') do
12
+ it { should exist }
13
+ it { should be_up }
14
+ its(:speed) { should eq 1000 }
15
+ end
16
+ "
17
17
  def initialize(iface)
18
18
  @iface = iface
19
19
 
@@ -23,6 +23,12 @@
23
23
  # @see https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
24
24
  class IpTables < Inspec.resource(1)
25
25
  name 'iptables'
26
+ desc 'Use the iptables InSpec audit resource to test rules that are defined in iptables, which maintains tables of IP packet filtering rules. There may be more than one table. Each table contains one (or more) chains (both built-in and custom). A chain is a list of rules that match packets. When the rule matches, the rule defines what target to assign to the packet.'
27
+ example "
28
+ describe iptables do
29
+ it { should have_rule('-P INPUT ACCEPT') }
30
+ end
31
+ "
26
32
 
27
33
  def initialize(params = {})
28
34
  @table = params[:table] || nil
@@ -2,13 +2,14 @@
2
2
  # author: Christoph Hartmann
3
3
  # author: Dominik Richter
4
4
 
5
- # Parses a json document
6
- # Usage:
7
- # describe json('policyfile.lock.json') do
8
- # its('cookbook_locks.omnibus.version') { should eq('2.2.0') }
9
- # end
10
5
  class JsonConfig < Inspec.resource(1)
11
6
  name 'json'
7
+ desc 'Use the json InSpec audit resource to test data in a JSON file.'
8
+ example "
9
+ describe json('policyfile.lock.json') do
10
+ its('cookbook_locks.omnibus.version') { should eq('2.2.0') }
11
+ end
12
+ "
12
13
 
13
14
  # make params readable
14
15
  attr_reader :params
@@ -3,13 +3,14 @@
3
3
  # author: Dominik Richter
4
4
  # license: All rights reserved
5
5
 
6
- # Verifies if a kernel module is loaded
7
- # Usage:
8
- # describe kernel_module('bridge') do
9
- # it { should be_loaded }
10
- # end
11
6
  class KernelModule < Inspec.resource(1)
12
7
  name 'kernel_module'
8
+ desc 'Use the kernel_module InSpec audit resource to test kernel modules on Linux platforms. These parameters are located under /lib/modules. Any submodule may be tested using this resource.'
9
+ example "
10
+ describe kernel_module('bridge') do
11
+ it { should be_loaded }
12
+ end
13
+ "
13
14
 
14
15
  def initialize(modulename = nil)
15
16
  @module = modulename
@@ -2,12 +2,14 @@
2
2
  # author: Christoph Hartmann
3
3
  # license: All rights reserved
4
4
 
5
- # Verifies if a kernel parameter is set
6
- # describe kernel_parameter('net.ipv4.conf.all.forwarding') do
7
- # its(:value) { should eq 0 }
8
- # end
9
5
  class KernelParameter < Inspec.resource(1)
10
6
  name 'kernel_parameter'
7
+ desc 'Use the kernel_parameter InSpec audit resource to test kernel parameters on Linux platforms.'
8
+ example "
9
+ describe kernel_parameter('net.ipv4.conf.all.forwarding') do
10
+ its(:value) { should eq 0 }
11
+ end
12
+ "
11
13
 
12
14
  def initialize(parameter = nil)
13
15
  @parameter = parameter
@@ -6,14 +6,14 @@
6
6
 
7
7
  require 'utils/simpleconfig'
8
8
 
9
- # Usage:
10
- #
11
- # describe limits_conf do
12
- # its('*') { should include ['hard','core','0'] }
13
- # end
14
-
15
9
  class LimitsConf < Inspec.resource(1)
16
10
  name 'limits_conf'
11
+ desc 'Use the limits_conf InSpec audit resource to test configuration settings in the /etc/security/limits.conf file. The limits.conf defines limits for processes (by user and/or group names) and helps ensure that the system on which those processes are running remains stable. Each process may be assigned a hard or soft limit.'
12
+ example "
13
+ describe limits_conf do
14
+ its('*') { should include ['hard','core','0'] }
15
+ end
16
+ "
17
17
 
18
18
  def initialize(path = nil)
19
19
  @conf_path = path || '/etc/security/limits.conf'
@@ -20,6 +20,12 @@ require 'utils/simpleconfig'
20
20
 
21
21
  class LoginDef < Inspec.resource(1)
22
22
  name 'login_defs'
23
+ desc 'Use the login_defs InSpec audit resource to test configuration settings in the /etc/login.defs file. The logins.defs file defines site-specific configuration for the shadow password suite on Linux and UNIX platforms, such as password expiration ranges, minimum/maximum values for automatic selection of user and group identifiers, or the method with which passwords are encrypted.'
24
+ example "
25
+ describe login_defs do
26
+ its('ENCRYPT_METHOD') { should eq 'SHA512' }
27
+ end
28
+ "
23
29
 
24
30
  def initialize(path = nil)
25
31
  @conf_path = path || '/etc/login.defs'
@@ -28,6 +28,12 @@ end
28
28
 
29
29
  class MysqlConf < Inspec.resource(1)
30
30
  name 'mysql_conf'
31
+ desc 'Use the mysql_conf InSpec audit resource to test the contents of the configuration file for MySQL, typically located at /etc/mysql/my.cnf or /etc/my.cnf.'
32
+ example "
33
+ describe mysql_conf('path') do
34
+ its('setting') { should eq 'value' }
35
+ end
36
+ "
31
37
 
32
38
  include FindFiles
33
39
 
@@ -6,6 +6,13 @@
6
6
 
7
7
  class MysqlSession < Inspec.resource(1)
8
8
  name 'mysql_session'
9
+ desc 'Use the mysql_session InSpec audit resource to test SQL commands run against a MySQL database.'
10
+ example "
11
+ sql = mysql_session('my_user','password')
12
+ describe sql.query('show databases like \'test\';') do
13
+ its(:stdout) { should_not match(/test/) }
14
+ end
15
+ "
9
16
 
10
17
  def initialize(user = nil, pass = nil)
11
18
  @user = user
@@ -2,12 +2,14 @@
2
2
  # author: Christoph Hartmann
3
3
  # author: Dominik Richter
4
4
 
5
- # Usage:
6
- # describe npm('bower') do
7
- # it { should be_installed }
8
- # end
9
5
  class NpmPackage < Inspec.resource(1)
10
6
  name 'npm'
7
+ desc 'Use the npm InSpec audit resource to test if a global npm package is installed. npm is the the package manager for Nodejs packages, such as bower and StatsD.'
8
+ example "
9
+ describe npm('bower') do
10
+ it { should be_installed }
11
+ end
12
+ "
11
13
 
12
14
  def initialize(package_name)
13
15
  @package_name = package_name
@@ -6,15 +6,15 @@
6
6
 
7
7
  require 'utils/simpleconfig'
8
8
 
9
- # Usage:
10
- #
11
- # describe ntp_conf do
12
- # its('server') { should_not eq nil }
13
- # its('restrict') { should include '-4 default kod notrap nomodify nopeer noquery'}
14
- # end
15
-
16
9
  class NtpConf < Inspec.resource(1)
17
10
  name 'ntp_conf'
11
+ desc 'Use the ntp_conf InSpec audit resource to test the synchronization settings defined in the ntp.conf file. This file is typically located at /etc/ntp.conf.'
12
+ example "
13
+ describe ntp_conf do
14
+ its('server') { should_not eq nil }
15
+ its('restrict') { should include '-4 default kod notrap nomodify nopeer noquery'}
16
+ end
17
+ "
18
18
 
19
19
  def initialize(path = nil)
20
20
  @conf_path = path || '/etc/ntp.conf'
@@ -11,6 +11,12 @@
11
11
  # end
12
12
  class OneGetPackage < Inspec.resource(1)
13
13
  name 'oneget'
14
+ desc 'Use the oneget InSpec audit resource to test if the named package and/or package version is installed on the system. This resource uses OneGet, which is part of the Windows Management Framework 5.0 and Windows 10. This resource uses the Get-Package cmdlet to return all of the package names in the OneGet repository.'
15
+ example "
16
+ describe oneget('zoomit') do
17
+ it { should be_installed }
18
+ end
19
+ "
14
20
 
15
21
  def initialize(package_name)
16
22
  @package_name = package_name
@@ -4,6 +4,12 @@
4
4
 
5
5
  class OS < Inspec.resource(1)
6
6
  name 'os'
7
+ desc 'Use the os InSpec audit resource to test the platform on which the system is running.'
8
+ example "
9
+ describe os[:family] do
10
+ it { should eq 'redhat' }
11
+ end
12
+ "
7
13
 
8
14
  # reuse helper methods from backend
9
15
  %w{redhat? debian? suse? bsd? solaris? linux? unix? windows?}.each do |os_family|
@@ -13,6 +19,8 @@ class OS < Inspec.resource(1)
13
19
  end
14
20
 
15
21
  def [](name)
22
+ # convert string to symbol
23
+ name = name.to_sym if name.is_a? String
16
24
  inspec.backend.os[name]
17
25
  end
18
26
 
@@ -15,6 +15,12 @@ require 'utils/simpleconfig'
15
15
 
16
16
  class OsEnv < Inspec.resource(1)
17
17
  name 'os_env'
18
+ desc 'Use the os_env InSpec audit resource to test the environment variables for the platform on which the system is running.'
19
+ example "
20
+ describe os_env('VARIABLE') do
21
+ its('matcher') { should eq 1 }
22
+ end
23
+ "
18
24
 
19
25
  attr_reader :content
20
26
  def initialize(env = nil)
@@ -10,6 +10,13 @@
10
10
  # end
11
11
  class Package < Inspec.resource(1)
12
12
  name 'package'
13
+ desc 'Use the package InSpec audit resource to test if the named package and/or package version is installed on the system.'
14
+ example "
15
+ describe package('nginx') do
16
+ it { should be_installed }
17
+ its('version') { should eq 1.9.5 }
18
+ end
19
+ "
13
20
 
14
21
  def initialize(package_name = nil)
15
22
  @package_name = package_name
@@ -21,7 +28,7 @@ class Package < Inspec.resource(1)
21
28
  case inspec.os[:family]
22
29
  when 'ubuntu', 'debian'
23
30
  @pkgman = Deb.new(inspec)
24
- when 'redhat', 'fedora', 'centos', 'opensuse'
31
+ when 'redhat', 'fedora', 'centos', 'opensuse', 'wrlinux'
25
32
  @pkgman = Rpm.new(inspec)
26
33
  when 'arch'
27
34
  @pkgman = Pacman.new(inspec)
@@ -15,6 +15,14 @@
15
15
 
16
16
  class PConfig < Inspec.resource(1)
17
17
  name 'parse_config'
18
+ desc 'Use the parse_config InSpec audit resource to test arbitrary configuration files.'
19
+ example "
20
+ output = command('some-command').stdout
21
+
22
+ describe parse_config(output, { data_config_option: value } ) do
23
+ its('setting') { should eq 1 }
24
+ end
25
+ "
18
26
 
19
27
  def initialize(content = nil, useropts = nil)
20
28
  @opts = {}
@@ -63,6 +71,12 @@ end
63
71
 
64
72
  class PConfigFile < PConfig
65
73
  name 'parse_config_file'
74
+ desc 'Use the parse_config_file InSpec audit resource to test arbitrary configuration files. It works identiacal to parse_config. Instead of using a command output, this resource works with files.'
75
+ example "
76
+ describe parse_config_file('/path/to/file') do
77
+ its('setting') { should eq 1 }
78
+ end
79
+ "
66
80
 
67
81
  def initialize(path, opts = nil)
68
82
  super(nil, opts)
@@ -29,6 +29,13 @@ require 'utils/parser'
29
29
 
30
30
  class Passwd < Inspec.resource(1)
31
31
  name 'passwd'
32
+ desc 'Use the passwd InSpec audit resource to test the contents of /etc/passwd, which contains the following information for users that may log into the system and/or as users that own running processes.'
33
+ example "
34
+ describe passwd.uid(0) do
35
+ its('username') { should eq 'root' }
36
+ its('count') { should eq 1 }
37
+ end
38
+ "
32
39
 
33
40
  include ContentParser
34
41
 
@@ -9,6 +9,12 @@
9
9
  #
10
10
  class PipPackage < Inspec.resource(1)
11
11
  name 'pip'
12
+ desc 'Use the pip InSpec audit resource to test packages that are installed using the pip installer.'
13
+ example "
14
+ describe pip('Jinja2') do
15
+ it { should be_installed }
16
+ end
17
+ "
12
18
 
13
19
  def initialize(package_name)
14
20
  @package_name = package_name
@@ -17,14 +17,22 @@
17
17
  # TODO: improve handling of same port on multiple interfaces
18
18
  class Port < Inspec.resource(1)
19
19
  name 'port'
20
+ desc "Use the port InSpec audit resource to test basic port properties, such as port, process, if it's listening."
21
+ example "
22
+ describe port(80) do
23
+ it { should be_listening }
24
+ its('protocols') {should eq ['tcp']}
25
+ end
26
+ "
20
27
 
21
- def initialize(port)
28
+ def initialize(ip = nil, port) # rubocop:disable OptionalArguments
29
+ @ip = ip
22
30
  @port = port
23
31
  @port_manager = nil
24
32
  @cache = nil
25
33
 
26
34
  case inspec.os[:family]
27
- when 'ubuntu', 'debian', 'redhat', 'fedora', 'centos', 'arch'
35
+ when 'ubuntu', 'debian', 'redhat', 'fedora', 'centos', 'arch', 'wrlinux'
28
36
  @port_manager = LinuxPorts.new(inspec)
29
37
  when 'darwin'
30
38
  @port_manager = DarwinPorts.new(inspec)
@@ -41,17 +49,17 @@ class Port < Inspec.resource(1)
41
49
  info.size > 0
42
50
  end
43
51
 
44
- def protocol
52
+ def protocols
45
53
  res = info.map { |x| x[:protocol] }.uniq.compact
46
54
  res.size > 0 ? res : nil
47
55
  end
48
56
 
49
- def process
57
+ def processes
50
58
  res = info.map { |x| x[:process] }.uniq.compact
51
59
  res.size > 0 ? res : nil
52
60
  end
53
61
 
54
- def pid
62
+ def pids
55
63
  res = info.map { |x| x[:pid] }.uniq.compact
56
64
  res.size > 0 ? res : nil
57
65
  end
@@ -68,18 +76,21 @@ class Port < Inspec.resource(1)
68
76
  return @cache = [] if @port_manager.nil?
69
77
  # query ports
70
78
  ports = @port_manager.info || []
71
- @cache = ports.select { |p| p[:port] == @port }
79
+ @cache = ports.select { |p| p[:port] == @port && (!@ip || p[:address] == @ip) }
72
80
  end
73
81
  end
74
82
 
75
83
  # implements an info method and returns all ip adresses and protocols for
76
84
  # each port
77
85
  # [{
78
- # port: 80,
79
- # address: [{
80
- # ip: '0.0.0.0'
81
- # protocol: 'tcp'
82
- # }],
86
+ # port: 22,
87
+ # address: '0.0.0.0'
88
+ # protocol: 'tcp'
89
+ # },
90
+ # {
91
+ # port: 22,
92
+ # address: '::'
93
+ # protocol: 'tcp6'
83
94
  # }]
84
95
  class PortsInfo
85
96
  attr_reader :inspec