inspec 1.21.0 → 1.22.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 +53 -0
- data/README.md +4 -0
- data/Rakefile +16 -9
- data/docs/dsl_inspec.md +4 -1
- data/docs/inspec_and_friends.md +4 -2
- data/docs/resources/parse_config.md.erb +7 -7
- data/docs/resources/parse_config_file.md.erb +8 -8
- data/docs/resources/port.md.erb +5 -5
- data/lib/inspec/backend.rb +18 -0
- data/lib/inspec/objects/control.rb +13 -1
- data/lib/inspec/resource.rb +4 -0
- data/lib/inspec/rule.rb +12 -6
- data/lib/inspec/shell.rb +76 -13
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apache_conf.rb +1 -1
- data/lib/resources/auditd_rules.rb +2 -2
- data/lib/resources/bond.rb +1 -1
- data/lib/resources/docker.rb +12 -0
- data/lib/resources/inetd_conf.rb +2 -2
- data/lib/resources/limits_conf.rb +2 -2
- data/lib/resources/login_def.rb +1 -1
- data/lib/resources/ntp_conf.rb +1 -1
- data/lib/resources/package.rb +5 -5
- data/lib/resources/parse_config.rb +2 -2
- data/lib/resources/pip.rb +1 -1
- data/lib/resources/postgres_conf.rb +1 -1
- data/lib/resources/security_policy.rb +1 -1
- data/lib/resources/service.rb +2 -2
- data/lib/resources/ssh_conf.rb +1 -1
- data/lib/resources/users.rb +4 -4
- data/lib/utils/simpleconfig.rb +17 -5
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 474a314003f5f557da8d77561757a2083f6cda14
|
|
4
|
+
data.tar.gz: a3d427af33967690bee737f8ea3fe6ebc3205fbf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f0cdabdfa5797224c35dc08b0b9159d7f4b5f20f115789618dffd880e9e0665cee0757cd194d2ed98dbee0c0c0bab1df65e23bbe6c6e3b052cb3c412d2a6767
|
|
7
|
+
data.tar.gz: 7b2add303caa99cda92831422e170805465536cc8e1e6b83fd92003817bc1b4cdd435ef46ee4f2e30635a6031b467396e0f069374443c64c3f2ae78e0433b115
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## [v1.22.0](https://github.com/chef/inspec/tree/v1.22.0) (2017-04-27)
|
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.21.0...v1.22.0)
|
|
5
|
+
|
|
6
|
+
**Implemented enhancements:**
|
|
7
|
+
|
|
8
|
+
- rename `parse\_config` options for clarity [\#1709](https://github.com/chef/inspec/issues/1709)
|
|
9
|
+
- Lackluster type coercion [\#445](https://github.com/chef/inspec/issues/445)
|
|
10
|
+
- Update port documentation to use `cmp` matcher [\#438](https://github.com/chef/inspec/issues/438)
|
|
11
|
+
- Simplify error output [\#437](https://github.com/chef/inspec/issues/437)
|
|
12
|
+
- Follow Gnu Standards for Command Line Interfaces [\#436](https://github.com/chef/inspec/issues/436)
|
|
13
|
+
- Clarify `impact` of controls [\#358](https://github.com/chef/inspec/issues/358)
|
|
14
|
+
- make the default logger readable [\#335](https://github.com/chef/inspec/issues/335)
|
|
15
|
+
- Resolve open points from \#252 [\#334](https://github.com/chef/inspec/issues/334)
|
|
16
|
+
- document all custom RSpec matcher [\#317](https://github.com/chef/inspec/issues/317)
|
|
17
|
+
- Readme: Point to sources of documentation [\#231](https://github.com/chef/inspec/issues/231)
|
|
18
|
+
- Readme: differentiate from Serverspec [\#229](https://github.com/chef/inspec/issues/229)
|
|
19
|
+
- support legacy backend configuration calls \(rspec/serverspec\) [\#187](https://github.com/chef/inspec/issues/187)
|
|
20
|
+
- Some inconsistencies with naming across the resources [\#120](https://github.com/chef/inspec/issues/120)
|
|
21
|
+
- ensure all resources do OS check [\#96](https://github.com/chef/inspec/issues/96)
|
|
22
|
+
- run docker backend in one exec loop [\#81](https://github.com/chef/inspec/issues/81)
|
|
23
|
+
- make all transport configurable and optional [\#65](https://github.com/chef/inspec/issues/65)
|
|
24
|
+
- inspec control.to\_ruby to use newlines instead of `\n` [\#1705](https://github.com/chef/inspec/pull/1705) ([arlimus](https://github.com/arlimus))
|
|
25
|
+
|
|
26
|
+
**Fixed bugs:**
|
|
27
|
+
|
|
28
|
+
- bugfix: unindent description misbehaviors [\#1707](https://github.com/chef/inspec/pull/1707) ([arlimus](https://github.com/arlimus))
|
|
29
|
+
|
|
30
|
+
**Closed issues:**
|
|
31
|
+
|
|
32
|
+
- Test [\#1721](https://github.com/chef/inspec/issues/1721)
|
|
33
|
+
- Inspec Shell Enhancement - Show universal matchers on HELP MATCHERS command [\#1684](https://github.com/chef/inspec/issues/1684)
|
|
34
|
+
- detecting service enabled on Ubuntu 16.04 \(systemd\) [\#931](https://github.com/chef/inspec/issues/931)
|
|
35
|
+
- Can't get sub key in YAML [\#554](https://github.com/chef/inspec/issues/554)
|
|
36
|
+
- Sharing custom resources? [\#353](https://github.com/chef/inspec/issues/353)
|
|
37
|
+
- Readme: What is being installed? [\#166](https://github.com/chef/inspec/issues/166)
|
|
38
|
+
|
|
39
|
+
**Merged pull requests:**
|
|
40
|
+
|
|
41
|
+
- Update GH Pages CNAME [\#1731](https://github.com/chef/inspec/pull/1731) ([adamleff](https://github.com/adamleff))
|
|
42
|
+
- Rakefile updates to support appbundle-updater [\#1730](https://github.com/chef/inspec/pull/1730) ([adamleff](https://github.com/adamleff))
|
|
43
|
+
- use cmp in port docs instead of eq [\#1726](https://github.com/chef/inspec/pull/1726) ([arlimus](https://github.com/arlimus))
|
|
44
|
+
- \[www\] update event on main page [\#1724](https://github.com/chef/inspec/pull/1724) ([adamleff](https://github.com/adamleff))
|
|
45
|
+
- rename SimpleConfig / parse\_config / parse\_config\_file options [\#1723](https://github.com/chef/inspec/pull/1723) ([arlimus](https://github.com/arlimus))
|
|
46
|
+
- Add matchers help to shell, clean up help output [\#1722](https://github.com/chef/inspec/pull/1722) ([adamleff](https://github.com/adamleff))
|
|
47
|
+
- provide `inspec.version` information [\#1719](https://github.com/chef/inspec/pull/1719) ([arlimus](https://github.com/arlimus))
|
|
48
|
+
- provide the `inspec` keyword [\#1718](https://github.com/chef/inspec/pull/1718) ([arlimus](https://github.com/arlimus))
|
|
49
|
+
- print and prettyprint the inspec backend class [\#1717](https://github.com/chef/inspec/pull/1717) ([arlimus](https://github.com/arlimus))
|
|
50
|
+
- describe the value ranges of `impact` [\#1713](https://github.com/chef/inspec/pull/1713) ([arlimus](https://github.com/arlimus))
|
|
51
|
+
- pretty-print multiline control descriptions [\#1711](https://github.com/chef/inspec/pull/1711) ([arlimus](https://github.com/arlimus))
|
|
52
|
+
- document reference to other tools [\#1710](https://github.com/chef/inspec/pull/1710) ([arlimus](https://github.com/arlimus))
|
|
53
|
+
- handle json parse errors in docker resource [\#1706](https://github.com/chef/inspec/pull/1706) ([chris-rock](https://github.com/chris-rock))
|
|
54
|
+
|
|
3
55
|
## [v1.21.0](https://github.com/chef/inspec/tree/v1.21.0) (2017-04-24)
|
|
4
56
|
[Full Changelog](https://github.com/chef/inspec/compare/v1.20.0...v1.21.0)
|
|
5
57
|
|
|
@@ -24,6 +76,7 @@
|
|
|
24
76
|
|
|
25
77
|
**Merged pull requests:**
|
|
26
78
|
|
|
79
|
+
- Release 1.21.0 [\#1703](https://github.com/chef/inspec/pull/1703) ([adamleff](https://github.com/adamleff))
|
|
27
80
|
- \[www\] Update www Gemfile.lock [\#1691](https://github.com/chef/inspec/pull/1691) ([adamleff](https://github.com/adamleff))
|
|
28
81
|
- showing how to shellout in docs [\#1689](https://github.com/chef/inspec/pull/1689) ([rshade](https://github.com/rshade))
|
|
29
82
|
- \[www\] Fix docs pages for x509\_certificate and key\_rsa [\#1683](https://github.com/chef/inspec/pull/1683) ([adamleff](https://github.com/adamleff))
|
data/README.md
CHANGED
|
@@ -308,6 +308,10 @@ Tutorials/Blogs/Podcasts:
|
|
|
308
308
|
|
|
309
309
|
* http://inspec.io/tutorials/
|
|
310
310
|
|
|
311
|
+
Relationship to other tools (RSpec, Serverspec):
|
|
312
|
+
|
|
313
|
+
* http://inspec.io/docs/reference/inspec_and_friends/
|
|
314
|
+
|
|
311
315
|
## Share your Profiles
|
|
312
316
|
|
|
313
317
|
You may share your InSpec Profiles in the [Tools & Plugins section](https://supermarket.chef.io/tools-directory) of the [Chef Supermarket](https://supermarket.chef.io/). [Sign in](https://supermarket.chef.io/sign-in) and [add the details of your profile](https://supermarket.chef.io/tools/new).
|
data/Rakefile
CHANGED
|
@@ -4,19 +4,26 @@
|
|
|
4
4
|
require 'bundler'
|
|
5
5
|
require 'bundler/gem_tasks'
|
|
6
6
|
require 'rake/testtask'
|
|
7
|
-
require 'rubocop/rake_task'
|
|
8
|
-
require_relative 'tasks/docs'
|
|
9
7
|
require_relative 'tasks/maintainers'
|
|
10
8
|
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
# The docs tasks rely on ruby-progressbar. If we can't load it, then don't
|
|
10
|
+
# load the docs tasks. This is necessary to allow this Rakefile to work
|
|
11
|
+
# when the "tests" gem group in the Gemfile has been excluded, such as
|
|
12
|
+
# during an appbundle-updater run.
|
|
13
|
+
begin
|
|
14
|
+
require 'ruby-progressbar'
|
|
15
|
+
require_relative 'tasks/docs'
|
|
16
|
+
rescue LoadError
|
|
17
|
+
puts 'docs tasks are unavailable because the ruby-progressbar gem is not available.'
|
|
15
18
|
end
|
|
16
19
|
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
# Rubocop
|
|
21
|
+
begin
|
|
22
|
+
require 'rubocop/rake_task'
|
|
23
|
+
RuboCop::RakeTask.new(:lint)
|
|
24
|
+
rescue LoadError
|
|
25
|
+
puts 'rubocop is not available. Install the rubocop gem to run the lint tests.'
|
|
26
|
+
end
|
|
20
27
|
|
|
21
28
|
# update command output for demo
|
|
22
29
|
desc 'Run inspec commands and save results to www/app/responses'
|
data/docs/dsl_inspec.md
CHANGED
|
@@ -44,7 +44,10 @@ where
|
|
|
44
44
|
|
|
45
45
|
* `'sshd-8'` is the name of the control
|
|
46
46
|
* `impact`, `title`, and `desc` define metadata that fully describes the importance of the control, its purpose, with a succinct and complete description
|
|
47
|
-
* `impact` is an float that measures the importance of the compliance results and must be a value between `0.0` and `1.0`.
|
|
47
|
+
* `impact` is an float that measures the importance of the compliance results and must be a value between `0.0` and `1.0`. The value ranges are:
|
|
48
|
+
* `0.0 to <0.4` these are controls with minor criticality
|
|
49
|
+
* `0.4 to <0.7` these are controls with major criticality
|
|
50
|
+
* `0.7 to 1.0` these are critical controls
|
|
48
51
|
* `tag` is optional meta-information with with key or key-value pairs
|
|
49
52
|
* `ref` is a reference to an external document
|
|
50
53
|
* `describe` is a block that contains at least one test. A `control` block must contain at least one `describe` block, but may contain as many as required
|
data/docs/inspec_and_friends.md
CHANGED
|
@@ -42,7 +42,7 @@ end
|
|
|
42
42
|
|
|
43
43
|
## Serverspec
|
|
44
44
|
|
|
45
|
-
Serverspec
|
|
45
|
+
Serverspec is the first extension of RSpec that enabled
|
|
46
46
|
users to run RSpec tests on servers to verify deployed artifacts. It was
|
|
47
47
|
created in March 2013 by Gosuke Miyashita and has been widely adopted.
|
|
48
48
|
It is also one of the core test frameworks within test-kitchen and has
|
|
@@ -60,7 +60,9 @@ Lessons learned from Serverspec include:
|
|
|
60
60
|
* Support for Windows is a first-class requirement.
|
|
61
61
|
* A command line interface (CLI) is required for faster iteration of test code.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
You can also watch this [podcast](http://foodfightshow.org/2016/02/inspec.html) to find out more on the relationship of InSpec and Serverspec.
|
|
64
|
+
|
|
65
|
+
### How is InSpec different from Serverspec
|
|
64
66
|
|
|
65
67
|
One of the key differences is that InSpec targets more user groups. It
|
|
66
68
|
is optimized for DevOps, Security, and Compliance professionals.
|
|
@@ -20,7 +20,7 @@ or:
|
|
|
20
20
|
|
|
21
21
|
audit = command('/sbin/auditctl -l').stdout
|
|
22
22
|
options = {
|
|
23
|
-
|
|
23
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
24
24
|
multiple_values: true
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -39,15 +39,15 @@ where each test
|
|
|
39
39
|
|
|
40
40
|
This InSpec audit resource has the following matchers:
|
|
41
41
|
|
|
42
|
-
###
|
|
42
|
+
### assignment_regex
|
|
43
43
|
|
|
44
|
-
Use `
|
|
44
|
+
Use `assignment_regex` to test a key value using a regular expression:
|
|
45
45
|
|
|
46
46
|
'key = value'
|
|
47
47
|
|
|
48
48
|
may be tested using the following regular expression, which determines assignment from key to value:
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*(.*?)\s*$/
|
|
51
51
|
|
|
52
52
|
### be
|
|
53
53
|
|
|
@@ -71,15 +71,15 @@ Use `comment_char` to test for comments in a configuration file:
|
|
|
71
71
|
|
|
72
72
|
<%= partial "/shared/matcher_include" %>
|
|
73
73
|
|
|
74
|
-
###
|
|
74
|
+
### key_values
|
|
75
75
|
|
|
76
|
-
Use `
|
|
76
|
+
Use `key_values` to test how many values a key contains:
|
|
77
77
|
|
|
78
78
|
key = a b c
|
|
79
79
|
|
|
80
80
|
contains three values. To test that value to ensure it only contains one, use:
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
key_values: 1
|
|
83
83
|
|
|
84
84
|
### match
|
|
85
85
|
|
|
@@ -17,7 +17,7 @@ A `parse_config_file` InSpec audit resource block declares the location of the c
|
|
|
17
17
|
or:
|
|
18
18
|
|
|
19
19
|
options = {
|
|
20
|
-
|
|
20
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
21
21
|
multiple_values: true
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -37,7 +37,7 @@ where each test
|
|
|
37
37
|
This resource supports the following options for parsing configuration data. Use them in an `options` block stated outside of (and immediately before) the actual test:
|
|
38
38
|
|
|
39
39
|
options = {
|
|
40
|
-
|
|
40
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
41
41
|
multiple_values: true
|
|
42
42
|
}
|
|
43
43
|
describe parse_config_file('path/to/file', options) do
|
|
@@ -48,15 +48,15 @@ This resource supports the following options for parsing configuration data. Use
|
|
|
48
48
|
|
|
49
49
|
This InSpec audit resource has the following matchers:
|
|
50
50
|
|
|
51
|
-
###
|
|
51
|
+
### assignment_regex
|
|
52
52
|
|
|
53
|
-
Use `
|
|
53
|
+
Use `assignment_regex` to test a key value using a regular expression:
|
|
54
54
|
|
|
55
55
|
'key = value'
|
|
56
56
|
|
|
57
57
|
may be tested using the following regular expression, which determines assignment from key to value:
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*(.*?)\s*$/
|
|
60
60
|
|
|
61
61
|
### be
|
|
62
62
|
|
|
@@ -80,15 +80,15 @@ Use `comment_char` to test for comments in a configuration file:
|
|
|
80
80
|
|
|
81
81
|
<%= partial "/shared/matcher_include" %>
|
|
82
82
|
|
|
83
|
-
###
|
|
83
|
+
### key_values
|
|
84
84
|
|
|
85
|
-
Use `
|
|
85
|
+
Use `key_values` to test how many values a key contains:
|
|
86
86
|
|
|
87
87
|
key = a b c
|
|
88
88
|
|
|
89
89
|
contains three values. To test that value to ensure it only contains one, use:
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
key_values: 1
|
|
92
92
|
|
|
93
93
|
### match
|
|
94
94
|
|
data/docs/resources/port.md.erb
CHANGED
|
@@ -75,13 +75,13 @@ The `be_listening` matcher tests if the port is listening for traffic:
|
|
|
75
75
|
|
|
76
76
|
The `pids` matcher tests the process identifiers (PIDs):
|
|
77
77
|
|
|
78
|
-
its('pids') { should
|
|
78
|
+
its('pids') { should cmp 27808 }
|
|
79
79
|
|
|
80
80
|
### processes
|
|
81
81
|
|
|
82
82
|
The `processes` matcher tests if the named process is running on the system:
|
|
83
83
|
|
|
84
|
-
its('processes') { should
|
|
84
|
+
its('processes') { should cmp 'syslog' }
|
|
85
85
|
|
|
86
86
|
### protocols
|
|
87
87
|
|
|
@@ -101,7 +101,7 @@ The following examples show how to use this InSpec audit resource.
|
|
|
101
101
|
|
|
102
102
|
describe port(80) do
|
|
103
103
|
it { should be_listening }
|
|
104
|
-
its('protocols') {should
|
|
104
|
+
its('protocols') { should cmp 'tcp' }
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
### Test port 80, on a specific address
|
|
@@ -123,7 +123,7 @@ or:
|
|
|
123
123
|
|
|
124
124
|
describe port(80) do
|
|
125
125
|
it { should be_listening }
|
|
126
|
-
its('protocols') {should
|
|
126
|
+
its('protocols') { should cmp 'tcp6' }
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
### Test that only secure ports accept requests
|
|
@@ -134,7 +134,7 @@ or:
|
|
|
134
134
|
|
|
135
135
|
describe port(443) do
|
|
136
136
|
it { should be_listening }
|
|
137
|
-
its('protocols') {should
|
|
137
|
+
its('protocols') { should cmp 'tcp' }
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
### Verify port 65432 is not listening
|
data/lib/inspec/backend.rb
CHANGED
|
@@ -26,9 +26,27 @@ module Inspec
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
cls = Class.new do
|
|
29
|
+
# Ruby internal for printing a nice name for this class
|
|
30
|
+
def to_s
|
|
31
|
+
'Inspec::Backend::Class'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Ruby internal for pretty-printing a summary for this class
|
|
35
|
+
def inspect
|
|
36
|
+
"Inspec::Backend::Class @transport=#{backend.class}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Provide a shorthand to retrieve the inspec version from within a profile
|
|
40
|
+
#
|
|
41
|
+
# @return [String] inspec version
|
|
42
|
+
def version
|
|
43
|
+
Inspec::VERSION
|
|
44
|
+
end
|
|
45
|
+
|
|
29
46
|
define_method :backend do
|
|
30
47
|
connection
|
|
31
48
|
end
|
|
49
|
+
|
|
32
50
|
Inspec::Resource.registry.each do |id, r|
|
|
33
51
|
define_method id.to_sym do |*args|
|
|
34
52
|
r.new(self, id.to_s, *args)
|
|
@@ -23,7 +23,7 @@ module Inspec
|
|
|
23
23
|
def to_ruby
|
|
24
24
|
res = ["control #{id.inspect} do"]
|
|
25
25
|
res.push " title #{title.inspect}" unless title.to_s.empty?
|
|
26
|
-
res.push " desc #{desc
|
|
26
|
+
res.push " desc #{prettyprint_text(desc, 2)}" unless desc.to_s.empty?
|
|
27
27
|
res.push " impact #{impact}" unless impact.nil?
|
|
28
28
|
tags.each { |t| res.push(indent(t.to_ruby, 2)) }
|
|
29
29
|
tests.each { |t| res.push(indent(t.to_ruby, 2)) }
|
|
@@ -33,6 +33,18 @@ module Inspec
|
|
|
33
33
|
|
|
34
34
|
private
|
|
35
35
|
|
|
36
|
+
# Pretty-print a text block of InSpec code
|
|
37
|
+
#
|
|
38
|
+
# @param s [String] should not be empty
|
|
39
|
+
# @param depth [Int] indentation length for multiline text blocks
|
|
40
|
+
# @return [String] pretty-printed textblock
|
|
41
|
+
def prettyprint_text(s, depth)
|
|
42
|
+
txt = s.to_s.inspect.gsub('\n', "\n")
|
|
43
|
+
return txt if !txt.include?("\n")
|
|
44
|
+
middle = indent(txt[1..-2], depth+2)
|
|
45
|
+
txt[0] + "\n" + middle + "\n" + ' '*depth + txt[-1]
|
|
46
|
+
end
|
|
47
|
+
|
|
36
48
|
def indent(txt, d)
|
|
37
49
|
dt = ' '*d
|
|
38
50
|
dt + txt.gsub("\n", "\n"+dt)
|
data/lib/inspec/resource.rb
CHANGED
data/lib/inspec/rule.rb
CHANGED
|
@@ -231,16 +231,22 @@ module Inspec
|
|
|
231
231
|
end
|
|
232
232
|
end
|
|
233
233
|
|
|
234
|
-
# Idio(ma)tic unindent
|
|
235
|
-
#
|
|
234
|
+
# Idio(ma)tic unindent, behaves similar to Ruby2.3 curly heredocs.
|
|
235
|
+
# Find the shortest indentation of non-empty lines and strip that from every line
|
|
236
|
+
# See: https://bugs.ruby-lang.org/issues/9098
|
|
237
|
+
#
|
|
238
|
+
# It is implemented here to support pre-Ruby2.3 with this feature and
|
|
239
|
+
# to not force non-programmers to understand heredocs.
|
|
240
|
+
#
|
|
241
|
+
# Please note: tabs are not supported! (they will be removed but they are not
|
|
242
|
+
# treated the same as in Ruby2.3 heredocs)
|
|
236
243
|
#
|
|
237
244
|
# @param [String] text string which needs to be unindented
|
|
238
|
-
# @return [String] input with indentation removed
|
|
245
|
+
# @return [String] input with indentation removed; '' if input is nil
|
|
239
246
|
def unindent(text)
|
|
240
247
|
return '' if text.nil?
|
|
241
|
-
text.
|
|
242
|
-
|
|
243
|
-
.join(' ')
|
|
248
|
+
len = text.split("\n").reject { |l| l.strip.empty? }.map { |x| x.index(/[^\s]/) }.compact.min
|
|
249
|
+
text.gsub(/^[[:blank:]]{#{len}}/, '').strip
|
|
244
250
|
end
|
|
245
251
|
|
|
246
252
|
# get the rule's source code
|
data/lib/inspec/shell.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Inspec
|
|
|
9
9
|
# A pry based shell for inspec. Given a runner (with a configured backend and
|
|
10
10
|
# all that jazz), this shell will produce a pry shell from which you can run
|
|
11
11
|
# inspec/ruby commands that will be run within the context of the runner.
|
|
12
|
-
class Shell
|
|
12
|
+
class Shell # rubocop:disable Metrics/ClassLength
|
|
13
13
|
def initialize(runner)
|
|
14
14
|
@runner = runner
|
|
15
15
|
end
|
|
@@ -107,8 +107,8 @@ You are currently running on:
|
|
|
107
107
|
EOF
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
def help(
|
|
111
|
-
if
|
|
110
|
+
def help(topic = nil)
|
|
111
|
+
if topic.nil?
|
|
112
112
|
|
|
113
113
|
puts <<EOF
|
|
114
114
|
|
|
@@ -117,6 +117,7 @@ Available commands:
|
|
|
117
117
|
`[resource]` - run resource on target machine
|
|
118
118
|
`help resources` - show all available resources that can be used as commands
|
|
119
119
|
`help [resource]` - information about a specific resource
|
|
120
|
+
`help matchers` - show information about common matchers
|
|
120
121
|
`exit` - exit the InSpec shell
|
|
121
122
|
|
|
122
123
|
You can use resources in this environment to test the target machine. For example:
|
|
@@ -126,32 +127,94 @@ You can use resources in this environment to test the target machine. For exampl
|
|
|
126
127
|
|
|
127
128
|
#{print_target_info}
|
|
128
129
|
EOF
|
|
129
|
-
elsif
|
|
130
|
-
resources
|
|
131
|
-
|
|
130
|
+
elsif topic == 'resources'
|
|
131
|
+
resources.sort.each do |resource|
|
|
132
|
+
puts " - #{resource}"
|
|
133
|
+
end
|
|
134
|
+
elsif topic == 'matchers'
|
|
135
|
+
print_matchers_help
|
|
136
|
+
elsif !Inspec::Resource.registry[topic].nil?
|
|
132
137
|
puts <<EOF
|
|
133
|
-
#{mark 'Name:'} #{
|
|
138
|
+
#{mark 'Name:'} #{topic}
|
|
134
139
|
|
|
135
140
|
#{mark 'Description:'}
|
|
136
141
|
|
|
137
|
-
#{Inspec::Resource.registry[
|
|
142
|
+
#{Inspec::Resource.registry[topic].desc}
|
|
138
143
|
|
|
139
144
|
#{mark 'Example:'}
|
|
140
|
-
#{print_example(Inspec::Resource.registry[
|
|
145
|
+
#{print_example(Inspec::Resource.registry[topic].example)}
|
|
141
146
|
|
|
142
147
|
#{mark 'Web Reference:'}
|
|
143
148
|
|
|
144
|
-
http://inspec.io/docs/reference/resources/#{
|
|
149
|
+
http://inspec.io/docs/reference/resources/#{topic}
|
|
145
150
|
|
|
146
151
|
EOF
|
|
147
152
|
else
|
|
148
|
-
puts
|
|
149
|
-
resources
|
|
153
|
+
puts "The resource #{topic} does not exist. For a list of valid resources, type: help resources"
|
|
150
154
|
end
|
|
151
155
|
end
|
|
152
156
|
|
|
153
157
|
def resources
|
|
154
|
-
|
|
158
|
+
Inspec::Resource.registry.keys
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def print_matchers_help
|
|
162
|
+
puts <<-EOL
|
|
163
|
+
Matchers are used to compare resource values to expectations. While some
|
|
164
|
+
resources implement their own custom matchers, the following matchers are
|
|
165
|
+
common amongst all resources:
|
|
166
|
+
|
|
167
|
+
#{mark 'be'}
|
|
168
|
+
|
|
169
|
+
The #{mark 'be'} matcher can be used to compare numeric values.
|
|
170
|
+
|
|
171
|
+
its('size') { should be >= 10 }
|
|
172
|
+
|
|
173
|
+
#{mark 'cmp'}
|
|
174
|
+
|
|
175
|
+
The #{mark 'cmp'} matcher is like #{mark 'eq'} but less restrictive. It will try
|
|
176
|
+
to fit the resource value to the expectation.
|
|
177
|
+
|
|
178
|
+
"Protocol" likely returns a string, but cmp will ensure it's a number before
|
|
179
|
+
comparing:
|
|
180
|
+
|
|
181
|
+
its('Protocol') { should cmp 2 }
|
|
182
|
+
its('Protocol') { should cmp '2' }
|
|
183
|
+
|
|
184
|
+
"users" may return an array, but if it contains only one item, cmp will compare
|
|
185
|
+
it as a string or number as needed:
|
|
186
|
+
|
|
187
|
+
its('users') { should cmp 'root' }
|
|
188
|
+
|
|
189
|
+
cmp is not case-sensitive:
|
|
190
|
+
|
|
191
|
+
its('log_format') { should cmp 'raw' }
|
|
192
|
+
its('log_format') { should cmp 'RAW' }
|
|
193
|
+
|
|
194
|
+
#{mark 'eq'}
|
|
195
|
+
|
|
196
|
+
The #{mark 'eq'} matcher tests for exact equality of two values. Value type
|
|
197
|
+
(string, number, etc.) is important and must be the same. For a less-restrictive
|
|
198
|
+
comparison matcher, use the #{mark 'cmp'} matcher.
|
|
199
|
+
|
|
200
|
+
its('RSAAuthentication') { should_not eq 'no' }
|
|
201
|
+
|
|
202
|
+
#{mark 'include'}
|
|
203
|
+
|
|
204
|
+
The #{mark 'include'} matcher tests to see if a value is included in a list.
|
|
205
|
+
|
|
206
|
+
its('users') { should include 'my_user' }
|
|
207
|
+
|
|
208
|
+
#{mark 'match'}
|
|
209
|
+
|
|
210
|
+
The #{mark 'match'} matcher can be used to test a string for a match using a
|
|
211
|
+
regular expression.
|
|
212
|
+
|
|
213
|
+
its('content') { should_not match /^MyKey:\\s+some value/ }
|
|
214
|
+
|
|
215
|
+
For more examples, see: http://inspec.io/docs/reference/matchers/
|
|
216
|
+
|
|
217
|
+
EOL
|
|
155
218
|
end
|
|
156
219
|
end
|
|
157
220
|
end
|
data/lib/inspec/version.rb
CHANGED
|
@@ -12,7 +12,7 @@ module Inspec::Resources
|
|
|
12
12
|
def initialize(content)
|
|
13
13
|
@content = content
|
|
14
14
|
@opts = {
|
|
15
|
-
|
|
15
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
16
16
|
multiple_values: true,
|
|
17
17
|
}
|
|
18
18
|
end
|
|
@@ -27,7 +27,7 @@ module Inspec::Resources
|
|
|
27
27
|
|
|
28
28
|
def status(name)
|
|
29
29
|
@status_opts = {
|
|
30
|
-
|
|
30
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
31
31
|
multiple_values: false,
|
|
32
32
|
}
|
|
33
33
|
@status_content ||= inspec.command('/sbin/auditctl -s').stdout.chomp
|
data/lib/resources/bond.rb
CHANGED
|
@@ -28,7 +28,7 @@ module Inspec::Resources
|
|
|
28
28
|
@content = @file.content
|
|
29
29
|
@params = SimpleConfig.new(
|
|
30
30
|
@file.content,
|
|
31
|
-
|
|
31
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
32
32
|
multiple_values: true,
|
|
33
33
|
).params if @file.exist?
|
|
34
34
|
@loaded = true
|
data/lib/resources/docker.rb
CHANGED
|
@@ -109,12 +109,16 @@ module Inspec::Resources
|
|
|
109
109
|
return @version if defined?(@version)
|
|
110
110
|
data = JSON.parse(inspec.command('docker version --format \'{{ json . }}\'').stdout)
|
|
111
111
|
@version = Hashie::Mash.new(data)
|
|
112
|
+
rescue JSON::ParserError => _e
|
|
113
|
+
return Hashie::Mash.new({})
|
|
112
114
|
end
|
|
113
115
|
|
|
114
116
|
def info
|
|
115
117
|
return @info if defined?(@info)
|
|
116
118
|
data = JSON.parse(inspec.command('docker info --format \'{{ json . }}\'').stdout)
|
|
117
119
|
@info = Hashie::Mash.new(data)
|
|
120
|
+
rescue JSON::ParserError => _e
|
|
121
|
+
return Hashie::Mash.new({})
|
|
118
122
|
end
|
|
119
123
|
|
|
120
124
|
# returns information about docker objects
|
|
@@ -123,6 +127,8 @@ module Inspec::Resources
|
|
|
123
127
|
data = JSON.parse(inspec.command("docker inspect #{id}").stdout)
|
|
124
128
|
data = data[0] if data.is_a?(Array)
|
|
125
129
|
@inspect = Hashie::Mash.new(data)
|
|
130
|
+
rescue JSON::ParserError => _e
|
|
131
|
+
return Hashie::Mash.new({})
|
|
126
132
|
end
|
|
127
133
|
|
|
128
134
|
def to_s
|
|
@@ -144,6 +150,9 @@ module Inspec::Resources
|
|
|
144
150
|
ps.push(j)
|
|
145
151
|
}
|
|
146
152
|
ps
|
|
153
|
+
rescue JSON::ParserError => _e
|
|
154
|
+
warn 'Could not parse `docker ps` output'
|
|
155
|
+
[]
|
|
147
156
|
end
|
|
148
157
|
|
|
149
158
|
def parse_images
|
|
@@ -154,6 +163,9 @@ module Inspec::Resources
|
|
|
154
163
|
c_images.push(JSON.parse(entry))
|
|
155
164
|
}
|
|
156
165
|
c_images
|
|
166
|
+
rescue JSON::ParserError => _e
|
|
167
|
+
warn 'Could not parse `docker images` output'
|
|
168
|
+
[]
|
|
157
169
|
end
|
|
158
170
|
end
|
|
159
171
|
end
|
data/lib/resources/inetd_conf.rb
CHANGED
|
@@ -50,8 +50,8 @@ module Inspec::Resources
|
|
|
50
50
|
# parse the file
|
|
51
51
|
conf = SimpleConfig.new(
|
|
52
52
|
content,
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
assignment_regex: /^\s*(\S+?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$/,
|
|
54
|
+
key_values: 6,
|
|
55
55
|
multiple_values: false,
|
|
56
56
|
)
|
|
57
57
|
@params = conf.params
|
|
@@ -43,8 +43,8 @@ module Inspec::Resources
|
|
|
43
43
|
# parse the file
|
|
44
44
|
conf = SimpleConfig.new(
|
|
45
45
|
content,
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
assignment_regex: /^\s*(\S+?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$/,
|
|
47
|
+
key_values: 3,
|
|
48
48
|
multiple_values: true,
|
|
49
49
|
)
|
|
50
50
|
@params = conf.params
|
data/lib/resources/login_def.rb
CHANGED
data/lib/resources/ntp_conf.rb
CHANGED
data/lib/resources/package.rb
CHANGED
|
@@ -88,7 +88,7 @@ module Inspec::Resources
|
|
|
88
88
|
|
|
89
89
|
params = SimpleConfig.new(
|
|
90
90
|
cmd.stdout.chomp,
|
|
91
|
-
|
|
91
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
92
92
|
multiple_values: false,
|
|
93
93
|
).params
|
|
94
94
|
# If the package is removed and not purged, Status is "deinstall ok config-files" with exit_status 0
|
|
@@ -111,7 +111,7 @@ module Inspec::Resources
|
|
|
111
111
|
return nil if cmd.exit_status.to_i != 0 || cmd.stdout.chomp.empty?
|
|
112
112
|
params = SimpleConfig.new(
|
|
113
113
|
cmd.stdout.chomp,
|
|
114
|
-
|
|
114
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
115
115
|
multiple_values: false,
|
|
116
116
|
).params
|
|
117
117
|
# On some (all?) systems, the linebreak before the vendor line is missing
|
|
@@ -161,7 +161,7 @@ module Inspec::Resources
|
|
|
161
161
|
|
|
162
162
|
params = SimpleConfig.new(
|
|
163
163
|
cmd.stdout.chomp,
|
|
164
|
-
|
|
164
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
165
165
|
multiple_values: false,
|
|
166
166
|
).params
|
|
167
167
|
|
|
@@ -261,7 +261,7 @@ module Inspec::Resources
|
|
|
261
261
|
|
|
262
262
|
params = SimpleConfig.new(
|
|
263
263
|
cmd.stdout.chomp,
|
|
264
|
-
|
|
264
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
265
265
|
multiple_values: false,
|
|
266
266
|
).params
|
|
267
267
|
|
|
@@ -282,7 +282,7 @@ module Inspec::Resources
|
|
|
282
282
|
|
|
283
283
|
params = SimpleConfig.new(
|
|
284
284
|
cmd.stdout.chomp,
|
|
285
|
-
|
|
285
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
286
286
|
multiple_values: false,
|
|
287
287
|
).params
|
|
288
288
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
#
|
|
9
9
|
# audit = command('/sbin/auditctl -l').stdout
|
|
10
10
|
# options = {
|
|
11
|
-
#
|
|
11
|
+
# assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
12
12
|
# multiple_values: true
|
|
13
13
|
# }
|
|
14
14
|
# describe parse_config(audit, options ) do
|
|
@@ -26,7 +26,7 @@ module Inspec::Resources
|
|
|
26
26
|
output2 = command('curl http://127.0.0.1/php_status').stdout
|
|
27
27
|
# php status is in format 'key : value', and we do not allow for multiple values
|
|
28
28
|
options2 = {
|
|
29
|
-
|
|
29
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
30
30
|
multiple_values: false
|
|
31
31
|
}
|
|
32
32
|
|
data/lib/resources/pip.rb
CHANGED
|
@@ -75,7 +75,7 @@ module Inspec::Resources
|
|
|
75
75
|
@content += raw_conf
|
|
76
76
|
|
|
77
77
|
opts = {
|
|
78
|
-
|
|
78
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*[']?\s*(.*?)\s*[']?\s*$/,
|
|
79
79
|
}
|
|
80
80
|
params = SimpleConfig.new(raw_conf, opts).params
|
|
81
81
|
@params.merge!(params)
|
data/lib/resources/service.rb
CHANGED
|
@@ -262,7 +262,7 @@ module Inspec::Resources
|
|
|
262
262
|
# parse data
|
|
263
263
|
params = SimpleConfig.new(
|
|
264
264
|
cmd.stdout.chomp,
|
|
265
|
-
|
|
265
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*(.*?)\s*$/,
|
|
266
266
|
multiple_values: false,
|
|
267
267
|
).params
|
|
268
268
|
|
|
@@ -637,7 +637,7 @@ module Inspec::Resources
|
|
|
637
637
|
|
|
638
638
|
params = SimpleConfig.new(
|
|
639
639
|
cmd.stdout.chomp,
|
|
640
|
-
|
|
640
|
+
assignment_regex: /^(\w+)\s*(.*)$/,
|
|
641
641
|
multiple_values: false,
|
|
642
642
|
).params
|
|
643
643
|
|
data/lib/resources/ssh_conf.rb
CHANGED
|
@@ -76,7 +76,7 @@ module Inspec::Resources
|
|
|
76
76
|
return @params = {} if read_content.nil?
|
|
77
77
|
conf = SimpleConfig.new(
|
|
78
78
|
read_content,
|
|
79
|
-
|
|
79
|
+
assignment_regex: /^\s*(\S+?)\s+(.*?)\s*$/,
|
|
80
80
|
multiple_values: true,
|
|
81
81
|
)
|
|
82
82
|
@params = convert_hash(conf.params)
|
data/lib/resources/users.rb
CHANGED
|
@@ -358,7 +358,7 @@ module Inspec::Resources
|
|
|
358
358
|
SimpleConfig.new(
|
|
359
359
|
line,
|
|
360
360
|
line_separator: ',',
|
|
361
|
-
|
|
361
|
+
assignment_regex: /^\s*([^\(]*?)\s*\(\s*(.*?)\)*$/,
|
|
362
362
|
group_re: nil,
|
|
363
363
|
multiple_values: false,
|
|
364
364
|
).params
|
|
@@ -372,7 +372,7 @@ module Inspec::Resources
|
|
|
372
372
|
# parse words
|
|
373
373
|
params = SimpleConfig.new(
|
|
374
374
|
parse_id_entries(cmd.stdout.chomp),
|
|
375
|
-
|
|
375
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*(.*?)\s*$/,
|
|
376
376
|
group_re: nil,
|
|
377
377
|
multiple_values: false,
|
|
378
378
|
).params
|
|
@@ -419,7 +419,7 @@ module Inspec::Resources
|
|
|
419
419
|
|
|
420
420
|
params = SimpleConfig.new(
|
|
421
421
|
cmd.stdout.chomp,
|
|
422
|
-
|
|
422
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
423
423
|
group_re: nil,
|
|
424
424
|
multiple_values: false,
|
|
425
425
|
).params
|
|
@@ -512,7 +512,7 @@ module Inspec::Resources
|
|
|
512
512
|
|
|
513
513
|
params = SimpleConfig.new(
|
|
514
514
|
cmd.stdout.chomp,
|
|
515
|
-
|
|
515
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
516
516
|
group_re: nil,
|
|
517
517
|
multiple_values: false,
|
|
518
518
|
).params
|
data/lib/utils/simpleconfig.rb
CHANGED
|
@@ -55,16 +55,28 @@ class SimpleConfig
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def parse_params_line(line, opts)
|
|
58
|
+
# Deprecation handling
|
|
59
|
+
if opts.key?(:assignment_re)
|
|
60
|
+
warn '[DEPRECATION] `:assignment_re` is deprecated in favor of `:assignment_regex` '\
|
|
61
|
+
'and will be removed in the next major version. See: https://github.com/chef/inspec/issues/1709'
|
|
62
|
+
opts[:assignment_regex] = opts[:assignment_re]
|
|
63
|
+
end
|
|
64
|
+
if opts.key?(:key_vals)
|
|
65
|
+
warn '[DEPRECATION] `:key_vals` is deprecated in favor of `:key_values` '\
|
|
66
|
+
'and will be removed in the next major version. See: https://github.com/chef/inspec/issues/1709'
|
|
67
|
+
opts[:key_values] = opts[:key_vals]
|
|
68
|
+
end
|
|
69
|
+
|
|
58
70
|
# now line contains what we are interested in parsing
|
|
59
71
|
# check if it is an assignment
|
|
60
|
-
m = opts[:
|
|
72
|
+
m = opts[:assignment_regex].match(line)
|
|
61
73
|
return nil if m.nil?
|
|
62
74
|
|
|
63
75
|
if opts[:multiple_values]
|
|
64
76
|
@vals[m[1]] ||= []
|
|
65
|
-
@vals[m[1]].push(parse_values(m, opts[:
|
|
77
|
+
@vals[m[1]].push(parse_values(m, opts[:key_values]))
|
|
66
78
|
else
|
|
67
|
-
@vals[m[1]] = parse_values(m, opts[:
|
|
79
|
+
@vals[m[1]] = parse_values(m, opts[:key_values])
|
|
68
80
|
end
|
|
69
81
|
end
|
|
70
82
|
|
|
@@ -111,9 +123,9 @@ class SimpleConfig
|
|
|
111
123
|
multiline: false,
|
|
112
124
|
comment_char: '#',
|
|
113
125
|
line_separator: nil, # uses this char to seperate lines before parsing
|
|
114
|
-
|
|
126
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*(.*?)\s*$/,
|
|
115
127
|
group_re: /\[([^\]]+)\]\s*$/,
|
|
116
|
-
|
|
128
|
+
key_values: 1, # default for key=value, may require for 'key val1 val2 val3'
|
|
117
129
|
standalone_comments: false,
|
|
118
130
|
multiple_values: false,
|
|
119
131
|
}
|
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.22.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-04-
|
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: train
|