inspec 0.26.0 → 0.27.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 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