inspec 0.20.1 → 0.21.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 +45 -2
- data/docs/dsl_inspec.rst +2 -2
- data/docs/resources.rst +9 -9
- data/docs/ruby_usage.rst +145 -0
- data/inspec.gemspec +1 -0
- data/lib/bundles/inspec-compliance/cli.rb +15 -2
- data/lib/inspec/cli.rb +23 -10
- data/lib/inspec/dsl.rb +0 -52
- data/lib/inspec/objects/or_test.rb +1 -0
- data/lib/inspec/objects/test.rb +4 -4
- data/lib/inspec/profile.rb +76 -61
- data/lib/inspec/profile_context.rb +12 -11
- data/lib/inspec/rspec_json_formatter.rb +93 -40
- data/lib/inspec/rule.rb +7 -29
- data/lib/inspec/runner.rb +15 -4
- data/lib/inspec/runner_mock.rb +1 -1
- data/lib/inspec/runner_rspec.rb +26 -24
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +3 -3
- data/lib/resources/auditd_rules.rb +2 -2
- data/lib/resources/host.rb +1 -1
- data/lib/resources/interface.rb +1 -1
- data/lib/resources/kernel_parameter.rb +1 -1
- data/lib/resources/mount.rb +2 -1
- data/lib/resources/mysql_session.rb +1 -1
- data/lib/resources/os_env.rb +2 -2
- data/lib/resources/passwd.rb +33 -93
- data/lib/resources/port.rb +47 -3
- data/lib/resources/processes.rb +3 -3
- data/lib/resources/service.rb +33 -1
- data/lib/resources/user.rb +15 -15
- data/lib/utils/base_cli.rb +1 -3
- data/lib/utils/filter.rb +30 -7
- data/test/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +4 -0
- data/test/functional/helper.rb +1 -0
- data/test/functional/inheritance_test.rb +1 -1
- data/test/functional/inspec_compliance_test.rb +4 -3
- data/test/functional/inspec_exec_json_test.rb +122 -0
- data/test/functional/inspec_exec_test.rb +23 -117
- data/test/functional/{inspec_json_test.rb → inspec_json_profile_test.rb} +13 -15
- data/test/functional/inspec_test.rb +15 -2
- data/test/helper.rb +5 -1
- data/test/integration/default/auditd_rules_spec.rb +3 -3
- data/test/integration/default/kernel_parameter_spec.rb +6 -6
- data/test/integration/default/service_spec.rb +4 -0
- data/test/resource/command_test.rb +9 -9
- data/test/resource/dsl_test.rb +1 -1
- data/test/resource/file_test.rb +17 -17
- data/test/unit/control_test.rb +1 -1
- data/test/unit/mock/cmd/hpux-netstat-inet +10 -0
- data/test/unit/mock/cmd/hpux-netstat-inet6 +11 -0
- data/test/unit/mock/profiles/skippy-profile-os/controls/one.rb +1 -1
- data/test/unit/profile_context_test.rb +2 -2
- data/test/unit/profile_test.rb +11 -14
- data/test/unit/resources/passwd_test.rb +13 -14
- data/test/unit/resources/port_test.rb +14 -0
- data/test/unit/resources/processes_test.rb +3 -3
- data/test/unit/resources/service_test.rb +103 -39
- data/test/unit/utils/filter_table_test.rb +35 -3
- metadata +25 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 609dd579538c5f1f9a4f86acf691fee0270ad878
|
4
|
+
data.tar.gz: c4d6ae9ca27a55efca499a37ee70d71c50e2ff42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29a47097ef98d5ddafc0c145bfff580ac74762538e3de8ef9d5730e210f0a76a478d084acf344f3668b946bee98c03102f8248d4d0632bcc12b5d94cf574b3e9
|
7
|
+
data.tar.gz: 65fb88edad1729f9968024c37e9466824d467f290c14f233ca87e70e1792d96cac3a37d9cd36ec2177ac0a64e7f0038225d38911183525e74c4ad23374f68472
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,46 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v0.20.
|
3
|
+
## [0.21.0](https://github.com/chef/inspec/tree/0.21.0) (2016-05-10)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.20.1...0.21.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Support nested describe.one blocks [\#711](https://github.com/chef/inspec/issues/711)
|
9
|
+
- inspec exec format json backtrace [\#614](https://github.com/chef/inspec/issues/614)
|
10
|
+
- Improve error output for compliance plugin [\#544](https://github.com/chef/inspec/issues/544)
|
11
|
+
- Cryptic error output if authentication with Chef Compliance fails [\#489](https://github.com/chef/inspec/issues/489)
|
12
|
+
- How to access the impact of a test failure? [\#377](https://github.com/chef/inspec/issues/377)
|
13
|
+
- Optimize InSpec detect [\#300](https://github.com/chef/inspec/issues/300)
|
14
|
+
- document output and/or expected results [\#210](https://github.com/chef/inspec/issues/210)
|
15
|
+
- Remove redundant space when missing expectation [\#724](https://github.com/chef/inspec/pull/724) ([alexpop](https://github.com/alexpop))
|
16
|
+
- Provide service params [\#721](https://github.com/chef/inspec/pull/721) ([alexpop](https://github.com/alexpop))
|
17
|
+
- api: make processes return integers for pid/vsz/rss [\#717](https://github.com/chef/inspec/pull/717) ([arlimus](https://github.com/arlimus))
|
18
|
+
- Expose systemd service properties via .info [\#715](https://github.com/chef/inspec/pull/715) ([alexpop](https://github.com/alexpop))
|
19
|
+
- Use only strings in resource examples, docs and tests [\#708](https://github.com/chef/inspec/pull/708) ([alexpop](https://github.com/alexpop))
|
20
|
+
- use filtertable with passwd resource [\#699](https://github.com/chef/inspec/pull/699) ([arlimus](https://github.com/arlimus))
|
21
|
+
- show error if user is not logged in to compliance server [\#696](https://github.com/chef/inspec/pull/696) ([chris-rock](https://github.com/chris-rock))
|
22
|
+
- JSON formatter redesign [\#671](https://github.com/chef/inspec/pull/671) ([arlimus](https://github.com/arlimus))
|
23
|
+
|
24
|
+
**Fixed bugs:**
|
25
|
+
|
26
|
+
- bugfix: handle train errors in inspec execution [\#705](https://github.com/chef/inspec/pull/705) ([arlimus](https://github.com/arlimus))
|
27
|
+
|
28
|
+
**Closed issues:**
|
29
|
+
|
30
|
+
- How do I inherit a profile from another profile? [\#691](https://github.com/chef/inspec/issues/691)
|
31
|
+
- How do I download a profile from a compliance server? [\#690](https://github.com/chef/inspec/issues/690)
|
32
|
+
- inspec compliance login fails [\#689](https://github.com/chef/inspec/issues/689)
|
33
|
+
|
34
|
+
**Merged pull requests:**
|
35
|
+
|
36
|
+
- inspec detect learns human-readable output [\#720](https://github.com/chef/inspec/pull/720) ([chris-rock](https://github.com/chris-rock))
|
37
|
+
- Add documentation on how to use ruby [\#718](https://github.com/chef/inspec/pull/718) ([alexpop](https://github.com/alexpop))
|
38
|
+
- export \#tests\(\) from OrTest object [\#714](https://github.com/chef/inspec/pull/714) ([arlimus](https://github.com/arlimus))
|
39
|
+
- use strings instead of symbols [\#707](https://github.com/chef/inspec/pull/707) ([vjeffrey](https://github.com/vjeffrey))
|
40
|
+
- hpux support for basic port properties [\#706](https://github.com/chef/inspec/pull/706) ([Anirudh-Gupta](https://github.com/Anirudh-Gupta))
|
41
|
+
|
42
|
+
## [v0.20.1](https://github.com/chef/inspec/tree/v0.20.1) (2016-04-30)
|
43
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.20.0...v0.20.1)
|
5
44
|
|
6
45
|
**Implemented enhancements:**
|
7
46
|
|
@@ -11,6 +50,10 @@
|
|
11
50
|
|
12
51
|
- fix appveyor caching [\#700](https://github.com/chef/inspec/pull/700) ([arlimus](https://github.com/arlimus))
|
13
52
|
|
53
|
+
**Merged pull requests:**
|
54
|
+
|
55
|
+
- 0.20.1 [\#702](https://github.com/chef/inspec/pull/702) ([alexpop](https://github.com/alexpop))
|
56
|
+
|
14
57
|
## [v0.20.0](https://github.com/chef/inspec/tree/v0.20.0) (2016-04-29)
|
15
58
|
[Full Changelog](https://github.com/chef/inspec/compare/v0.19.3...v0.20.0)
|
16
59
|
|
data/docs/dsl_inspec.rst
CHANGED
@@ -117,7 +117,7 @@ The following test shows how to audit machines running |mysql| to ensure that pa
|
|
117
117
|
them to an attacker. Prevent this at all costs.
|
118
118
|
'
|
119
119
|
describe command('env') do
|
120
|
-
its(
|
120
|
+
its('stdout') { should_not match(/^MYSQL_PWD=/) }
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
@@ -232,7 +232,7 @@ The following example illustrates various ways to add tags and references to `co
|
|
232
232
|
.. |inspec resource| replace:: InSpec Resource
|
233
233
|
.. |chef compliance| replace:: Chef Compliance
|
234
234
|
.. |ruby| replace:: Ruby
|
235
|
-
.. |
|
235
|
+
.. |ssh| replace:: SSH
|
236
236
|
.. |windows| replace:: Microsoft Windows
|
237
237
|
.. |postgresql| replace:: PostgreSQL
|
238
238
|
.. |apache| replace:: Apache
|
data/docs/resources.rst
CHANGED
@@ -364,7 +364,7 @@ The following examples show how to use this InSpec audit resource.
|
|
364
364
|
|
365
365
|
# syntax for auditd >= 2.3
|
366
366
|
describe auditd_rules do
|
367
|
-
its(
|
367
|
+
its('lines') { should contain_match(%r{-w /etc/ssh/sshd_config/}) }
|
368
368
|
end
|
369
369
|
|
370
370
|
The syntax for recent auditd versions allows more precise tests, such as the following:
|
@@ -386,7 +386,7 @@ The syntax for recent auditd versions allows more precise tests, such as the fol
|
|
386
386
|
end
|
387
387
|
|
388
388
|
describe auditd_rules.key('sshd_config') do
|
389
|
-
its(
|
389
|
+
its('permissions') { should contain_match(/x/) }
|
390
390
|
end
|
391
391
|
|
392
392
|
Note that filters can be chained, for example:
|
@@ -2045,7 +2045,7 @@ The following examples show how to use this InSpec audit resource.
|
|
2045
2045
|
.. code-block:: ruby
|
2046
2046
|
|
2047
2047
|
describe kernel_parameter('net.ipv4.conf.all.forwarding') do
|
2048
|
-
its(
|
2048
|
+
its('value') { should eq 1 }
|
2049
2049
|
end
|
2050
2050
|
|
2051
2051
|
**Test if global forwarding is disabled for an IPv6 address**
|
@@ -2053,7 +2053,7 @@ The following examples show how to use this InSpec audit resource.
|
|
2053
2053
|
.. code-block:: ruby
|
2054
2054
|
|
2055
2055
|
describe kernel_parameter('net.ipv6.conf.all.forwarding') do
|
2056
|
-
its(
|
2056
|
+
its('value') { should eq 0 }
|
2057
2057
|
end
|
2058
2058
|
|
2059
2059
|
**Test if an IPv6 address accepts redirects**
|
@@ -2061,7 +2061,7 @@ The following examples show how to use this InSpec audit resource.
|
|
2061
2061
|
.. code-block:: ruby
|
2062
2062
|
|
2063
2063
|
describe kernel_parameter('net.ipv6.conf.interface.accept_redirects') do
|
2064
|
-
its(
|
2064
|
+
its('value') { should eq 'true' }
|
2065
2065
|
end
|
2066
2066
|
|
2067
2067
|
|
@@ -2417,7 +2417,7 @@ The following examples show how to use this InSpec audit resource.
|
|
2417
2417
|
|
2418
2418
|
sql = mysql_session('my_user','password')
|
2419
2419
|
describe sql.query('show databases like \'test\';') do
|
2420
|
-
its(
|
2420
|
+
its('stdout') { should_not match(/test/) }
|
2421
2421
|
end
|
2422
2422
|
|
2423
2423
|
|
@@ -3148,12 +3148,12 @@ A ``passwd`` |inspec resource| block declares one (or more) users and associated
|
|
3148
3148
|
.. code-block:: ruby
|
3149
3149
|
|
3150
3150
|
describe passwd do
|
3151
|
-
its(
|
3151
|
+
its('users') { should_not include 'forbidden_user' }
|
3152
3152
|
end
|
3153
3153
|
|
3154
3154
|
describe passwd.uid(0) do
|
3155
|
-
its(
|
3156
|
-
its(
|
3155
|
+
its('users') { should cmp 'root' }
|
3156
|
+
its('count') { should eq 1 }
|
3157
3157
|
end
|
3158
3158
|
|
3159
3159
|
where
|
data/docs/ruby_usage.rst
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
=====================================================
|
2
|
+
Using |ruby| in InSpec
|
3
|
+
=====================================================
|
4
|
+
|
5
|
+
The |inspec| DSL is a |ruby| based DSL for writing audit controls, which includes audit resources that you can invoke.
|
6
|
+
Core and custom resources are written as regular |ruby| classes which inherit from ``Inspec.resource``.
|
7
|
+
|
8
|
+
Assuming we have a |json| file like this on the node to be tested:
|
9
|
+
|
10
|
+
.. code-block:: json
|
11
|
+
|
12
|
+
{
|
13
|
+
"keys":[
|
14
|
+
{"username":"john", "key":"/opt/keys/johnd.key"},
|
15
|
+
{"username":"jane", "key":"/opt/keys/janed.key"},
|
16
|
+
{"username":"sunny ", "key":"/opt/keys/sunnym.key"}
|
17
|
+
]
|
18
|
+
}
|
19
|
+
|
20
|
+
The following example shows how you can use pure |ruby| code(variables, loops, conditionals, regular expressions, etc) to run a few tests against the above |json| file:
|
21
|
+
|
22
|
+
.. code-block:: ruby
|
23
|
+
|
24
|
+
control 'check-interns' do
|
25
|
+
# use the json inspec resource to get the file
|
26
|
+
json_obj = json('/opt/keys/interns.json')
|
27
|
+
describe json_obj do
|
28
|
+
its('keys') { should_not eq nil }
|
29
|
+
end
|
30
|
+
if json_obj['keys']
|
31
|
+
# loop over the keys array
|
32
|
+
json_obj['keys'].each do |intern|
|
33
|
+
username = intern['username'].strip
|
34
|
+
# check for white spaces chars in usernames
|
35
|
+
describe username do
|
36
|
+
it { should_not match(/\s/) }
|
37
|
+
end
|
38
|
+
# check key file owners and permissions
|
39
|
+
describe file(intern['key']) do
|
40
|
+
it { should be_owned_by username }
|
41
|
+
its('mode') { should eq 0600 }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Execution
|
48
|
+
=====================================================
|
49
|
+
|
50
|
+
It's important to understand that |ruby| code used in custom resources and controls DSL is executed on the system that runs |inspec|. This allows |inspec| to work without |ruby| and rubygems being required on remote targets(servers or containers).
|
51
|
+
|
52
|
+
For example, using ```ls``` or ``system('ls')`` will result in the ``ls`` command being run locally and not on the target(remote) system.
|
53
|
+
In order to process the output of ``ls`` executed on the target system, use ``inspec.command('ls')`` or ``inspec.powershell('ls')``
|
54
|
+
|
55
|
+
Similarly, use ``inspec.file(PATH)`` to access files or directories from remote systems in your tests or custom resources.
|
56
|
+
|
57
|
+
Using rubygems
|
58
|
+
=====================================================
|
59
|
+
|
60
|
+
|ruby| gems are self-contained programs and libraries ...
|
61
|
+
|
62
|
+
|
63
|
+
Interactive Debugging with Pry
|
64
|
+
=====================================================
|
65
|
+
|
66
|
+
Here's a sample |inspec| control that users |ruby| variables to instantiate an |inspec| resource once and use the content in multipLe tests.
|
67
|
+
|
68
|
+
.. code-block:: ruby
|
69
|
+
|
70
|
+
control 'check-perl' do
|
71
|
+
impact 0.3
|
72
|
+
title 'Check perl compiled options and permissions'
|
73
|
+
perl_out = command('perl -V')
|
74
|
+
#require 'pry'; binding.pry;
|
75
|
+
describe perl_out do
|
76
|
+
its('exit_status') { should eq 0 }
|
77
|
+
its('stdout') { should match (/USE_64_BIT_ALL/) }
|
78
|
+
its('stdout') { should match (/useposix=true/) }
|
79
|
+
its('stdout') { should match (/-fstack-protector/) }
|
80
|
+
end
|
81
|
+
|
82
|
+
# extract an array of include directories
|
83
|
+
perl_inc = perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
84
|
+
# ensure include directories are only writable by 'owner'
|
85
|
+
perl_inc.each do |path|
|
86
|
+
describe directory(path.strip) do
|
87
|
+
it { should_not be_writable.by('group') }
|
88
|
+
it { should_not be_writable.by('other') }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
An **advanced** but very useful |ruby| tip. In the previous example, I commented out the ``require 'pry'; binding.pry;`` line. If you remove the ``#`` prefix and run the control, the execution will stop at that line and give you a ``pry`` shell. Use that to troubleshoot, print variables, see methods available, etc. For the above example:
|
94
|
+
|
95
|
+
.. code-block:: ruby
|
96
|
+
|
97
|
+
[1] pry> perl_out.exit_status
|
98
|
+
=> 0
|
99
|
+
[2] pry> perl_out.stderr
|
100
|
+
=> ""
|
101
|
+
[3] pry> ls perl_out
|
102
|
+
Inspec::Plugins::Resource#methods: inspect
|
103
|
+
Inspec::Resources::Cmd#methods: command exist? exit_status result stderr stdout to_s
|
104
|
+
Inspec::Plugins::ResourceCommon#methods: resource_skipped skip_resource
|
105
|
+
Inspec::Resource::Registry::Command#methods: inspec
|
106
|
+
instance variables: @__backend_runner__ @__resource_name__ @command @result
|
107
|
+
[4] pry> perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
108
|
+
=> ["/Library/Perl/5.18/darwin-thread-multi-2level",
|
109
|
+
" /Library/Perl/5.18",
|
110
|
+
...REDACTED...
|
111
|
+
[5] pry> exit # or abort
|
112
|
+
|
113
|
+
You can use ``pry`` inside both the controls DSL and resources.
|
114
|
+
Similarly, for dev and test, you can use ``inspec shell`` which is based on ``pry``, for example:
|
115
|
+
|
116
|
+
.. code-block:: ruby
|
117
|
+
|
118
|
+
$ inspec shell
|
119
|
+
Welcome to the interactive InSpec Shell
|
120
|
+
To find out how to use it, type: help
|
121
|
+
|
122
|
+
inspec> command('ls /home/gordon/git/inspec/docs').stdout
|
123
|
+
=> "ctl_inspec.rst\ndsl_inspec.rst\ndsl_resource.rst\n"
|
124
|
+
inspec> command('ls').stdout.split("\n")
|
125
|
+
=> ["ctl_inspec.rst", "dsl_inspec.rst", "dsl_resource.rst"]
|
126
|
+
|
127
|
+
inspec> help command
|
128
|
+
Name: command
|
129
|
+
|
130
|
+
Description:
|
131
|
+
Use the command InSpec audit resource to test an arbitrary command that is run on the system.
|
132
|
+
|
133
|
+
Example:
|
134
|
+
describe command('ls -al /') do
|
135
|
+
it { should exist }
|
136
|
+
its('stdout') { should match /bin/ }
|
137
|
+
its('stderr') { should eq '' }
|
138
|
+
its('exit_status') { should eq 0 }
|
139
|
+
end
|
140
|
+
|
141
|
+
.. |inspec| replace:: InSpec
|
142
|
+
.. |chef compliance| replace:: Chef Compliance
|
143
|
+
.. |ruby| replace:: Ruby
|
144
|
+
.. |csv| replace:: CSV
|
145
|
+
.. |json| replace:: JSON
|
data/inspec.gemspec
CHANGED
@@ -58,6 +58,8 @@ module Compliance
|
|
58
58
|
desc 'profiles', 'list all available profiles in Chef Compliance'
|
59
59
|
def profiles
|
60
60
|
config = Compliance::Configuration.new
|
61
|
+
return if !loggedin(config)
|
62
|
+
|
61
63
|
profiles = Compliance::API.profiles(config)
|
62
64
|
if !profiles.empty?
|
63
65
|
# iterate over profiles
|
@@ -73,6 +75,9 @@ module Compliance
|
|
73
75
|
desc 'exec PROFILE', 'executes a Chef Compliance profile'
|
74
76
|
exec_options
|
75
77
|
def exec(*tests)
|
78
|
+
config = Compliance::Configuration.new
|
79
|
+
return if !loggedin(config)
|
80
|
+
|
76
81
|
# iterate over tests and add compliance scheme
|
77
82
|
tests = tests.map { |t| 'compliance://' + t }
|
78
83
|
|
@@ -84,7 +89,10 @@ module Compliance
|
|
84
89
|
desc 'upload PATH', 'uploads a local profile to Chef Compliance'
|
85
90
|
option :overwrite, type: :boolean, default: false,
|
86
91
|
desc: 'Overwrite existing profile on Chef Compliance.'
|
87
|
-
def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, PerceivedComplexity
|
92
|
+
def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, PerceivedComplexity, Metrics/CyclomaticComplexity
|
93
|
+
config = Compliance::Configuration.new
|
94
|
+
return if !loggedin(config)
|
95
|
+
|
88
96
|
unless File.exist?(path)
|
89
97
|
puts "Directory #{path} does not exist."
|
90
98
|
exit 1
|
@@ -110,7 +118,6 @@ module Compliance
|
|
110
118
|
end
|
111
119
|
|
112
120
|
# determine user information
|
113
|
-
config = Compliance::Configuration.new
|
114
121
|
if config['token'].nil? || config['user'].nil?
|
115
122
|
error.call('Please login via `inspec compliance login`')
|
116
123
|
end
|
@@ -261,6 +268,12 @@ module Compliance
|
|
261
268
|
|
262
269
|
[success, msg]
|
263
270
|
end
|
271
|
+
|
272
|
+
def loggedin(config)
|
273
|
+
serverknown = !config['server'].nil?
|
274
|
+
puts 'You need to login first with `inspec compliance login`' if !serverknown
|
275
|
+
serverknown
|
276
|
+
end
|
264
277
|
end
|
265
278
|
|
266
279
|
# register the subcommand to Inspec CLI registry
|
data/lib/inspec/cli.rb
CHANGED
@@ -15,8 +15,6 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
15
15
|
desc: 'Show diagnostics (versions, configurations)'
|
16
16
|
|
17
17
|
desc 'json PATH', 'read all tests in PATH and generate a JSON summary'
|
18
|
-
option :id, type: :string,
|
19
|
-
desc: 'Attach a profile ID to all test results'
|
20
18
|
option :output, aliases: :o, type: :string,
|
21
19
|
desc: 'Save the created profile to a path'
|
22
20
|
option :controls, type: :array,
|
@@ -115,9 +113,19 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
115
113
|
|
116
114
|
desc 'detect', 'detect the target OS'
|
117
115
|
target_options
|
116
|
+
option :format, type: :string
|
118
117
|
def detect
|
119
|
-
|
120
|
-
|
118
|
+
o = opts.dup
|
119
|
+
o[:command] = 'os.params'
|
120
|
+
res = run_command(o)
|
121
|
+
if opts['format'] == 'json'
|
122
|
+
puts res.to_json
|
123
|
+
else
|
124
|
+
headline('Operating System Details')
|
125
|
+
%w{name family release arch}.each { |item|
|
126
|
+
puts "#{mark_text(item.to_s.capitalize + ':')} #{res[item.to_sym]}"
|
127
|
+
}
|
128
|
+
end
|
121
129
|
end
|
122
130
|
|
123
131
|
desc 'shell', 'open an interactive debugging shell'
|
@@ -129,25 +137,30 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
129
137
|
o = opts.dup
|
130
138
|
o[:logger] = Logger.new(STDOUT)
|
131
139
|
o[:logger].level = get_log_level(o.log_level)
|
132
|
-
|
133
140
|
if o[:command].nil?
|
134
141
|
runner = Inspec::Runner.new(o)
|
135
142
|
return Inspec::Shell.new(runner).start
|
136
143
|
else
|
137
|
-
|
138
|
-
runner = Inspec::Runner.new(opts)
|
139
|
-
res = runner.create_context.load(o[:command])
|
144
|
+
res = run_command(o)
|
140
145
|
jres = res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)
|
141
146
|
puts jres
|
142
147
|
end
|
143
|
-
rescue RuntimeError => e
|
144
|
-
puts e.message
|
148
|
+
rescue RuntimeError, Train::UserError => e
|
149
|
+
$stderr.puts e.message
|
145
150
|
end
|
146
151
|
|
147
152
|
desc 'version', 'prints the version of this tool'
|
148
153
|
def version
|
149
154
|
puts Inspec::VERSION
|
150
155
|
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def run_command(opts)
|
160
|
+
opts[:test_collector] = 'mock'
|
161
|
+
runner = Inspec::Runner.new(opts)
|
162
|
+
runner.create_context.load(opts[:command])
|
163
|
+
end
|
151
164
|
end
|
152
165
|
|
153
166
|
# Load all plugins on startup
|
data/lib/inspec/dsl.rb
CHANGED
@@ -31,37 +31,6 @@ module Inspec::DSL
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
# Register a given rule with RSpec and
|
35
|
-
# let it run. This happens after everything
|
36
|
-
# else is merged in.
|
37
|
-
def self.execute_rule(r, profile_id)
|
38
|
-
checks = ::Inspec::Rule.prepare_checks(r)
|
39
|
-
fid = InspecBaseRule.full_id(r, profile_id)
|
40
|
-
checks.each do |m, a, b|
|
41
|
-
# check if the resource is skippable and skipped
|
42
|
-
cres = rule_from_check(m, a, b)
|
43
|
-
set_rspec_ids(cres, fid) if m == 'describe'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# merge two rules completely; all defined
|
48
|
-
# fields from src will be overwritten in dst
|
49
|
-
def self.merge_rules(dst, src)
|
50
|
-
InspecBaseRule.merge dst, src
|
51
|
-
end
|
52
|
-
|
53
|
-
# Attach an ID attribute to the
|
54
|
-
# metadata of all examples
|
55
|
-
# TODO: remove this once IDs are in rspec-core
|
56
|
-
def self.set_rspec_ids(obj, id)
|
57
|
-
obj.examples.each {|ex|
|
58
|
-
ex.metadata[:id] = id
|
59
|
-
}
|
60
|
-
obj.children.each {|c|
|
61
|
-
set_rspec_ids(c, id)
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
34
|
def self.load_spec_files_for_profile(bind_context, opts, &block)
|
66
35
|
# get all spec files
|
67
36
|
target = get_reference_profile(opts[:profile_id], opts[:conf])
|
@@ -121,24 +90,3 @@ module Inspec::DSL
|
|
121
90
|
ctx
|
122
91
|
end
|
123
92
|
end
|
124
|
-
|
125
|
-
module Inspec::GlobalDSL
|
126
|
-
def __register_rule(r)
|
127
|
-
# make sure the profile id is attached to the rule
|
128
|
-
::Inspec::DSL.execute_rule(r, __profile_id)
|
129
|
-
end
|
130
|
-
|
131
|
-
def __unregister_rule(_id)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
module Inspec::DSLHelper
|
136
|
-
def self.bind_dsl(scope)
|
137
|
-
(class << scope; self; end).class_exec do
|
138
|
-
include Inspec::DSL
|
139
|
-
include Inspec::GlobalDSL
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
::Inspec::DSLHelper.bind_dsl(self)
|