inspec 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24a4519c426bef0955b532d458a7436c172ee78e
4
- data.tar.gz: 94fa93e202174527e9d40cbf1f174cc37a879492
3
+ metadata.gz: 46a196f44aef946778a2c1551727b83826eaaede
4
+ data.tar.gz: b351a6fddd347b9f951818ad3332270f3d399139
5
5
  SHA512:
6
- metadata.gz: afa1eeb884e110fd29387f621aa29ff8a90f428257a96f657fba4001520bb893e23af8f94d583cb73579c9eb6a4f95986a4df842f81aea5513fd7eb7c450a944
7
- data.tar.gz: 7cb77d205bdf7ebadae0b376aefb35d03ee1ab444b8d95a30f8042eb5ab139bc2f6112d2557ded9bdbfbff07cb68998bf86b7d8884d4b15554b64f6dd827a925
6
+ metadata.gz: 70da720dd36b4df18aca90293777b169ee25df1ebbb679500104e191ecdfa203d2136223e063e37c7ab0b5d5eed44029f65d2331bcd5d3eb825376c9e63f344f
7
+ data.tar.gz: d09acee41a988495d4bec78a6a02409a89c89e8b527b5b3475ba622d2e6ab0da9751236bf1af7c6059c8e51a9193940b24cab6ef1f86cb66db80a174d5f4b8be
data/CHANGELOG.md CHANGED
@@ -1,7 +1,34 @@
1
1
  # Change Log
2
2
 
3
- ## [0.26.0](https://github.com/chef/inspec/tree/0.26.0) (2016-06-16)
4
- [Full Changelog](https://github.com/chef/inspec/compare/v0.25.0...0.26.0)
3
+ ## [0.27.0](https://github.com/chef/inspec/tree/0.27.0) (2016-07-10)
4
+ [Full Changelog](https://github.com/chef/inspec/compare/v0.26.0...0.27.0)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - inspec report source\_location data type [\#807](https://github.com/chef/inspec/issues/807)
9
+ - Additional fields in inspec reports [\#806](https://github.com/chef/inspec/issues/806)
10
+ - api: report source location with field identifiers [\#808](https://github.com/chef/inspec/pull/808) ([arlimus](https://github.com/arlimus))
11
+ - add boolean support for cmp matcher [\#801](https://github.com/chef/inspec/pull/801) ([chris-rock](https://github.com/chris-rock))
12
+ - improve wmi resource [\#800](https://github.com/chef/inspec/pull/800) ([chris-rock](https://github.com/chris-rock))
13
+ - Update documentation for bundles [\#716](https://github.com/chef/inspec/pull/716) ([chris-rock](https://github.com/chris-rock))
14
+
15
+ **Fixed bugs:**
16
+
17
+ - `os` resource not accessible within a `describe` [\#451](https://github.com/chef/inspec/issues/451)
18
+ - add suid sgid and sticky support for file resource [\#819](https://github.com/chef/inspec/pull/819) ([arlimus](https://github.com/arlimus))
19
+ - pin gem version for ffi due to appveyor failures [\#816](https://github.com/chef/inspec/pull/816) ([arlimus](https://github.com/arlimus))
20
+ - check service running by ActiveState [\#814](https://github.com/chef/inspec/pull/814) ([arlimus](https://github.com/arlimus))
21
+
22
+ **Merged pull requests:**
23
+
24
+ - small fix for postgres\_session documentation \(Test for risky database entries example\) [\#815](https://github.com/chef/inspec/pull/815) ([atomic111](https://github.com/atomic111))
25
+ - Add array documentation to yaml / json resource [\#803](https://github.com/chef/inspec/pull/803) ([bigbam505](https://github.com/bigbam505))
26
+ - Updating ctl docs to include the init command [\#802](https://github.com/chef/inspec/pull/802) ([ChefRycar](https://github.com/ChefRycar))
27
+ - add documentation for bash resource [\#799](https://github.com/chef/inspec/pull/799) ([chris-rock](https://github.com/chris-rock))
28
+ - align inspec's check, detect, and exec cli formatters [\#797](https://github.com/chef/inspec/pull/797) ([arlimus](https://github.com/arlimus))
29
+
30
+ ## [v0.26.0](https://github.com/chef/inspec/tree/v0.26.0) (2016-06-16)
31
+ [Full Changelog](https://github.com/chef/inspec/compare/v0.25.0...v0.26.0)
5
32
 
6
33
  **Implemented enhancements:**
7
34
 
data/Gemfile CHANGED
@@ -8,6 +8,9 @@ if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('1.9.3')
8
8
  gem 'net-ssh', '~> 2.9'
9
9
  end
10
10
 
11
+ # TODO: ffi 1.9.11 is currently erroneous on windows tests
12
+ gem 'ffi', '= 1.9.10'
13
+
11
14
  group :test do
12
15
  gem 'bundler', '~> 1.5'
13
16
  gem 'minitest', '~> 5.5'
data/docs/ctl_inspec.rst CHANGED
@@ -171,6 +171,33 @@ Use ``inspec help`` to print help for the |ctl inspec| from the command shell.
171
171
 
172
172
 
173
173
 
174
+ init
175
+ =====================================================
176
+ Use ``inspec init`` to initialize a new inspec profile
177
+
178
+ Syntax
179
+ -----------------------------------------------------
180
+ This command has the following syntax:
181
+ .. code-block:: bash
182
+
183
+ $ inspec init profile PROFILE (options)
184
+
185
+ where:
186
+
187
+ * ``PROFILE`` is the name of the profile you wish to create
188
+
189
+ Options
190
+ -----------------------------------------------------
191
+ This subcommand has additional options:
192
+
193
+ ``--overwrite``
194
+ Overwite directory if it exists
195
+
196
+ ``--no-overwrite``
197
+ Converse of ``--overwrite``. (default)
198
+
199
+
200
+
174
201
  json
175
202
  =====================================================
176
203
  Use ``inspec json`` to read all tests at the specified path, and then generate a |json| profile to standard output (stdout).
data/docs/resources.rst CHANGED
@@ -9,6 +9,7 @@ The following InSpec audit resources are available:
9
9
  * `audit_policy`_
10
10
  * `auditd_conf`_
11
11
  * `auditd_rules`_
12
+ * `bash`_
12
13
  * `bond`_
13
14
  * `bridge`_
14
15
  * `csv`_
@@ -398,6 +399,130 @@ Note that filters can be chained, for example:
398
399
  end
399
400
 
400
401
 
402
+
403
+
404
+ bash
405
+ =====================================================
406
+ Use the ``bash`` |inspec resource| to test an arbitrary command in BASH on the system.
407
+
408
+ **Stability: Stable**
409
+
410
+ Syntax
411
+ -----------------------------------------------------
412
+ A ``bash`` |inspec resource| block declares a command to be run, one (or more) expected outputs, and the location to which that output is sent:
413
+
414
+ .. code-block:: ruby
415
+
416
+ describe bash('command') do
417
+ it { should exist }
418
+ its('matcher') { should eq 'output' }
419
+ end
420
+
421
+ where
422
+
423
+ * ``'command'`` must specify a command to be run
424
+ * ``'matcher'`` is one of ``exit_status``, ``stderr``, or ``stdout``
425
+ * ``'output'`` tests the output of the command run on the system versus the output value stated in the test
426
+
427
+ Matchers
428
+ -----------------------------------------------------
429
+ This InSpec audit resource has the following matchers.
430
+
431
+ exist
432
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
433
+ The ``exist`` matcher tests if a command may be run on the system:
434
+
435
+ .. code-block:: ruby
436
+
437
+ it { should exist }
438
+
439
+ exit_status
440
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
441
+ The ``exit_status`` matcher tests the exit status for the command:
442
+
443
+ .. code-block:: ruby
444
+
445
+ its('exit_status') { should eq 123 }
446
+
447
+ stderr
448
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
449
+ The ``stderr`` matcher tests results of the command as returned in standard error (stderr):
450
+
451
+ .. code-block:: ruby
452
+
453
+ its('stderr') { should eq 'error' }
454
+
455
+ stdout
456
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
457
+ The ``stdout`` matcher tests results of the command as returned in standard output (stdout):
458
+
459
+ .. code-block:: ruby
460
+
461
+ its('stdout') { should match /^1$/ }
462
+
463
+ Examples
464
+ -----------------------------------------------------
465
+ The following examples show how to use this InSpec audit resource.
466
+
467
+ **List content of a directorye**
468
+
469
+ .. code-block:: ruby
470
+
471
+ describe bash('ls -al /') do
472
+ its('stdout') { should match /bin/ }
473
+ its('stderr') { should eq '' }
474
+ its('exit_status') { should eq 0 }
475
+ end
476
+
477
+ **Test standard output (stdout)**
478
+
479
+ .. code-block:: ruby
480
+
481
+ describe bash('echo hello') do
482
+ its('stdout') { should eq 'hello\n' }
483
+ its('stderr') { should eq '' }
484
+ its('exit_status') { should eq 0 }
485
+ end
486
+
487
+ **Test standard error (stderr)**
488
+
489
+ .. code-block:: ruby
490
+
491
+ describe bash('>&2 echo error') do
492
+ its('stdout') { should eq '' }
493
+ its('stderr') { should eq 'error\n' }
494
+ its('exit_status') { should eq 0 }
495
+ end
496
+
497
+ **Test an exit status code**
498
+
499
+ .. code-block:: ruby
500
+
501
+ describe bash('exit 123') do
502
+ its('stdout') { should eq '' }
503
+ its('stderr') { should eq '' }
504
+ its('exit_status') { should eq 123 }
505
+ end
506
+
507
+ **Specify the path of the bash executable**
508
+
509
+ .. code-block:: ruby
510
+
511
+ describe bash('echo hello', path: '/bin/bash') do
512
+ its('stdout') { should eq 'hello\n' }
513
+ end
514
+
515
+ **Specify bash arguments (defaults to -c)**
516
+
517
+ .. code-block:: ruby
518
+
519
+ describe bash('echo hello', args: '-x -c') do
520
+ its('stdout') { should eq 'hello\n' }
521
+ end
522
+
523
+
524
+
525
+
401
526
  bond
402
527
  =====================================================
403
528
  Use the ``bond`` |inspec resource| to test a logical, bonded network interface (i.e. "two or more network interfaces aggregated into a single, logical network interface"). On |linux| platforms, any value in the ``/proc/net/bonding`` directory may be tested.
@@ -1913,7 +2038,11 @@ A ``json`` |inspec resource| block declares the data to be tested. Assume the fo
1913
2038
  "name" : "hello",
1914
2039
  "meta" : {
1915
2040
  "creator" : "John Doe"
1916
- }
2041
+ },
2042
+ "array": [
2043
+ "zero",
2044
+ "one"
2045
+ ]
1917
2046
  }
1918
2047
 
1919
2048
 
@@ -1924,6 +2053,7 @@ This file can be queried via:
1924
2053
  describe json('/paht/to/name.json') do
1925
2054
  its('name') { should eq 'hello' }
1926
2055
  its(['meta','creator']) { should eq 'John Doe' }
2056
+ its(['array', 1]) { should eq 'one' }
1927
2057
  end
1928
2058
 
1929
2059
  where
@@ -3562,11 +3692,11 @@ The following examples show how to use this InSpec audit resource.
3562
3692
  .. code-block:: ruby
3563
3693
 
3564
3694
  describe postgres_session('my_user', 'password').query('SELECT count (*)
3565
- FROM pg_language
3566
- WHERE lanpltrusted = 'f'
3567
- AND lanname!='internal'
3568
- AND lanname!='c';') do
3569
- its('output') { should eq(/^0/) }
3695
+ FROM pg_language
3696
+ WHERE lanpltrusted = \'f\'
3697
+ AND lanname!=\'internal\'
3698
+ AND lanname!=\'c\';') do
3699
+ its('output') { should eq '0' }
3570
3700
  end
3571
3701
 
3572
3702
 
@@ -4344,10 +4474,21 @@ Syntax
4344
4474
  -----------------------------------------------------
4345
4475
  A ``yaml`` |inspec resource| block declares the configuration data to be tested:
4346
4476
 
4477
+ .. code-block:: yaml
4478
+
4479
+ name: foo
4480
+ array:
4481
+ - zero
4482
+ - one
4483
+
4484
+
4485
+ This file can be queried via:
4486
+
4347
4487
  .. code-block:: ruby
4348
4488
 
4349
4489
  describe yaml do
4350
4490
  its('name') { should eq 'foo' }
4491
+ its(['array', 1]) { should eq 'one' }
4351
4492
  end
4352
4493
 
4353
4494
  where
data/inspec.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
25
  spec.require_paths = ['lib']
26
26
 
27
- spec.add_dependency 'train', '~> 0.13'
27
+ spec.add_dependency 'train', '>=0.15.1', '<1.0'
28
28
  spec.add_dependency 'thor', '~> 0.19'
29
29
  spec.add_dependency 'json', '~> 1.8'
30
30
  spec.add_dependency 'rainbow', '~> 2'
@@ -8,7 +8,6 @@ This extensions offers the following features:
8
8
 
9
9
  To use the CLI, this InSpec add-on adds the following commands:
10
10
 
11
- * `$ inspec compliance api_token server --token TOKEN --user USER` - save the Chef Compliance API token for user
12
11
  * `$ inspec compliance login` - authentication of the API token against Chef Compliance
13
12
  * `$ inspec compliance profiles` - list all available Chef Compliance profiles
14
13
  * `$ inspec compliance exec profile` - runs a Chef Compliance profile
@@ -20,6 +19,111 @@ Compliance profiles can be executed in two mays:
20
19
  - via compliance exec: `inspec compliance exec profile`
21
20
  - via compliance scheme: `inspec exec compliance://profile`
22
21
 
22
+ ## Usage
23
+
24
+ Before you start using the compliance plugin, you need a running [Chef Compliance](https://www.chef.io/compliance/) server. Please login and gather the access token:
25
+
26
+ ![Chef Compliance Token](images/cc-token.png)
27
+
28
+ You can choose the access token (`--token`) or the refresh token (`--refresh_token`)
29
+
30
+ ```
31
+ $ inspec compliance
32
+ Commands:
33
+ inspec compliance exec PROFILE # executes a Chef Compliance profile
34
+ inspec compliance help [COMMAND] # Describe subcommands or one specific subcommand
35
+ inspec compliance login SERVER # Log in to a Chef Compliance SERVER
36
+ inspec compliance logout # user logout from Chef Compliance
37
+ inspec compliance profiles # list all available profiles in Chef Compliance
38
+ inspec compliance upload PATH # uploads a local profile to Chef Compliance
39
+ inspec compliance version # displays the version of the Chef Compliance server
40
+
41
+ # login to chef compliance server
42
+ $ inspec compliance login https://compliance.test --user admin --insecure --token '...'
43
+
44
+ # display the chef compliance server version
45
+ $ inspec compliance version
46
+ Chef Compliance version: 1.0.11
47
+
48
+ # list available profiles via Chef Compliance
49
+ $ inspec compliance profiles
50
+ Available profiles:
51
+ -------------------
52
+ * base/apache
53
+ * base/linux
54
+ * base/mysql
55
+ * base/postgres
56
+ * base/ssh
57
+ * base/windows
58
+ * cis/cis-centos6-level1
59
+ * cis/cis-centos6-level2
60
+ * cis/cis-centos7-level1
61
+ * cis/cis-centos7-level2
62
+ * cis/cis-rhel7-level1
63
+ * cis/cis-rhel7-level2
64
+ * cis/cis-ubuntu12.04lts-level1
65
+ * cis/cis-ubuntu12.04lts-level2
66
+ * cis/cis-ubuntu14.04lts-level1
67
+ * cis/cis-ubuntu14.04lts-level2
68
+
69
+ # upload a profile to chef Compliance
70
+ $ inspec compliance version
71
+ Chef Compliance version: 1.0.11
72
+ ➜ inspec git:(chris-rock/cc-error-not-loggedin) ✗ b inspec compliance upload examples/profile
73
+ I, [2016-05-06T14:27:20.907547 #37592] INFO -- : Checking profile in examples/profile
74
+ I, [2016-05-06T14:27:20.907668 #37592] INFO -- : Metadata OK.
75
+ I, [2016-05-06T14:27:20.968584 #37592] INFO -- : Found 4 controls.
76
+ I, [2016-05-06T14:27:20.968638 #37592] INFO -- : Control definitions OK.
77
+ Profile is valid
78
+ Generate temporary profile archive at /var/folders/jy/2bnrfb4s36jbjtzllvhhyqhw0000gn/T/profile20160506-37592-1tf326f.tar.gz
79
+ I, [2016-05-06T14:27:21.020017 #37592] INFO -- : Generate archive /var/folders/jy/2bnrfb4s36jbjtzllvhhyqhw0000gn/T/profile20160506-37592-1tf326f.tar.gz.
80
+ I, [2016-05-06T14:27:21.024837 #37592] INFO -- : Finished archive generation.
81
+ Start upload to admin/profile
82
+ Uploading to Chef Compliance
83
+ Successfully uploaded profile
84
+
85
+ # display all profiles
86
+ $ inspec compliance profiles
87
+ Available profiles:
88
+ -------------------
89
+ * admin/profile
90
+ * base/apache
91
+ * base/linux
92
+ * base/mysql
93
+ * base/postgres
94
+ * base/ssh
95
+ * base/windows
96
+ * cis/cis-centos6-level1
97
+ * cis/cis-centos6-level2
98
+ * cis/cis-centos7-level1
99
+ * cis/cis-centos7-level2
100
+ * cis/cis-rhel7-level1
101
+ * cis/cis-rhel7-level2
102
+ * cis/cis-ubuntu12.04lts-level1
103
+ * cis/cis-ubuntu12.04lts-level2
104
+ * cis/cis-ubuntu14.04lts-level1
105
+ * cis/cis-ubuntu14.04lts-level2
106
+
107
+ # run a profile from Chef Compliance locally
108
+ $ inspec exec compliance://admin/profile
109
+ .*...
110
+
111
+ Pending: (Failures listed here are expected and do not affect your suite's status)
112
+
113
+ 1) gordon_config Can't find file "/tmp/gordon/config.yaml"
114
+ # Not yet implemented
115
+ # ./lib/inspec/runner.rb:157
116
+
117
+
118
+ Finished in 0.02862 seconds (files took 0.62628 seconds to load)
119
+ 5 examples, 0 failures, 1 pending
120
+
121
+ # logout from Chef Compliance
122
+ ```
123
+ $ inspec compliance logout
124
+ Successfully logged out
125
+ ```
126
+
23
127
  ## Integration Tests
24
128
 
25
129
  At this point of time, InSpec is not able to pick up the token directly, therefore the integration test is semi-automatic at this point of time:
@@ -0,0 +1,31 @@
1
+ # InSpec Extension to create new profiles
2
+
3
+ This extensions helps you to easily create a new profile
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ $ inspec init profile examples/new-profile
9
+ Create new profile at /Users/chartmann/Development/compliance/inspec/examples/new-profile
10
+ * Create directory controls
11
+ * Create file controls/example.rb
12
+ * Create file inspec.yml
13
+ * Create directory libraries
14
+ * Create file README.md
15
+ * Create file libraries/.gitkeep
16
+
17
+ $ inspec check examples/new-profile
18
+ Summary
19
+ -------
20
+ Location: examples/new-profile
21
+ Profile: examples/new-profile
22
+ Controls: 2
23
+ Timestamp: 2016-05-06T14:39:47+02:00
24
+ Valid: true
25
+
26
+ Errors
27
+ ------
28
+
29
+ Warnings
30
+ --------
31
+ ```
@@ -10,3 +10,36 @@ To use the CLI, this InSpec add-on adds the following commands:
10
10
 
11
11
  - via supermarket exec: `inspec supermarket exec nathenharvey/tmp-compliance-profile`
12
12
  - via supermarket scheme: `inspec exec supermarket://nathenharvey/tmp-compliance-profile`
13
+
14
+ ## Usage
15
+
16
+ ```
17
+ $ inspec supermarket
18
+ Commands:
19
+ inspec supermarket exec PROFILE # execute a Supermarket profile
20
+ inspec supermarket help [COMMAND] # Describe subcommands or one specific subcommand
21
+ inspec supermarket info PROFILE # display Supermarket profile details
22
+ inspec supermarket profiles # list all available profiles in Chef Supermarket
23
+
24
+ $ inspec supermarket profiles
25
+ Available profiles:
26
+ -------------------
27
+ * nathenharvey/tmp-compliance-profile
28
+ * hardening/os-hardening
29
+ * hardening/ssh-hardening
30
+
31
+ $ inspec supermarket info hardening/os-hardening
32
+ name: os-hardening
33
+ owner: hardening
34
+ url: https://github.com/dev-sec/tests-os-hardening
35
+
36
+ description: Base Linux Compliance profile, used for Security + DevOps. More Information is available at http://dev-sec.io/
37
+
38
+ $ inspec exec supermarket://hardening/os-hardening
39
+ ........F.F.................F......FFF.....FFFF.F........FF....FFFFFFF...FF.FFFFFF.FFFFFFFFFFF.F...
40
+
41
+ ...
42
+
43
+ Finished in 3.81 seconds (files took 5.69 seconds to load)
44
+ 99 examples, 40 failures
45
+ ```
data/lib/inspec/cli.rb CHANGED
@@ -57,19 +57,35 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
57
57
  if opts['format'] == 'json'
58
58
  puts JSON.generate(result)
59
59
  else
60
- headline('Summary')
61
- %w{location profile controls timestamp valid}.each { |item|
62
- puts "#{mark_text(item.to_s.capitalize + ':')} #{result[:summary][item.to_sym]}"
63
- }
60
+ %w{location profile controls timestamp valid}.each do |item|
61
+ puts format('%-12s %s', item.to_s.capitalize + ':',
62
+ mark_text(result[:summary][item.to_sym]))
63
+ end
64
64
  puts
65
65
 
66
- %w{errors warnings}.each { |list|
67
- headline(list.to_s.capitalize)
68
- result[list.to_sym].each { |item|
69
- puts "#{item[:file]}:#{item[:line]}:#{item[:column]}: #{item[:msg]} "
66
+ if result[:errors].empty? and result[:warnings].empty?
67
+ puts 'No errors or warnings'
68
+ else
69
+ red = "\033[31m"
70
+ yellow = "\033[33m"
71
+ rst = "\033[0m"
72
+
73
+ item_msg = lambda { |item|
74
+ pos = [item[:file], item[:line], item[:column]].compact.join(':')
75
+ pos.empty? ? item[:msg] : pos + ': ' + item[:msg]
70
76
  }
77
+ result[:errors].each do |item|
78
+ puts "#{red} ✖ #{item_msg.call(item)}#{rst}"
79
+ end
80
+ result[:warnings].each do |item|
81
+ puts "#{yellow} ! #{item_msg.call(item)}#{rst}"
82
+ end
83
+
71
84
  puts
72
- }
85
+ puts format('Summary: %s%d errors%s, %s%d warnings%s',
86
+ red, result[:errors].length, rst,
87
+ yellow, result[:warnings].length, rst)
88
+ end
73
89
  end
74
90
  exit 1 unless result[:summary][:valid]
75
91
  end
@@ -127,7 +143,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
127
143
  else
128
144
  headline('Operating System Details')
129
145
  %w{name family release arch}.each { |item|
130
- puts "#{mark_text(item.to_s.capitalize + ':')} #{res[item.to_sym]}"
146
+ puts format('%-10s %s', item.to_s.capitalize + ':',
147
+ mark_text(res[item.to_sym]))
131
148
  }
132
149
  end
133
150
  end
@@ -145,7 +145,8 @@ module Inspec
145
145
 
146
146
  # iterate over hash of groups
147
147
  params[:controls].each { |id, control|
148
- sfile, sline = control[:source_location]
148
+ sfile = control[:source_location][:ref]
149
+ sline = control[:source_location][:line]
149
150
  error.call(sfile, sline, nil, id, 'Avoid controls with empty IDs') if id.nil? or id.empty?
150
151
  next if id.start_with? '(generated '
151
152
  warn.call(sfile, sline, nil, id, "Control #{id} has no title") if control[:title].to_s.empty?
@@ -202,8 +202,10 @@ class InspecRspecCli < InspecRspecJson # rubocop:disable Metrics/ClassLength
202
202
 
203
203
  res = @output_hash[:summary]
204
204
  passed = res[:example_count] - res[:failure_count] - res[:skip_count]
205
- s = format('Summary: %3d successful %3d failures %3d skipped',
206
- passed, res[:failure_count], res[:skip_count])
205
+ s = format('Summary: %s%d successful%s, %s%d failures%s, %s%d skipped%s',
206
+ COLORS['passed'], passed, COLORS['reset'],
207
+ COLORS['failed'], res[:failure_count], COLORS['reset'],
208
+ COLORS['skipped'], res[:skip_count], COLORS['reset'])
207
209
  output.puts(s)
208
210
  end
209
211
 
data/lib/inspec/rule.rb CHANGED
@@ -199,10 +199,11 @@ module Inspec
199
199
 
200
200
  # get the source location of the block
201
201
  def __get_block_source_location(&block)
202
- return [nil, nil] unless block_given?
203
- block.source_location
202
+ return {} unless block_given?
203
+ r, l = block.source_location
204
+ { ref: r, line: l }
204
205
  rescue MethodSource::SourceNotFoundError
205
- [nil, nil]
206
+ {}
206
207
  end
207
208
  end
208
209
  end
@@ -3,5 +3,5 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  module Inspec
6
- VERSION = '0.26.0'.freeze
6
+ VERSION = '0.27.0'.freeze
7
7
  end
@@ -247,6 +247,15 @@ RSpec::Matchers.define :cmp do |first_expected|
247
247
  !(value =~ /\A0+\d+\Z/).nil?
248
248
  end
249
249
 
250
+ def boolean?(value)
251
+ %w{true false}.include?(value.downcase)
252
+ end
253
+
254
+ # expects that the values have been checked with boolean?
255
+ def to_boolean(value)
256
+ value.casecmp('true') == 0
257
+ end
258
+
250
259
  def try_match(actual, op, expected) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
251
260
  # if actual and expected are strings
252
261
  if expected.is_a?(String) && actual.is_a?(String)
@@ -255,6 +264,8 @@ RSpec::Matchers.define :cmp do |first_expected|
255
264
  return !actual.to_s.match(expected).nil?
256
265
  elsif expected.is_a?(String) && integer?(expected) && actual.is_a?(Integer)
257
266
  return actual.method(op).call(expected.to_i)
267
+ elsif expected.is_a?(String) && boolean?(expected) && [true, false].include?(actual)
268
+ return actual.method(op).call(to_boolean(expected))
258
269
  elsif expected.is_a?(Integer) && integer?(actual)
259
270
  return actual.to_i.method(op).call(expected)
260
271
  elsif expected.is_a?(Float) && float?(actual)
@@ -91,6 +91,18 @@ module Inspec::Resources
91
91
  end
92
92
  end
93
93
 
94
+ def suid
95
+ (mode & 04000) > 0
96
+ end
97
+
98
+ def sgid
99
+ (mode & 02000) > 0
100
+ end
101
+
102
+ def sticky
103
+ (mode & 01000) > 0
104
+ end
105
+
94
106
  def to_s
95
107
  "File #{source_path}"
96
108
  end
@@ -248,7 +248,8 @@ module Inspec::Resources
248
248
  installed = params['LoadState'] == 'loaded'
249
249
  # test via 'systemctl is-active service'
250
250
  # SubState values running
251
- running = params['SubState'] == 'running'
251
+ running = (params['ActiveState'] == 'active') ||
252
+ (params['SubState'] == 'running')
252
253
  # test via systemctl --quiet is-enabled
253
254
  # ActiveState values eg.g inactive, active
254
255
  enabled = %w{enabled static}.include? params['UnitFileState']
data/lib/resources/wmi.rb CHANGED
@@ -13,7 +13,8 @@ module Inspec::Resources
13
13
  name 'wmi'
14
14
  desc 'request wmi information'
15
15
  example "
16
- describe wmi('RSOP_SecuritySettingNumeric', {
16
+ describe wmi({
17
+ class: 'RSOP_SecuritySettingNumeric',
17
18
  namespace: 'root\\rsop\\computer',
18
19
  filter: 'KeyName = \'MinimumPasswordAge\' And precedence=1'
19
20
  }) do
@@ -24,13 +25,18 @@ module Inspec::Resources
24
25
  include ObjectTraverser
25
26
  attr_accessor :content
26
27
 
27
- def initialize(wmiclass, opts = {})
28
+ def initialize(wmiclass = nil, opts = nil)
28
29
  # verify that this resource is only supported on Windows
29
30
  return skip_resource 'The `windows_feature` resource is not supported on your OS.' unless inspec.os.windows?
30
31
 
31
- @wmiclass = wmiclass
32
- @wminamespace = opts[:namespace]
33
- @wmifilter = opts[:filter]
32
+ @options = opts || {}
33
+ # if wmiclass is not a hash, we have to handle deprecation behavior
34
+ if wmiclass.is_a?(Hash)
35
+ @options.merge!(wmiclass)
36
+ else
37
+ warn '[DEPRECATION] `wmi(\'wmiclass\')` is deprecated. Please use `wmi({class: \'wmiclass\'})` instead.'
38
+ @options[:class] = wmiclass
39
+ end
34
40
  end
35
41
 
36
42
  # returns nil, if not existant or value
@@ -40,36 +46,69 @@ module Inspec::Resources
40
46
  keys.shift if keys.is_a?(Array) && keys[0] == :[]
41
47
 
42
48
  # map all symbols to strings
43
- keys = keys.map(&:to_s) if keys.is_a?(Array)
49
+ keys = keys.map { |x| x.to_s.downcase } if keys.is_a?(Array)
44
50
 
45
51
  value(keys)
46
52
  end
47
53
 
48
54
  def value(key)
49
- extract_value(key, info)
55
+ extract_value(key, params)
50
56
  end
51
57
 
52
- def info
58
+ def params
53
59
  return @content if defined?(@content)
54
60
  @content = {}
55
61
 
56
- # we should abort execution, if wmi class is not given or wmi resource is
57
- # executed on a non-windows system
58
- return @content if @wmiclass.nil?
62
+ # abort if no options are available
63
+ return @content unless defined?(@options)
64
+
65
+ # filter for supported options
66
+ args = @options.select { |key, _value| [:class, :namespace, :query, :filter].include?(key) }
59
67
 
60
- # optional params
61
- cmd_namespace = "-namespace #{@wminamespace}" unless @wminamespace.nil?
62
- cmd_filter = "-filter \"#{@wmifilter}\"" unless @wmifilter.nil?
68
+ # convert to Get-WmiObject arguments
69
+ params = ''
70
+ args.each { |key, value| params += " -#{key} \"#{value}\"" }
71
+
72
+ # run wmi command and filter empty wmi
73
+ script = <<-EOH
74
+ Filter Aggregate
75
+ {
76
+ $arr = @{}
77
+ $_.properties | % {
78
+ $arr.Add($_.name, $_.value)
79
+ }
80
+ $arr
81
+ }
82
+ Get-WmiObject #{params} | Aggregate | ConvertTo-Json
83
+ EOH
63
84
 
64
85
  # run wmi command
65
- cmd = inspec.command("Get-WmiObject -class #{@wmiclass} #{cmd_namespace} #{cmd_filter} | ConvertTo-Json")
86
+ cmd = inspec.powershell(script)
66
87
  @content = JSON.parse(cmd.stdout)
88
+
89
+ # make all keys case-insensitive
90
+ @content = lowercase_keys(@content)
67
91
  rescue JSON::ParserError => _e
68
92
  @content
69
93
  end
70
94
 
71
95
  def to_s
72
- "WMI #{@wmiclass} where #{@wmifilter}"
96
+ "WMI with #{@options}"
97
+ end
98
+
99
+ private
100
+
101
+ def lowercase_keys(content)
102
+ if content.is_a?(Hash)
103
+ content.keys.each do |key|
104
+ new_key = key.to_s.downcase
105
+ content[new_key] = content.delete(key)
106
+ lowercase_keys(content[new_key])
107
+ end
108
+ elsif content.respond_to?(:each)
109
+ content.each { |item| lowercase_keys(item) }
110
+ end
111
+ content
73
112
  end
74
113
  end
75
114
  end
@@ -136,13 +136,11 @@ module Inspec
136
136
  end
137
137
 
138
138
  def mark_text(text)
139
- "\e[0;32m#{text}\e[0m"
139
+ "\e[0;36m#{text}\e[0m"
140
140
  end
141
141
 
142
142
  def headline(title)
143
- puts title
144
- title.each_char { print '-' }
145
- puts
143
+ puts "\n== #{title}\n\n"
146
144
  end
147
145
 
148
146
  def li(entry)
@@ -25,6 +25,13 @@ if node['platform_family'] != 'windows'
25
25
  content 'hello world'
26
26
  end
27
27
 
28
+ file '/tmp/sfile' do
29
+ mode '7765'
30
+ owner 'root'
31
+ group gid
32
+ content 'hello suid/sgid/sticky'
33
+ end
34
+
28
35
  directory '/tmp/folder' do
29
36
  mode '0567'
30
37
  owner 'root'
@@ -80,8 +80,8 @@ describe 'inspec exec with json formatter' do
80
80
  actual = ex1.dup
81
81
 
82
82
  src = actual.delete('source_location')
83
- src[0].must_match %r{examples/profile/controls/example.rb$}
84
- src[1].must_equal 8
83
+ src['ref'].must_match %r{examples/profile/controls/example.rb$}
84
+ src['line'].must_equal 8
85
85
 
86
86
  result = actual.delete('results')[0]
87
87
  result.wont_be :nil?
@@ -18,7 +18,7 @@ describe 'inspec exec' do
18
18
  \e[37m ○ gordon-1.0: Verify the version number of Gordon (1 skipped)\e[0m
19
19
  \e[37m Can't find file \"/tmp/gordon/config.yaml\"\e[0m
20
20
  "
21
- stdout.must_include "\nSummary: 4 successful 0 failures 1 skipped\n"
21
+ stdout.must_include "\nSummary: \e[32m4 successful\e[0m, \e[31m0 failures\e[0m, \e[37m1 skipped\e[0m\n"
22
22
  end
23
23
 
24
24
  it 'executes a minimum metadata-only profile' do
@@ -32,7 +32,7 @@ Target: local://
32
32
 
33
33
  No tests executed.\e[0m
34
34
 
35
- Summary: 0 successful 0 failures 0 skipped
35
+ Summary: \e[32m0 successful\e[0m, \e[31m0 failures\e[0m, \e[37m0 skipped\e[0m
36
36
  "
37
37
  end
38
38
 
@@ -47,7 +47,7 @@ Target: local://
47
47
 
48
48
  No tests executed.\e[0m
49
49
 
50
- Summary: 0 successful 0 failures 0 skipped
50
+ Summary: \e[32m0 successful\e[0m, \e[31m0 failures\e[0m, \e[37m0 skipped\e[0m
51
51
  "
52
52
  end
53
53
 
@@ -66,7 +66,7 @@ Target: local://
66
66
  \n (compared using ==)
67
67
  \e[0m
68
68
 
69
- Summary: 1 successful 1 failures 1 skipped
69
+ Summary: \e[32m1 successful\e[0m, \e[31m1 failures\e[0m, \e[37m1 skipped\e[0m
70
70
  "
71
71
  end
72
72
 
@@ -74,14 +74,14 @@ Summary: 1 successful 1 failures 1 skipped
74
74
  out = inspec('exec ' + example_profile + ' --controls tmp-1.0')
75
75
  out.stderr.must_equal ''
76
76
  out.exit_status.must_equal 0
77
- out.stdout.must_include "\nSummary: 1 successful 0 failures 0 skipped\n"
77
+ out.stdout.must_include "\nSummary: \e[32m1 successful\e[0m, \e[31m0 failures\e[0m, \e[37m0 skipped\e[0m\n"
78
78
  end
79
79
 
80
80
  it 'can execute a simple file with the default formatter' do
81
81
  out = inspec('exec ' + example_control)
82
82
  out.stderr.must_equal ''
83
83
  out.exit_status.must_equal 0
84
- out.stdout.must_include 'Summary: 2 successful 0 failures 0 skipped'
84
+ out.stdout.must_include "\nSummary: \e[32m2 successful\e[0m, \e[31m0 failures\e[0m, \e[37m0 skipped\e[0m\n"
85
85
  end
86
86
 
87
87
  describe 'with a profile that is not supported on this OS/platform' do
@@ -67,7 +67,8 @@ describe 'inspec json' do
67
67
 
68
68
  it 'has a source location' do
69
69
  loc = File.join(example_profile, '/controls/example.rb')
70
- control['source_location'].must_equal [loc, 8]
70
+ control['source_location']['ref'].must_equal loc
71
+ control['source_location']['line'].must_equal 8
71
72
  end
72
73
 
73
74
  it 'has a the source code' do
@@ -26,10 +26,11 @@ describe 'command tests' do
26
26
  out.stderr.must_equal ''
27
27
  out.exit_status.must_equal 0
28
28
  std = out.stdout
29
- std.must_include 'Name:'
30
- std.must_include 'Family:'
31
- std.must_include 'Arch:'
32
- std.must_include 'Release:'
29
+ std.must_include "\n== Operating System Details\n\n"
30
+ std.must_include "\nName: \e[0;36m"
31
+ std.must_include "\nFamily: \e[0;36m"
32
+ std.must_include "\nArch: \e[0;36m"
33
+ std.must_include "\nRelease: \e[0;36m"
33
34
  end
34
35
  end
35
36
 
data/test/helper.rb CHANGED
@@ -243,7 +243,7 @@ class MockLoader
243
243
  # xinetd configuration
244
244
  'find /etc/xinetd.d -type f' => cmd.call('find-xinetd.d'),
245
245
  # wmi test
246
- "Get-WmiObject -class win32_service -filter \"name like '%winrm%'\" | ConvertTo-Json" => cmd.call('get-wmiobject'),
246
+ "4762fab9e8180997634ae70aae6d5f59e641084111fb9f5e5bf2848a583aa5f5" => cmd.call('get-wmiobject'),
247
247
  #user info on hpux
248
248
  "logins -x -l root" => cmd.call('logins-x'),
249
249
  #packages on hpux
@@ -100,4 +100,16 @@ if os.linux?
100
100
  it { should_not cmp < 3 }
101
101
  it { should_not cmp /something/ }
102
102
  end
103
+
104
+ describe true do
105
+ it { should cmp 'true' }
106
+ it { should cmp 'True' }
107
+ it { should cmp true }
108
+ end
109
+
110
+ describe false do
111
+ it { should cmp 'false' }
112
+ it { should cmp 'False' }
113
+ it { should cmp false }
114
+ end
103
115
  end
@@ -61,6 +61,9 @@ if os.unix?
61
61
  it { should be_mode 00765 }
62
62
  its('mode') { should cmp 0765 }
63
63
  its('mode') { should_not cmp 0777 }
64
+ its('suid') { should eq false }
65
+ its('sgid') { should eq false }
66
+ its('sticky') { should eq false }
64
67
 
65
68
  it { should be_readable }
66
69
  it { should be_readable.by('owner') }
@@ -107,6 +110,12 @@ if os.unix?
107
110
  its('type') { should eq :file }
108
111
  end
109
112
 
113
+ describe file('/tmp/file') do
114
+ its('suid') { should eq true }
115
+ its('sgid') { should eq true }
116
+ its('sticky') { should eq true }
117
+ end
118
+
110
119
  describe file('/tmp/folder') do
111
120
  it { should exist }
112
121
  it { should be_directory }
@@ -2,27 +2,62 @@
2
2
 
3
3
  return unless os.windows?
4
4
 
5
- # Get-WmiObject win32_service
6
- # Get-WmiObject -class win32_service
5
+ # Get-WmiObject win32_service or Get-WmiObject -class win32_service
7
6
  # returns an array of service objects
8
- describe wmi('win32_service') do
9
- its(['Path','ClassName']) { should include 'Win32_Service' }
7
+ describe wmi({class: 'win32_service'}) do
10
8
  its('DisplayName') { should include 'Windows Remote Management (WS-Management)'}
11
9
  end
12
10
 
13
- # Use win32_service with filter
14
- # this returns a single service object
15
- describe wmi('win32_service', {
11
+ # Use win32_service with filter, it returns a single service object
12
+ describe wmi({
13
+ class: 'win32_service',
16
14
  filter: "name like '%winrm%'"
17
15
  }) do
18
- its(['Path','ClassName']) { should eq 'Win32_Service' }
16
+ its('Status') { should cmp 'ok' }
17
+ its('State') { should cmp 'Running' }
18
+ its('ExitCode') { should cmp 0 }
19
19
  its('DisplayName') { should eq 'Windows Remote Management (WS-Management)'}
20
20
  end
21
21
 
22
22
  # TODO: this works on domain controllers only
23
+ describe wmi({
24
+ class: 'RSOP_SecuritySettingNumeric',
25
+ namespace: 'root\\rsop\\computer',
26
+ filter: 'KeyName = \'MinimumPasswordAge\' And precedence=1'
27
+ }) do
28
+ its('Setting') { should eq 1 }
29
+ end
30
+
31
+ # new syntax
32
+ describe wmi({
33
+ namespace: 'root\rsop\computer',
34
+ query: "SELECT Setting FROM RSOP_SecuritySettingBoolean WHERE KeyName='LSAAnonymousNameLookup' AND Precedence=1"
35
+ }) do
36
+ its('Setting') { should eq false }
37
+ end
38
+
39
+ describe wmi({
40
+ namespace: 'root\cimv2',
41
+ query: 'SELECT filesystem FROM win32_logicaldisk WHERE drivetype=3'
42
+ }).params.values.join do
43
+ it { should eq 'NTFS' }
44
+ end
45
+
46
+ # deprecated syntax
47
+ describe wmi('win32_service') do
48
+ its('DisplayName') { should include 'Windows Remote Management (WS-Management)'}
49
+ end
50
+
23
51
  describe wmi('RSOP_SecuritySettingNumeric', {
24
52
  namespace: 'root\\rsop\\computer',
25
53
  filter: 'KeyName = \'MinimumPasswordAge\' And precedence=1'
26
54
  }) do
27
55
  its('Setting') { should eq 1 }
56
+ its('setting') { should eq 1 }
57
+ end
58
+
59
+ describe wmi('win32_service', {
60
+ filter: "name like '%winrm%'"
61
+ }) do
62
+ its('DisplayName') { should eq 'Windows Remote Management (WS-Management)'}
28
63
  end
@@ -1,10 +1,9 @@
1
1
  {
2
- "Path": {
3
- "ClassName": "Win32_Service"
4
- },
5
- "Caption": "Windows Remote Management (WS-Management)",
6
- "CreationClassName": "Win32_Service",
7
2
  "DisplayName": "Windows Remote Management (WS-Management)",
3
+ "Caption": "Windows Remote Management (WS-Management)",
4
+ "DesktopInteract": false,
8
5
  "Name": "WinRM",
9
- "PathName": "C:\\Windows\\System32\\svchost.exe -k NetworkService"
6
+ "StartMode": "Auto",
7
+ "ExitCode": 0,
8
+ "Status": "OK"
10
9
  }
@@ -4,3 +4,4 @@ Description=OpenSSH server daemon
4
4
  LoadState=loaded
5
5
  UnitFileState=enabled
6
6
  SubState=running
7
+ ActiveState=active
@@ -51,7 +51,7 @@ describe 'Inspec::Resources::Service' do
51
51
  # ubuntu 15.04 with systemd
52
52
  it 'verify ubuntu package parsing' do
53
53
  resource = MockLoader.new(:ubuntu1504).load_resource('service', 'sshd')
54
- params = Hashie::Mash.new({ 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
54
+ params = Hashie::Mash.new({ 'ActiveState' => 'active', 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
55
55
  _(resource.type).must_equal 'systemd'
56
56
  _(resource.name).must_equal 'sshd.service'
57
57
  _(resource.description).must_equal 'OpenSSH server daemon'
@@ -64,7 +64,7 @@ describe 'Inspec::Resources::Service' do
64
64
 
65
65
  it 'verify ubuntu package parsing with default systemd_service' do
66
66
  resource = MockLoader.new(:ubuntu1504).load_resource('systemd_service', 'sshd')
67
- params = Hashie::Mash.new({ 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
67
+ params = Hashie::Mash.new({ 'ActiveState' => 'active', 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
68
68
  _(resource.type).must_equal 'systemd'
69
69
  _(resource.name).must_equal 'sshd.service'
70
70
  _(resource.description).must_equal 'OpenSSH server daemon'
@@ -103,7 +103,7 @@ describe 'Inspec::Resources::Service' do
103
103
  # centos 7 with systemd
104
104
  it 'verify centos 7 package parsing' do
105
105
  resource = MockLoader.new(:centos7).load_resource('service', 'sshd')
106
- params = Hashie::Mash.new({ 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
106
+ params = Hashie::Mash.new({ 'ActiveState' => 'active', 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
107
107
  _(resource.type).must_equal 'systemd'
108
108
  _(resource.name).must_equal 'sshd.service'
109
109
  _(resource.description).must_equal 'OpenSSH server daemon'
@@ -115,7 +115,7 @@ describe 'Inspec::Resources::Service' do
115
115
 
116
116
  it 'verify centos 7 package parsing with systemd_service and service_ctl override' do
117
117
  resource = MockLoader.new(:centos7).load_resource('systemd_service', 'sshd', '/path/to/systemctl')
118
- params = Hashie::Mash.new({ 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
118
+ params = Hashie::Mash.new({ 'ActiveState' => 'active', 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'UnitFileState' => 'enabled', 'SubState' => 'running' })
119
119
  _(resource.type).must_equal 'systemd'
120
120
  _(resource.name).must_equal 'sshd.service'
121
121
  _(resource.description).must_equal 'OpenSSH server daemon'
@@ -166,7 +166,7 @@ describe 'Inspec::Resources::Service' do
166
166
  # arch linux with systemd
167
167
  it 'verify arch linux package parsing' do
168
168
  resource = MockLoader.new(:arch).load_resource('service', 'sshd')
169
- params = Hashie::Mash.new({ 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
169
+ params = Hashie::Mash.new({ 'ActiveState' => 'active', 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
170
170
  _(resource.type).must_equal 'systemd'
171
171
  _(resource.name).must_equal 'sshd.service'
172
172
  _(resource.description).must_equal 'OpenSSH server daemon'
@@ -192,7 +192,7 @@ describe 'Inspec::Resources::Service' do
192
192
  # debian 8 with systemd
193
193
  it 'verify debian 8 package parsing' do
194
194
  resource = MockLoader.new(:debian8).load_resource('service', 'sshd')
195
- params = Hashie::Mash.new({ 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
195
+ params = Hashie::Mash.new({ 'ActiveState' => 'active', 'Description' => 'OpenSSH server daemon', 'Id' => 'sshd.service', 'LoadState' => 'loaded', 'Names' => 'sshd.service', 'SubState' => 'running', 'UnitFileState' => 'enabled' })
196
196
  _(resource.type).must_equal 'systemd'
197
197
  _(resource.name).must_equal 'sshd.service'
198
198
  _(resource.description).must_equal 'OpenSSH server daemon'
@@ -8,7 +8,8 @@ require 'inspec/resource'
8
8
  describe 'Inspec::Resources::WMI' do
9
9
 
10
10
  # Check the following as unit test
11
- # describe wmi('win32_service', {
11
+ # describe wmi({
12
+ # class: 'win32_service',
12
13
  # filter: "name like '%winrm%'"
13
14
  # }) do
14
15
  # its(['Path','ClassName']) { should eq 'Win32_Service' }
@@ -17,29 +18,25 @@ describe 'Inspec::Resources::WMI' do
17
18
 
18
19
  # windows
19
20
  it 'verify wmi parsing on windows' do
20
- resource = MockLoader.new(:windows).load_resource('wmi', 'win32_service', { filter: "name like '%winrm%'" })
21
+ resource = MockLoader.new(:windows).load_resource('wmi', {class: 'win32_service', filter: "name like '%winrm%'" })
21
22
  _(resource.send('DisplayName')).must_equal 'Windows Remote Management (WS-Management)'
22
- _(resource.send('method_missing', 'Path', 'ClassName')).must_equal 'Win32_Service'
23
23
  end
24
24
 
25
25
  # ubuntu 14.04 with upstart
26
26
  it 'fail wmi on ubuntu' do
27
- resource = MockLoader.new(:ubuntu1404).load_resource('wmi', 'win32_service', { filter: "name like '%winrm%'" })
27
+ resource = MockLoader.new(:ubuntu1404).load_resource('wmi', {class: 'win32_service', filter: "name like '%winrm%'" })
28
28
  _(resource.send('DisplayName')).must_equal nil
29
- _(resource.send('method_missing', 'Path', 'ClassName')).must_equal nil
30
29
  end
31
30
 
32
31
  # centos 7 with systemd
33
32
  it 'fail wmi on centos' do
34
- resource = MockLoader.new(:centos7).load_resource('wmi', 'win32_service', { filter: "name like '%winrm%'" })
33
+ resource = MockLoader.new(:centos7).load_resource('wmi', {class: 'win32_service', filter: "name like '%winrm%'" })
35
34
  _(resource.send('DisplayName')).must_equal nil
36
- _(resource.send('method_missing', 'Path', 'ClassName')).must_equal nil
37
35
  end
38
36
 
39
37
  # unknown OS
40
38
  it 'fail wmi on unknown os' do
41
- resource = MockLoader.new(:undefined).load_resource('wmi', 'win32_service', { filter: "name like '%winrm%'" })
39
+ resource = MockLoader.new(:undefined).load_resource('wmi', {class: 'win32_service', filter: "name like '%winrm%'" })
42
40
  _(resource.send('DisplayName')).must_equal nil
43
- _(resource.send('method_missing', 'Path', 'ClassName')).must_equal nil
44
41
  end
45
42
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.27.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: 2016-06-16 00:00:00.000000000 Z
11
+ date: 2016-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.15.1
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '0.13'
22
+ version: '1.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.15.1
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '0.13'
32
+ version: '1.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: thor
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -240,10 +246,12 @@ files:
240
246
  - lib/bundles/inspec-compliance/cli.rb
241
247
  - lib/bundles/inspec-compliance/configuration.rb
242
248
  - lib/bundles/inspec-compliance/http.rb
249
+ - lib/bundles/inspec-compliance/images/cc-token.png
243
250
  - lib/bundles/inspec-compliance/support.rb
244
251
  - lib/bundles/inspec-compliance/target.rb
245
252
  - lib/bundles/inspec-compliance/test/integration/default/cli.rb
246
253
  - lib/bundles/inspec-init.rb
254
+ - lib/bundles/inspec-init/README.md
247
255
  - lib/bundles/inspec-init/cli.rb
248
256
  - lib/bundles/inspec-init/templates/profile/README.md
249
257
  - lib/bundles/inspec-init/templates/profile/controls/example.rb
@@ -413,7 +421,7 @@ files:
413
421
  - test/integration/default/apache_conf_spec.rb
414
422
  - test/integration/default/apt_spec.rb
415
423
  - test/integration/default/auditd_rules_spec.rb
416
- - test/integration/default/compare_matcher_spec.rb
424
+ - test/integration/default/cmp_matcher_spec.rb
417
425
  - test/integration/default/csv_spec.rb
418
426
  - test/integration/default/etc_group_spec.rb
419
427
  - test/integration/default/file_spec.rb
@@ -697,7 +705,7 @@ test_files:
697
705
  - test/integration/default/apache_conf_spec.rb
698
706
  - test/integration/default/apt_spec.rb
699
707
  - test/integration/default/auditd_rules_spec.rb
700
- - test/integration/default/compare_matcher_spec.rb
708
+ - test/integration/default/cmp_matcher_spec.rb
701
709
  - test/integration/default/csv_spec.rb
702
710
  - test/integration/default/etc_group_spec.rb
703
711
  - test/integration/default/file_spec.rb