inspec 1.27.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/docs/resources/host.md.erb +4 -4
- data/docs/resources/iis_app.md.erb +126 -0
- data/docs/resources/virtualization.md.erb +71 -0
- data/examples/inheritance/inspec.lock +11 -0
- data/examples/meta-profile/inspec.lock +18 -0
- data/examples/meta-profile/vendor/0e6d170415e120af5f1dda113f96f7e0d156e49f82706ac41d13da00599f9b25.tar.gz +0 -0
- data/examples/meta-profile/vendor/403580959915ea24bc176b9ebdc555aeda5e2c957604b48d5f32b43554423582.tar.gz +0 -0
- data/examples/meta-profile/vendor/d08d3cc35debff04e708147cdd07739876c5d1c8357afb5e58adfaad92dd650f.tar.gz +0 -0
- data/lib/bundles/inspec-compliance/api.rb +13 -2
- data/lib/bundles/inspec-compliance/configuration.rb +4 -0
- data/lib/fetchers/url.rb +2 -0
- data/lib/inspec/archive/tar.rb +1 -1
- data/lib/inspec/base_cli.rb +19 -2
- data/lib/inspec/file_provider.rb +29 -2
- data/lib/inspec/plugins/resource.rb +1 -1
- data/lib/inspec/profile.rb +2 -2
- data/lib/inspec/resource.rb +2 -0
- data/lib/inspec/rspec_json_formatter.rb +9 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/auditd_rules.rb +1 -0
- data/lib/resources/host.rb +97 -27
- data/lib/resources/iis_app.rb +103 -0
- data/lib/resources/service.rb +2 -0
- data/lib/resources/virtualization.rb +252 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0d407da61108e3110902410c9250bb1aa65727d
|
4
|
+
data.tar.gz: '08e3dfe5818627298ae9fada47ebdb20295be3d3'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00b4a96e07c8b54024b756c1abfe4fe0334d16817177ae538902ddb76cc9e21fbd604a473c41fc3538b2a26491872f8ae30c02af82cf913c430238fe526a07d9
|
7
|
+
data.tar.gz: a020a8a48d76d26da019ea92ad298b9e1c70d5a22dc8d3f691457201649d5108c85fb49ff90f37d1112f6b5710db2c5296a20d09ab9512fc5281a68535ba218a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v1.28.0](https://github.com/chef/inspec/tree/v1.28.0) (2017-06-15)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.27.0...v1.28.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Add support for CoreOS to the service resource [\#1928](https://github.com/chef/inspec/pull/1928) ([rarenerd](https://github.com/rarenerd))
|
9
|
+
- Host resource ping method should return stdout [\#1927](https://github.com/chef/inspec/pull/1927) ([justincmoy](https://github.com/justincmoy))
|
10
|
+
- Add TCP reachability support on Linux for host resource [\#1915](https://github.com/chef/inspec/pull/1915) ([adamleff](https://github.com/adamleff))
|
11
|
+
- Adds support for iis\_app InSpec testing [\#1905](https://github.com/chef/inspec/pull/1905) ([EasyAsABC123](https://github.com/EasyAsABC123))
|
12
|
+
- Add support for virtualization resource [\#1803](https://github.com/chef/inspec/pull/1803) ([tkak](https://github.com/tkak))
|
13
|
+
|
14
|
+
**Fixed bugs:**
|
15
|
+
|
16
|
+
- Error when listing compliance profiles against Automate pre 0.8 [\#1921](https://github.com/chef/inspec/issues/1921)
|
17
|
+
- Unexpected `nil` authentication with `inspec exec -t` and WinRM [\#1901](https://github.com/chef/inspec/issues/1901)
|
18
|
+
- inspec exec with --json-config option having multiple node information [\#1897](https://github.com/chef/inspec/issues/1897)
|
19
|
+
- describe package failing in newer version [\#1797](https://github.com/chef/inspec/issues/1797)
|
20
|
+
- Fix detection of Automate pre-0.8.x in Compliance::API [\#1922](https://github.com/chef/inspec/pull/1922) ([adamleff](https://github.com/adamleff))
|
21
|
+
- bugfix: reading tgz files with binread [\#1920](https://github.com/chef/inspec/pull/1920) ([arlimus](https://github.com/arlimus))
|
22
|
+
- fix intermitten functional vendor test failures [\#1919](https://github.com/chef/inspec/pull/1919) ([arlimus](https://github.com/arlimus))
|
23
|
+
- enforce option values where needed [\#1918](https://github.com/chef/inspec/pull/1918) ([arlimus](https://github.com/arlimus))
|
24
|
+
- inspec archive for tgz files on windows [\#1907](https://github.com/chef/inspec/pull/1907) ([arlimus](https://github.com/arlimus))
|
25
|
+
- reading binary profile data on windows [\#1906](https://github.com/chef/inspec/pull/1906) ([arlimus](https://github.com/arlimus))
|
26
|
+
- remove duplicate message in describe.one blocks [\#1896](https://github.com/chef/inspec/pull/1896) ([arlimus](https://github.com/arlimus))
|
27
|
+
|
3
28
|
## [v1.27.0](https://github.com/chef/inspec/tree/v1.27.0) (2017-06-06)
|
4
29
|
[Full Changelog](https://github.com/chef/inspec/compare/v1.26.0...v1.27.0)
|
5
30
|
|
data/docs/resources/host.md.erb
CHANGED
@@ -12,7 +12,7 @@ A `host` resource block declares a host name, and then (depending on what is to
|
|
12
12
|
|
13
13
|
.. code-block:: ruby
|
14
14
|
|
15
|
-
describe host('example.com', port: 80,
|
15
|
+
describe host('example.com', port: 80, protocol: 'tcp') do
|
16
16
|
it { should be_reachable }
|
17
17
|
end
|
18
18
|
|
@@ -21,7 +21,7 @@ where
|
|
21
21
|
* `host()` must specify a host name and may specify a port number and/or a protocol
|
22
22
|
* `'example.com'` is the host name
|
23
23
|
* `port:` is the port number
|
24
|
-
* `
|
24
|
+
* `protocol: 'name'` is the Internet protocol: TCP (`protocol: 'tcp'`), UDP (`protocol: 'udp'` or ICMP (`protocol: 'icmp'`))
|
25
25
|
* `be_reachable` is a valid matcher for this resource
|
26
26
|
|
27
27
|
|
@@ -73,13 +73,13 @@ The following examples show how to use this InSpec audit resource.
|
|
73
73
|
|
74
74
|
### Verify host name is reachable over a specific protocol and port number
|
75
75
|
|
76
|
-
describe host('example.com', port:
|
76
|
+
describe host('example.com', port: 80, protocol: 'tcp') do
|
77
77
|
it { should be_reachable }
|
78
78
|
end
|
79
79
|
|
80
80
|
### Verify that a specific IP address can be resolved
|
81
81
|
|
82
|
-
describe host('example.com'
|
82
|
+
describe host('example.com') do
|
83
83
|
it { should be_resolvable }
|
84
84
|
its('ipaddress') { should include '192.168.1.1' }
|
85
85
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
---
|
2
|
+
title: About the iis_app Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# iis_app
|
6
|
+
|
7
|
+
Use the `iis_app` InSpec audit resource to test the state of IIS on Windows Server 2012 (and later).
|
8
|
+
|
9
|
+
## Syntax
|
10
|
+
|
11
|
+
An `iis_app` resource block declares details about the named site:
|
12
|
+
|
13
|
+
describe iis_app('application_path', 'site_name') do
|
14
|
+
it { should exist }
|
15
|
+
it { should have_application_pool('application_pool') }
|
16
|
+
it { should have_protocols('protocol') }
|
17
|
+
it { should have_site_name('site') }
|
18
|
+
it { should have_physical_path('physical_path') }
|
19
|
+
it { should have_path('application_path') }
|
20
|
+
end
|
21
|
+
|
22
|
+
where
|
23
|
+
|
24
|
+
* `'application_path'` is the path to the application, such as `'/myapp'`
|
25
|
+
* `'site_name'` is the name of the site, such as `'Default Web Site'`
|
26
|
+
* `('application_pool')` is the name of the application pool in which the site's root application is run, such as `'DefaultAppPool'`
|
27
|
+
* `('protocols')` is a binding for the site, such as `'http'`. A site may have multiple bindings; therefore, use a `have_protocol` matcher for each site protocol to be tested
|
28
|
+
* `('physical_path') is the physical path to the application, such as `'C:\\inetpub\\wwwroot\\myapp'`
|
29
|
+
|
30
|
+
For example:
|
31
|
+
|
32
|
+
describe iis_app('/myapp', 'Default Web Site') do
|
33
|
+
it { should exist }
|
34
|
+
it { should have_application_pool('MyAppPool') }
|
35
|
+
it { should have_protocols('http') }
|
36
|
+
it { should have_site_name('Default Web Site') }
|
37
|
+
it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') }
|
38
|
+
it { should have_path('\\My Application') }
|
39
|
+
end
|
40
|
+
|
41
|
+
## Matchers
|
42
|
+
|
43
|
+
This InSpec audit resource has the following matchers:
|
44
|
+
|
45
|
+
### cmp
|
46
|
+
|
47
|
+
<%= partial "/shared/matcher_cmp" %>
|
48
|
+
|
49
|
+
### eq
|
50
|
+
|
51
|
+
<%= partial "/shared/matcher_eq" %>
|
52
|
+
|
53
|
+
### exist
|
54
|
+
|
55
|
+
The `exist` matcher tests if the site exists:
|
56
|
+
|
57
|
+
it { should exist }
|
58
|
+
|
59
|
+
### have\_application\_pool
|
60
|
+
|
61
|
+
The `have_application_pool` matcher tests if the named application pool exists for the web application:
|
62
|
+
|
63
|
+
it { should have_application_pool('DefaultAppPool') }
|
64
|
+
|
65
|
+
### have_protocol
|
66
|
+
|
67
|
+
The `have_protocol` matcher tests if the specified protocol exists for the web application:
|
68
|
+
|
69
|
+
it { should have_protocol('http') }
|
70
|
+
|
71
|
+
or:
|
72
|
+
|
73
|
+
it { should have_protocol('https') }
|
74
|
+
|
75
|
+
A web application may have multiple bindings; use a `have_protocol` matcher for each unique web application binding to be tested.
|
76
|
+
|
77
|
+
##### Protocol Attributes
|
78
|
+
|
79
|
+
The `have_protocol` matcher can also test attributes that are defined for a web application enabledProtocols.
|
80
|
+
|
81
|
+
it { should have_protocol('http') }
|
82
|
+
|
83
|
+
For example, testing a site that doesn't have https enabled:
|
84
|
+
|
85
|
+
it { should_not have_protocol('https') }
|
86
|
+
it { should have_protocol('http') }
|
87
|
+
|
88
|
+
Testing a web application with https enabled and http enabled:
|
89
|
+
|
90
|
+
it { should have_protocol('https') }
|
91
|
+
it { should have_protocol('http') }
|
92
|
+
|
93
|
+
### have_physical_path
|
94
|
+
|
95
|
+
The `have_physical_path` matcher tests if the named path is defined for the web application:
|
96
|
+
|
97
|
+
it { should have_physical_path('C:\\inetpub\\wwwroot') }
|
98
|
+
|
99
|
+
### include
|
100
|
+
|
101
|
+
<%= partial "/shared/matcher_include" %>
|
102
|
+
|
103
|
+
### match
|
104
|
+
|
105
|
+
<%= partial "/shared/matcher_match" %>
|
106
|
+
|
107
|
+
## Examples
|
108
|
+
|
109
|
+
The following examples show how to use this InSpec audit resource.
|
110
|
+
|
111
|
+
### Test a default IIS web application
|
112
|
+
|
113
|
+
describe iis_app('Default Web Site') do
|
114
|
+
it { should exist }
|
115
|
+
it { should be_running }
|
116
|
+
it { should have_app_pool('DefaultAppPool') }
|
117
|
+
it { should have_binding('http *:80:') }
|
118
|
+
it { should have_path('%SystemDrive%\\inetpub\\wwwroot') }
|
119
|
+
end
|
120
|
+
|
121
|
+
### Test if IIS service is running
|
122
|
+
|
123
|
+
describe service('W3SVC') do
|
124
|
+
it { should be_installed }
|
125
|
+
it { should be_running }
|
126
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
---
|
2
|
+
title: About the virtualization Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# virtualization
|
6
|
+
|
7
|
+
Use the `virtualization` InSpec audit resource to test the virtualization platform on which the system is running.
|
8
|
+
|
9
|
+
## Syntax
|
10
|
+
|
11
|
+
An `virtualization` resource block declares the virtualization platform that should be tested:
|
12
|
+
|
13
|
+
describe virtualization do
|
14
|
+
its('system') { should MATCHER 'value' }
|
15
|
+
end
|
16
|
+
|
17
|
+
where
|
18
|
+
|
19
|
+
* `('system')` is the name of the system information of the virtualization platform (e.g. docker, lxc, vbox, kvm, etc)
|
20
|
+
* `MATCHER` is a valid matcher for this resource
|
21
|
+
* `'value'` is the value to be tested
|
22
|
+
|
23
|
+
## Matchers
|
24
|
+
|
25
|
+
This InSpec audit resource has the following matchers:
|
26
|
+
|
27
|
+
### be
|
28
|
+
|
29
|
+
<%= partial "/shared/matcher_be" %>
|
30
|
+
|
31
|
+
### cmp
|
32
|
+
|
33
|
+
<%= partial "/shared/matcher_cmp" %>
|
34
|
+
|
35
|
+
### eq
|
36
|
+
|
37
|
+
<%= partial "/shared/matcher_eq" %>
|
38
|
+
|
39
|
+
### include
|
40
|
+
|
41
|
+
<%= partial "/shared/matcher_include" %>
|
42
|
+
|
43
|
+
### match
|
44
|
+
|
45
|
+
<%= partial "/shared/matcher_match" %>
|
46
|
+
|
47
|
+
## Examples
|
48
|
+
|
49
|
+
The following examples show how to use this InSpec audit resource.
|
50
|
+
|
51
|
+
### Test for Docker
|
52
|
+
|
53
|
+
describe virtualization do
|
54
|
+
its('system') { should eq 'docker' }
|
55
|
+
end
|
56
|
+
|
57
|
+
### Test for VirtualBox
|
58
|
+
|
59
|
+
describe virtualization do
|
60
|
+
its('system') { should eq 'vbox' }
|
61
|
+
its('role') { should eq 'guest' }
|
62
|
+
end
|
63
|
+
|
64
|
+
### Detect the virtualization platform
|
65
|
+
|
66
|
+
if virtualization.system == 'vbox'
|
67
|
+
describe package('name') do
|
68
|
+
it { should be_installed }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
---
|
2
|
+
lockfile_version: 1
|
3
|
+
depends:
|
4
|
+
- name: profile
|
5
|
+
resolved_source:
|
6
|
+
path: "/Users/aleff/projects/inspec/examples/profile"
|
7
|
+
version_constraints: ">= 0"
|
8
|
+
- name: profile-attribute
|
9
|
+
resolved_source:
|
10
|
+
path: "/Users/aleff/projects/inspec/examples/profile-attribute"
|
11
|
+
version_constraints: ">= 0"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
lockfile_version: 1
|
3
|
+
depends:
|
4
|
+
- name: dev-sec/ssh-baseline
|
5
|
+
resolved_source:
|
6
|
+
url: https://github.com/dev-sec/ssh-baseline/archive/master.tar.gz
|
7
|
+
sha256: 403580959915ea24bc176b9ebdc555aeda5e2c957604b48d5f32b43554423582
|
8
|
+
version_constraints: ">= 0"
|
9
|
+
- name: ssl-baseline
|
10
|
+
resolved_source:
|
11
|
+
url: https://github.com/dev-sec/ssl-baseline/archive/master.tar.gz
|
12
|
+
sha256: 0e6d170415e120af5f1dda113f96f7e0d156e49f82706ac41d13da00599f9b25
|
13
|
+
version_constraints: ">= 0"
|
14
|
+
- name: windows-patch-benchmark
|
15
|
+
resolved_source:
|
16
|
+
url: https://github.com/chris-rock/windows-patch-benchmark/archive/master.tar.gz
|
17
|
+
sha256: d08d3cc35debff04e708147cdd07739876c5d1c8357afb5e58adfaad92dd650f
|
18
|
+
version_constraints: ">= 0"
|
Binary file
|
Binary file
|
Binary file
|
@@ -204,11 +204,22 @@ module Compliance
|
|
204
204
|
end
|
205
205
|
|
206
206
|
def self.is_automate_server_pre_080?(config)
|
207
|
-
|
207
|
+
# Automate versions before 0.8.x may have a "version" key in the config.
|
208
|
+
# Unless it's a hash that also contains a "version" key, it came from
|
209
|
+
# an Automate server that is pre-0.8.x.
|
210
|
+
return false unless config['server_type'] == 'automate'
|
211
|
+
return true unless config.key?('version')
|
212
|
+
return true unless config['version'].is_a?(Hash)
|
213
|
+
config['version']['version'].nil?
|
208
214
|
end
|
209
215
|
|
210
216
|
def self.is_automate_server_080_and_later?(config)
|
211
|
-
|
217
|
+
# Automate versions 0.8.x and later will have a "version" key in the config
|
218
|
+
# that looks like: "version":{"api":"compliance","version":"0.8.24"}
|
219
|
+
return false unless config['server_type'] == 'automate'
|
220
|
+
return false unless config.key?('version')
|
221
|
+
return false unless config['version'].is_a?(Hash)
|
222
|
+
!config['version']['version'].nil?
|
212
223
|
end
|
213
224
|
|
214
225
|
def self.is_automate_server?(config)
|
data/lib/fetchers/url.rb
CHANGED
data/lib/inspec/archive/tar.rb
CHANGED
data/lib/inspec/base_cli.rb
CHANGED
@@ -19,7 +19,7 @@ module Inspec
|
|
19
19
|
desc: 'Specify the login port for a remote scan.'
|
20
20
|
option :user, type: :string,
|
21
21
|
desc: 'The login user for a remote scan.'
|
22
|
-
option :password, type: :string,
|
22
|
+
option :password, type: :string, lazy_default: -1,
|
23
23
|
desc: 'Login password for a remote scan, if required.'
|
24
24
|
option :key_files, aliases: :i, type: :array,
|
25
25
|
desc: 'Login key or certificate file for a remote scan.'
|
@@ -27,7 +27,7 @@ module Inspec
|
|
27
27
|
desc: 'Login path to use when connecting to the target (WinRM).'
|
28
28
|
option :sudo, type: :boolean,
|
29
29
|
desc: 'Run scans with sudo. Only activates on Unix and non-root user.'
|
30
|
-
option :sudo_password, type: :string,
|
30
|
+
option :sudo_password, type: :string, lazy_default: -1,
|
31
31
|
desc: 'Specify a sudo password, if it is required.'
|
32
32
|
option :sudo_options, type: :string,
|
33
33
|
desc: 'Additional sudo options for a remote scan.'
|
@@ -100,6 +100,23 @@ module Inspec
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def opts
|
103
|
+
o = merged_opts
|
104
|
+
|
105
|
+
# Due to limitations in Thor it is not possible to set an argument to be
|
106
|
+
# both optional and its value to be mandatory. E.g. the user supplying
|
107
|
+
# the --password argument is optional and not always required, but
|
108
|
+
# whenever it is used, it requires a value. Handle options that were
|
109
|
+
# defined above and require a value here:
|
110
|
+
%w{password sudo-password}.each do |v|
|
111
|
+
id = v.tr('-', '_').to_sym
|
112
|
+
next unless o[id] == -1
|
113
|
+
raise ArgumentError, "Please provide a value for --#{v}. For example: --#{v}=hello."
|
114
|
+
end
|
115
|
+
|
116
|
+
o
|
117
|
+
end
|
118
|
+
|
119
|
+
def merged_opts
|
103
120
|
# argv overrides json
|
104
121
|
Thor::CoreExt::HashWithIndifferentAccess.new(options_json.merge(options))
|
105
122
|
end
|
data/lib/inspec/file_provider.rb
CHANGED
@@ -24,12 +24,29 @@ module Inspec
|
|
24
24
|
def initialize(_path)
|
25
25
|
end
|
26
26
|
|
27
|
+
# List all files that are offered.
|
28
|
+
#
|
29
|
+
# @return [Array[String]] list of file paths that are included
|
30
|
+
def files
|
31
|
+
raise "Fetcher #{self} does not implement `files()`. This is required."
|
32
|
+
end
|
33
|
+
|
34
|
+
# Read the contents of a file. This will typically refer to a text
|
35
|
+
# file reading a string.
|
36
|
+
#
|
37
|
+
# @param _file [String] path of the file to be read
|
38
|
+
# @return [String] contents of the file described
|
27
39
|
def read(_file)
|
28
40
|
raise "#{self} does not implement `read(...)`. This is required."
|
29
41
|
end
|
30
42
|
|
31
|
-
|
32
|
-
|
43
|
+
# Provide a method for reading binary contents from a file.
|
44
|
+
# It will default to #read if not defined. For most streams that implement
|
45
|
+
# it, it will be the same. For some special cases, it will add change the
|
46
|
+
# way in which encoding of the returned data structure is handled.
|
47
|
+
# Does not work with alias nor alias_method.
|
48
|
+
def binread(file)
|
49
|
+
read(file)
|
33
50
|
end
|
34
51
|
|
35
52
|
def relative_provider
|
@@ -65,6 +82,12 @@ module Inspec
|
|
65
82
|
return nil unless File.file?(file)
|
66
83
|
File.read(file)
|
67
84
|
end
|
85
|
+
|
86
|
+
def binread(file)
|
87
|
+
return nil unless files.include?(file)
|
88
|
+
return nil unless File.file?(file)
|
89
|
+
File.binread(file)
|
90
|
+
end
|
68
91
|
end
|
69
92
|
|
70
93
|
class ZipProvider < FileProvider
|
@@ -163,6 +186,10 @@ module Inspec
|
|
163
186
|
parent.read(abs_path(file))
|
164
187
|
end
|
165
188
|
|
189
|
+
def binread(file)
|
190
|
+
parent.binread(abs_path(file))
|
191
|
+
end
|
192
|
+
|
166
193
|
private
|
167
194
|
|
168
195
|
def get_prefix(fs)
|
data/lib/inspec/profile.rb
CHANGED
@@ -37,7 +37,7 @@ module Inspec
|
|
37
37
|
cache = file_provider.files.find_all do |entry|
|
38
38
|
entry.start_with?('vendor')
|
39
39
|
end
|
40
|
-
content = Hash[cache.map { |x| [x, file_provider.
|
40
|
+
content = Hash[cache.map { |x| [x, file_provider.binread(x)] }]
|
41
41
|
keys = content.keys
|
42
42
|
keys.each do |key|
|
43
43
|
next if content[key].nil?
|
@@ -47,7 +47,7 @@ module Inspec
|
|
47
47
|
|
48
48
|
FileUtils.mkdir_p tar.dirname.to_s
|
49
49
|
Inspec::Log.debug "Copy #{tar} to cache directory"
|
50
|
-
File.
|
50
|
+
File.binwrite(tar.to_s, content[key])
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
data/lib/inspec/resource.rb
CHANGED
@@ -96,6 +96,7 @@ require 'resources/groups'
|
|
96
96
|
require 'resources/grub_conf'
|
97
97
|
require 'resources/host'
|
98
98
|
require 'resources/http'
|
99
|
+
require 'resources/iis_app'
|
99
100
|
require 'resources/iis_site'
|
100
101
|
require 'resources/inetd_conf'
|
101
102
|
require 'resources/interface'
|
@@ -138,6 +139,7 @@ require 'resources/ssh_conf'
|
|
138
139
|
require 'resources/sys_info'
|
139
140
|
require 'resources/users'
|
140
141
|
require 'resources/vbscript'
|
142
|
+
require 'resources/virtualization'
|
141
143
|
require 'resources/windows_feature'
|
142
144
|
require 'resources/windows_task'
|
143
145
|
require 'resources/xinetd'
|
@@ -52,7 +52,7 @@ class InspecRspecMiniJson < RSpec::Core::Formatters::JsonFormatter
|
|
52
52
|
format_example(example).tap do |hash|
|
53
53
|
e = example.exception
|
54
54
|
next unless e
|
55
|
-
hash[:message] = e
|
55
|
+
hash[:message] = exception_message(e)
|
56
56
|
|
57
57
|
next if e.is_a? RSpec::Expectations::ExpectationNotMetError
|
58
58
|
hash[:exception] = e.class.name
|
@@ -63,6 +63,14 @@ class InspecRspecMiniJson < RSpec::Core::Formatters::JsonFormatter
|
|
63
63
|
|
64
64
|
private
|
65
65
|
|
66
|
+
def exception_message(exception)
|
67
|
+
if exception.is_a?(RSpec::Core::MultipleExceptionError)
|
68
|
+
exception.all_exceptions.map(&:message).uniq.join("\n\n")
|
69
|
+
else
|
70
|
+
exception.message
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
66
74
|
def format_example(example)
|
67
75
|
if !example.metadata[:description_args].empty? && example.metadata[:skip]
|
68
76
|
# For skipped profiles, rspec returns in full_description the skip_message as well. We don't want
|
data/lib/inspec/version.rb
CHANGED
data/lib/resources/host.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
# end
|
11
11
|
#
|
12
12
|
# To verify a hostname with protocol and port
|
13
|
-
# describe host('example.com', port:
|
13
|
+
# describe host('example.com', port: 443, protocol: 'tcp') do
|
14
14
|
# it { should be_reachable }
|
15
15
|
# end
|
16
16
|
#
|
@@ -33,17 +33,26 @@ module Inspec::Resources
|
|
33
33
|
it { should be_reachable }
|
34
34
|
end
|
35
35
|
|
36
|
-
describe host('example.com', port: '80') do
|
36
|
+
describe host('example.com', port: '80', protocol: 'tcp') do
|
37
37
|
it { should be_reachable }
|
38
38
|
end
|
39
39
|
"
|
40
40
|
|
41
|
+
attr_reader :hostname, :port, :protocol
|
42
|
+
|
41
43
|
def initialize(hostname, params = {})
|
42
44
|
@hostname = hostname
|
43
|
-
@port = params[:port]
|
44
|
-
@proto = params[:proto] || nil
|
45
|
+
@port = params[:port]
|
45
46
|
|
46
|
-
|
47
|
+
if params[:proto]
|
48
|
+
warn '[DEPRECATION] The `proto` parameter is deprecated. Use `protocol` instead.'
|
49
|
+
@protocol = params[:proto]
|
50
|
+
else
|
51
|
+
@protocol = params.fetch(:protocol, 'icmp')
|
52
|
+
end
|
53
|
+
|
54
|
+
return skip_resource 'Invalid protocol: only `tcp` and `icmp` protocols are support for the `host` resource.' unless
|
55
|
+
%w{icmp tcp}.include?(@protocol)
|
47
56
|
|
48
57
|
@host_provider = nil
|
49
58
|
if inspec.os.linux?
|
@@ -55,6 +64,16 @@ module Inspec::Resources
|
|
55
64
|
else
|
56
65
|
return skip_resource 'The `host` resource is not supported on your OS yet.'
|
57
66
|
end
|
67
|
+
|
68
|
+
missing_requirements = @host_provider.missing_requirements(protocol)
|
69
|
+
unless missing_requirements.empty?
|
70
|
+
return skip_resource "The following requirements are not met for this resource: #{missing_requirements.join(', ')}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def proto
|
75
|
+
warn '[DEPRECATION] The `proto` method is deprecated. Use `protocol` instead.'
|
76
|
+
protocol
|
58
77
|
end
|
59
78
|
|
60
79
|
# if we get the IP address, the host is resolvable
|
@@ -63,9 +82,25 @@ module Inspec::Resources
|
|
63
82
|
resolve.nil? || resolve.empty? ? false : true
|
64
83
|
end
|
65
84
|
|
66
|
-
def reachable?
|
67
|
-
|
68
|
-
ping.
|
85
|
+
def reachable?
|
86
|
+
# ping checks do not require port or protocol
|
87
|
+
return ping.fetch(:success, false) if protocol == 'icmp'
|
88
|
+
|
89
|
+
# if either port or protocol are specified but not both, we cannot proceed.
|
90
|
+
if port.nil? || protocol.nil?
|
91
|
+
raise "Protocol required with port. Use `host` resource with host('#{hostname}', port: 1234, proto: 'tcp') parameters." if port.nil? || protocol.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
# perform the protocol-specific reachability test
|
95
|
+
ping.fetch(:success, false)
|
96
|
+
end
|
97
|
+
|
98
|
+
def connection
|
99
|
+
ping[:connection]
|
100
|
+
end
|
101
|
+
|
102
|
+
def socket
|
103
|
+
ping[:socket]
|
69
104
|
end
|
70
105
|
|
71
106
|
# returns all A records of the IP address, will return an array
|
@@ -74,19 +109,21 @@ module Inspec::Resources
|
|
74
109
|
end
|
75
110
|
|
76
111
|
def to_s
|
77
|
-
"Host #{
|
112
|
+
"Host #{hostname}"
|
78
113
|
end
|
79
114
|
|
80
115
|
private
|
81
116
|
|
82
117
|
def ping
|
83
118
|
return @ping_cache if defined?(@ping_cache)
|
84
|
-
|
119
|
+
return {} if @host_provider.nil?
|
120
|
+
|
121
|
+
@ping_cache = @host_provider.ping(hostname, port, protocol)
|
85
122
|
end
|
86
123
|
|
87
124
|
def resolve
|
88
125
|
return @ip_cache if defined?(@ip_cache)
|
89
|
-
@ip_cache = @host_provider.resolve(
|
126
|
+
@ip_cache = @host_provider.resolve(hostname) if !@host_provider.nil?
|
90
127
|
end
|
91
128
|
end
|
92
129
|
|
@@ -95,16 +132,37 @@ module Inspec::Resources
|
|
95
132
|
def initialize(inspec)
|
96
133
|
@inspec = inspec
|
97
134
|
end
|
135
|
+
|
136
|
+
def missing_requirements(_protocol)
|
137
|
+
# each provider can return an array of missing requirements that can
|
138
|
+
# be enumerated in a skip_resource message
|
139
|
+
[]
|
140
|
+
end
|
98
141
|
end
|
99
142
|
|
100
143
|
class DarwinHostProvider < HostProvider
|
101
|
-
def
|
102
|
-
|
144
|
+
def missing_requirements(protocol)
|
145
|
+
missing = []
|
146
|
+
|
147
|
+
if protocol == 'tcp'
|
148
|
+
missing << 'netcat must be installed' unless inspec.command('nc').exist?
|
149
|
+
end
|
150
|
+
|
151
|
+
missing
|
152
|
+
end
|
153
|
+
|
154
|
+
def ping(hostname, port, protocol)
|
155
|
+
if protocol == 'tcp'
|
103
156
|
resp = inspec.command("nc -vz -G 1 #{hostname} #{port}")
|
104
157
|
else
|
105
158
|
resp = inspec.command("ping -W 1 -c 1 #{hostname}")
|
106
159
|
end
|
107
|
-
|
160
|
+
|
161
|
+
{
|
162
|
+
success: resp.exit_status.to_i.zero?,
|
163
|
+
connection: resp.stderr,
|
164
|
+
socket: resp.stdout,
|
165
|
+
}
|
108
166
|
end
|
109
167
|
|
110
168
|
def resolve(hostname)
|
@@ -121,12 +179,29 @@ module Inspec::Resources
|
|
121
179
|
end
|
122
180
|
|
123
181
|
class LinuxHostProvider < HostProvider
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
182
|
+
def missing_requirements(protocol)
|
183
|
+
missing = []
|
184
|
+
|
185
|
+
if protocol == 'tcp'
|
186
|
+
missing << 'netcat must be installed' unless inspec.command('nc').exist?
|
187
|
+
end
|
188
|
+
|
189
|
+
missing
|
190
|
+
end
|
191
|
+
|
192
|
+
def ping(hostname, port, protocol)
|
193
|
+
if protocol == 'tcp'
|
194
|
+
resp = inspec.command("echo | nc -v -w 1 #{hostname} #{port}")
|
195
|
+
else
|
196
|
+
# fall back to ping, but we can only test ICMP packages with ping
|
197
|
+
resp = inspec.command("ping -w 1 -c 1 #{hostname}")
|
198
|
+
end
|
199
|
+
|
200
|
+
{
|
201
|
+
success: resp.exit_status.to_i.zero?,
|
202
|
+
connection: resp.stderr,
|
203
|
+
socket: resp.stdout,
|
204
|
+
}
|
130
205
|
end
|
131
206
|
|
132
207
|
def resolve(hostname)
|
@@ -156,15 +231,10 @@ module Inspec::Resources
|
|
156
231
|
begin
|
157
232
|
ping = JSON.parse(cmd.stdout)
|
158
233
|
rescue JSON::ParserError => _e
|
159
|
-
return
|
234
|
+
return {}
|
160
235
|
end
|
161
236
|
|
162
|
-
|
163
|
-
if port.nil?
|
164
|
-
ping['PingSucceeded']
|
165
|
-
else
|
166
|
-
ping['TcpTestSucceeded']
|
167
|
-
end
|
237
|
+
{ success: port.nil? ? ping['PingSucceeded'] : ping['TcpTestSucceeded'] }
|
168
238
|
end
|
169
239
|
|
170
240
|
def resolve(hostname)
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# check for web applications in IIS
|
4
|
+
# Note: this is only supported in windows 2012 and later
|
5
|
+
module Inspec::Resources
|
6
|
+
class IisApp < Inspec.resource(1)
|
7
|
+
name 'iis_app'
|
8
|
+
desc 'Tests IIS application configuration on windows. Supported in server 2012+ only'
|
9
|
+
example "
|
10
|
+
describe iis_app('/myapp', 'Default Web Site') do
|
11
|
+
it { should exist }
|
12
|
+
it { should have_application_pool('MyAppPool') }
|
13
|
+
it { should have_protocols('http') }
|
14
|
+
it { should have_site_name('Default Web Site') }
|
15
|
+
it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') }
|
16
|
+
it { should have_path('\\My Application') }
|
17
|
+
end
|
18
|
+
"
|
19
|
+
|
20
|
+
def initialize(path, site_name)
|
21
|
+
@path = path
|
22
|
+
@site_name = site_name
|
23
|
+
@cache = nil
|
24
|
+
@inspec = inspec
|
25
|
+
|
26
|
+
# verify that this resource is only supported on Windows
|
27
|
+
return skip_resource 'The `iis_app` resource is not supported on your OS.' unless inspec.os.windows?
|
28
|
+
end
|
29
|
+
|
30
|
+
def application_pool
|
31
|
+
iis_app[:application_pool]
|
32
|
+
end
|
33
|
+
|
34
|
+
def protocols
|
35
|
+
iis_app[:protocols]
|
36
|
+
end
|
37
|
+
|
38
|
+
def site_name
|
39
|
+
iis_app[:site_name]
|
40
|
+
end
|
41
|
+
|
42
|
+
def path
|
43
|
+
iis_app[:path]
|
44
|
+
end
|
45
|
+
|
46
|
+
def physical_path
|
47
|
+
iis_app[:physical_path]
|
48
|
+
end
|
49
|
+
|
50
|
+
def exists?
|
51
|
+
!iis_app[:path].empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
def has_site_name?(site_name)
|
55
|
+
iis_app[:site_name] == site_name
|
56
|
+
end
|
57
|
+
|
58
|
+
def has_application_pool?(application_pool)
|
59
|
+
iis_app[:application_pool] == application_pool
|
60
|
+
end
|
61
|
+
|
62
|
+
def has_path?(path)
|
63
|
+
iis_app[:path] == path
|
64
|
+
end
|
65
|
+
|
66
|
+
def has_physical_path?(physical_path)
|
67
|
+
iis_app[:physical_path] == physical_path
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_protocol?(protocol)
|
71
|
+
iis_app[:protocols].include?(protocol)
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_s
|
75
|
+
"iis_app '#{@site_name}#{@path}'"
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def iis_app
|
81
|
+
return @cache unless @cache.nil?
|
82
|
+
command = "Import-Module WebAdministration; Get-WebApplication -Name '#{@path}' -Site '#{@site_name}' | Select-Object * | ConvertTo-Json"
|
83
|
+
cmd = @inspec.command(command)
|
84
|
+
|
85
|
+
begin
|
86
|
+
app = JSON.parse(cmd.stdout)
|
87
|
+
rescue JSON::ParserError => _e
|
88
|
+
return {}
|
89
|
+
end
|
90
|
+
|
91
|
+
# map our values to a hash table
|
92
|
+
info = {
|
93
|
+
site_name: @site_name,
|
94
|
+
path: @path,
|
95
|
+
application_pool: app['applicationPool'],
|
96
|
+
physical_path: app['PhysicalPath'],
|
97
|
+
protocols: app['enabledProtocols'],
|
98
|
+
}
|
99
|
+
|
100
|
+
@cache = info unless info.nil?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/resources/service.rb
CHANGED
@@ -151,6 +151,8 @@ module Inspec::Resources
|
|
151
151
|
BSDInit.new(inspec, service_ctl)
|
152
152
|
elsif %w{arch}.include?(platform)
|
153
153
|
Systemd.new(inspec, service_ctl)
|
154
|
+
elsif %w{coreos}.include?(platform)
|
155
|
+
Systemd.new(inspec, service_ctl)
|
154
156
|
elsif %w{suse opensuse}.include?(platform)
|
155
157
|
if os[:release].to_i >= 12
|
156
158
|
Systemd.new(inspec, service_ctl)
|
@@ -0,0 +1,252 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Takaaki Furukawa
|
3
|
+
|
4
|
+
require 'hashie/mash'
|
5
|
+
|
6
|
+
module Inspec::Resources
|
7
|
+
class Virtualization < Inspec.resource(1) # rubocop:disable Metrics/ClassLength
|
8
|
+
name 'virtualization'
|
9
|
+
desc 'Use the virtualization InSpec audit resource to test the virtualization platform on which the system is running'
|
10
|
+
example "
|
11
|
+
describe virtualization do
|
12
|
+
its('system') { should eq 'docker' }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe virtualization do
|
16
|
+
its('role') { should eq 'guest' }
|
17
|
+
end
|
18
|
+
|
19
|
+
control 'test' do
|
20
|
+
describe file('/var/tmp/foo') do
|
21
|
+
it { should be_file }
|
22
|
+
end
|
23
|
+
only_if { virtualization.system == 'docker' }
|
24
|
+
end
|
25
|
+
"
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
unless inspec.os.linux?
|
29
|
+
skip_resource 'The `virtualization` resource is not supported on your OS yet.'
|
30
|
+
else
|
31
|
+
collect_data_linux
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# add helper methods for easy access of properties
|
36
|
+
# allows users to use virtualization.role, virtualization.system
|
37
|
+
%w{role system}.each do |property|
|
38
|
+
define_method(property.to_sym) do
|
39
|
+
@virtualization_data[property.to_sym]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def params
|
44
|
+
collect_data_linux
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
'Virtualization Detection'
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def lxc_version_exists?
|
54
|
+
inspec.command('lxc-version').exist?
|
55
|
+
end
|
56
|
+
|
57
|
+
def docker_exists?
|
58
|
+
inspec.command('docker').exist?
|
59
|
+
end
|
60
|
+
|
61
|
+
def nova_exists?
|
62
|
+
inspec.command('nova').exist?
|
63
|
+
end
|
64
|
+
|
65
|
+
# Detect Xen
|
66
|
+
# /proc/xen is an empty dir for EL6 + Linode Guests + Paravirt EC2 instances
|
67
|
+
# Notes:
|
68
|
+
# - cpuid of guests, if we could get it, would also be a clue
|
69
|
+
# - may be able to determine if under paravirt from /dev/xen/evtchn (See OHAI-253)
|
70
|
+
# - Additional edge cases likely should not change the above assumptions
|
71
|
+
# but rather be additive - btm
|
72
|
+
def detect_xen
|
73
|
+
return false unless inspec.file('/proc/xen').exist?
|
74
|
+
@virtualization_data[:system] = 'xen'
|
75
|
+
@virtualization_data[:role] = 'guest'
|
76
|
+
|
77
|
+
# This file should exist on most Xen systems, normally empty for guests
|
78
|
+
if inspec.file('/proc/xen/capabilities').exist? &&
|
79
|
+
inspec.file('/proc/xen/capabilities').content =~ /control_d/i # rubocop:disable Style/MultilineOperationIndentation
|
80
|
+
@virtualization_data[:role] = 'host'
|
81
|
+
end
|
82
|
+
true
|
83
|
+
end
|
84
|
+
|
85
|
+
# Detect Virtualbox from kernel module
|
86
|
+
def detect_virtualbox
|
87
|
+
return false unless inspec.file('/proc/modules').exist?
|
88
|
+
modules = inspec.file('/proc/modules').content
|
89
|
+
if modules =~ /^vboxdrv/
|
90
|
+
Inspec::Log.debug('Plugin Virtualization: /proc/modules contains vboxdrv. Detecting as vbox host')
|
91
|
+
@virtualization_data[:system] = 'vbox'
|
92
|
+
@virtualization_data[:role] = 'host'
|
93
|
+
elsif modules =~ /^vboxguest/
|
94
|
+
Inspec::Log.debug('Plugin Virtualization: /proc/modules contains vboxguest. Detecting as vbox guest')
|
95
|
+
@virtualization_data[:system] = 'vbox'
|
96
|
+
@virtualization_data[:role] = 'guest'
|
97
|
+
else
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
true
|
101
|
+
end
|
102
|
+
|
103
|
+
# if nova binary is present we're on an openstack host
|
104
|
+
def detect_openstack
|
105
|
+
return false unless nova_exists?
|
106
|
+
@virtualization_data[:system] = 'openstack'
|
107
|
+
@virtualization_data[:role] = 'host'
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
# Detect paravirt KVM/QEMU from cpuinfo, report as KVM
|
112
|
+
def detect_kvm_from_cpuinfo
|
113
|
+
return false unless inspec.file('/proc/cpuinfo').content =~ /QEMU Virtual CPU|Common KVM processor|Common 32-bit KVM processor/
|
114
|
+
@virtualization_data[:system] = 'kvm'
|
115
|
+
@virtualization_data[:role] = 'guest'
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
# Detect KVM systems via /sys
|
120
|
+
# guests will have the hypervisor cpu feature that hosts don't have
|
121
|
+
def detect_kvm_from_sys
|
122
|
+
return false unless inspec.file('/sys/devices/virtual/misc/kvm').exist?
|
123
|
+
if inspec.file('/proc/cpuinfo').content =~ /hypervisor/
|
124
|
+
@virtualization_data[:system] = 'kvm'
|
125
|
+
@virtualization_data[:role] = 'guest'
|
126
|
+
else
|
127
|
+
@virtualization_data[:system] = 'kvm'
|
128
|
+
@virtualization_data[:role] = 'host'
|
129
|
+
end
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
# Detect OpenVZ / Virtuozzo.
|
134
|
+
# http://wiki.openvz.org/BC_proc_entries
|
135
|
+
def detect_openvz
|
136
|
+
if inspec.file('/proc/bc/0').exist?
|
137
|
+
@virtualization_data[:system] = 'openvz'
|
138
|
+
@virtualization_data[:role] = 'host'
|
139
|
+
elsif inspec.file('/proc/vz').exist?
|
140
|
+
@virtualization_data[:system] = 'openvz'
|
141
|
+
@virtualization_data[:role] = 'guest'
|
142
|
+
else
|
143
|
+
return false
|
144
|
+
end
|
145
|
+
true
|
146
|
+
end
|
147
|
+
|
148
|
+
# Detect Parallels virtual machine from pci devices
|
149
|
+
def detect_parallels
|
150
|
+
return false unless inspec.file('/proc/bus/pci/devices').content =~ /1ab84000/
|
151
|
+
@virtualization_data[:system] = 'parallels'
|
152
|
+
@virtualization_data[:role] = 'guest'
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
156
|
+
# Detect Linux-VServer
|
157
|
+
def detect_linux_vserver
|
158
|
+
return false unless inspec.file('/proc/self/status').exist?
|
159
|
+
proc_self_status = inspec.file('/proc/self/status').content
|
160
|
+
vxid = proc_self_status.match(/^(s_context|VxID):\s*(\d+)$/)
|
161
|
+
return false unless vxid && vxid[2]
|
162
|
+
@virtualization_data[:system] = 'linux-vserver'
|
163
|
+
if vxid[2] == '0'
|
164
|
+
@virtualization_data[:role] = 'host'
|
165
|
+
else
|
166
|
+
@virtualization_data[:role] = 'guest'
|
167
|
+
end
|
168
|
+
true
|
169
|
+
end
|
170
|
+
|
171
|
+
# Detect LXC/Docker
|
172
|
+
#
|
173
|
+
# /proc/self/cgroup will look like this inside a docker container:
|
174
|
+
# <index #>:<subsystem>:/lxc/<hexadecimal container id>
|
175
|
+
#
|
176
|
+
# /proc/self/cgroup could have a name including alpha/digit/dashes
|
177
|
+
# <index #>:<subsystem>:/lxc/<named container id>
|
178
|
+
#
|
179
|
+
# /proc/self/cgroup could have a non-lxc cgroup name indicating other uses
|
180
|
+
# of cgroups. This is probably not LXC/Docker.
|
181
|
+
# <index #>:<subsystem>:/Charlie
|
182
|
+
#
|
183
|
+
# A host which supports cgroups, and has capacity to host lxc containers,
|
184
|
+
# will show the subsystems and root (/) namespace.
|
185
|
+
# <index #>:<subsystem>:/
|
186
|
+
#
|
187
|
+
# Full notes, https://tickets.opscode.com/browse/OHAI-551
|
188
|
+
# Kernel docs, https://www.kernel.org/doc/Documentation/cgroups
|
189
|
+
def detect_lxc_docker
|
190
|
+
return false unless inspec.file('/proc/self/cgroup').exist?
|
191
|
+
cgroup_content = inspec.file('/proc/self/cgroup').content
|
192
|
+
if cgroup_content =~ %r{^\d+:[^:]+:/(lxc|docker)/.+$} ||
|
193
|
+
cgroup_content =~ %r{^\d+:[^:]+:/[^/]+/(lxc|docker)-.+$} # rubocop:disable Style/MultilineOperationIndentation
|
194
|
+
@virtualization_data[:system] = $1 # rubocop:disable Style/PerlBackrefs
|
195
|
+
@virtualization_data[:role] = 'guest'
|
196
|
+
elsif lxc_version_exists? && cgroup_content =~ %r{\d:[^:]+:/$}
|
197
|
+
# lxc-version shouldn't be installed by default
|
198
|
+
# Even so, it is likely we are on an LXC capable host that is not being used as such
|
199
|
+
# So we're cautious here to not overwrite other existing values (OHAI-573)
|
200
|
+
unless @virtualization_data[:system] && @virtualization_data[:role]
|
201
|
+
@virtualization_data[:system] = 'lxc'
|
202
|
+
@virtualization_data[:role] = 'host'
|
203
|
+
end
|
204
|
+
else
|
205
|
+
return false
|
206
|
+
end
|
207
|
+
true
|
208
|
+
end
|
209
|
+
|
210
|
+
def detect_docker
|
211
|
+
return false unless inspec.file('/.dockerenv').exist? || inspec.file('/.dockerinit').exist?
|
212
|
+
@virtualization_data[:system] = 'docker'
|
213
|
+
@virtualization_data[:role] = 'guest'
|
214
|
+
true
|
215
|
+
end
|
216
|
+
|
217
|
+
# Detect LXD
|
218
|
+
# See https://github.com/lxc/lxd/blob/master/doc/dev-lxd.md
|
219
|
+
def detect_lxd
|
220
|
+
if inspec.file('/dev/lxd/sock').exist?
|
221
|
+
@virtualization_data[:system] = 'lxd'
|
222
|
+
@virtualization_data[:role] = 'guest'
|
223
|
+
elsif inspec.file('/var/lib/lxd/devlxd').exist?
|
224
|
+
@virtualization_data[:system] = 'lxd'
|
225
|
+
@virtualization_data[:role] = 'host'
|
226
|
+
else
|
227
|
+
return false
|
228
|
+
end
|
229
|
+
true
|
230
|
+
end
|
231
|
+
|
232
|
+
def collect_data_linux # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
233
|
+
# cache data in an instance var to avoid doing multiple detections for a single test
|
234
|
+
@virtualization_data ||= Hashie::Mash.new
|
235
|
+
return unless @virtualization_data.empty?
|
236
|
+
|
237
|
+
# each detect method will return true if it matched and was successfully
|
238
|
+
# able to populate @virtualization_data with stuff.
|
239
|
+
return if detect_xen
|
240
|
+
return if detect_virtualbox
|
241
|
+
return if detect_openstack
|
242
|
+
return if detect_kvm_from_cpuinfo
|
243
|
+
return if detect_kvm_from_sys
|
244
|
+
return if detect_openvz
|
245
|
+
return if detect_parallels
|
246
|
+
return if detect_linux_vserver
|
247
|
+
return if detect_lxc_docker
|
248
|
+
return if detect_docker
|
249
|
+
return if detect_lxd
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: train
|
@@ -305,6 +305,7 @@ files:
|
|
305
305
|
- docs/migration.md
|
306
306
|
- docs/plugin_kitchen_inspec.md
|
307
307
|
- docs/profiles.md
|
308
|
+
- docs/resources.md
|
308
309
|
- docs/resources/apache_conf.md.erb
|
309
310
|
- docs/resources/apt.md.erb
|
310
311
|
- docs/resources/audit_policy.md.erb
|
@@ -331,6 +332,7 @@ files:
|
|
331
332
|
- docs/resources/grub_conf.md.erb
|
332
333
|
- docs/resources/host.md.erb
|
333
334
|
- docs/resources/http.md.erb
|
335
|
+
- docs/resources/iis_app.md.erb
|
334
336
|
- docs/resources/iis_site.md.erb
|
335
337
|
- docs/resources/inetd_conf.md.erb
|
336
338
|
- docs/resources/ini.md.erb
|
@@ -377,6 +379,7 @@ files:
|
|
377
379
|
- docs/resources/user.md.erb
|
378
380
|
- docs/resources/users.md.erb
|
379
381
|
- docs/resources/vbscript.md.erb
|
382
|
+
- docs/resources/virtualization.md.erb
|
380
383
|
- docs/resources/windows_feature.md.erb
|
381
384
|
- docs/resources/windows_task.md.erb
|
382
385
|
- docs/resources/wmi.md.erb
|
@@ -396,6 +399,7 @@ files:
|
|
396
399
|
- examples/README.md
|
397
400
|
- examples/inheritance/README.md
|
398
401
|
- examples/inheritance/controls/example.rb
|
402
|
+
- examples/inheritance/inspec.lock
|
399
403
|
- examples/inheritance/inspec.yml
|
400
404
|
- examples/kitchen-ansible/.kitchen.yml
|
401
405
|
- examples/kitchen-ansible/Gemfile
|
@@ -421,7 +425,11 @@ files:
|
|
421
425
|
- examples/kitchen-puppet/test/integration/default/web_spec.rb
|
422
426
|
- examples/meta-profile/README.md
|
423
427
|
- examples/meta-profile/controls/example.rb
|
428
|
+
- examples/meta-profile/inspec.lock
|
424
429
|
- examples/meta-profile/inspec.yml
|
430
|
+
- examples/meta-profile/vendor/0e6d170415e120af5f1dda113f96f7e0d156e49f82706ac41d13da00599f9b25.tar.gz
|
431
|
+
- examples/meta-profile/vendor/403580959915ea24bc176b9ebdc555aeda5e2c957604b48d5f32b43554423582.tar.gz
|
432
|
+
- examples/meta-profile/vendor/d08d3cc35debff04e708147cdd07739876c5d1c8357afb5e58adfaad92dd650f.tar.gz
|
425
433
|
- examples/profile-attribute.yml
|
426
434
|
- examples/profile-attribute/README.md
|
427
435
|
- examples/profile-attribute/controls/example.rb
|
@@ -558,6 +566,7 @@ files:
|
|
558
566
|
- lib/resources/grub_conf.rb
|
559
567
|
- lib/resources/host.rb
|
560
568
|
- lib/resources/http.rb
|
569
|
+
- lib/resources/iis_app.rb
|
561
570
|
- lib/resources/iis_site.rb
|
562
571
|
- lib/resources/inetd_conf.rb
|
563
572
|
- lib/resources/ini.rb
|
@@ -601,6 +610,7 @@ files:
|
|
601
610
|
- lib/resources/sys_info.rb
|
602
611
|
- lib/resources/users.rb
|
603
612
|
- lib/resources/vbscript.rb
|
613
|
+
- lib/resources/virtualization.rb
|
604
614
|
- lib/resources/windows_feature.rb
|
605
615
|
- lib/resources/windows_task.rb
|
606
616
|
- lib/resources/wmi.rb
|