inspec 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -8
  3. data/README.md +8 -39
  4. data/Rakefile +74 -9
  5. data/bin/inspec +66 -10
  6. data/docs/ctl_inspec.rst +7 -1
  7. data/docs/inspec_and_friends.rst +1 -1
  8. data/docs/resources.rst +51 -45
  9. data/examples/README.md +7 -0
  10. data/examples/kitchen-ansible/.kitchen.yml +25 -0
  11. data/examples/kitchen-ansible/Gemfile +20 -0
  12. data/examples/kitchen-ansible/README.md +53 -0
  13. data/examples/kitchen-ansible/files/nginx.repo +6 -0
  14. data/examples/kitchen-ansible/tasks/main.yml +16 -0
  15. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -0
  16. data/examples/{test-kitchen → kitchen-ansible}/test/integration/default/web_spec.rb +0 -0
  17. data/examples/{test-kitchen → kitchen-chef}/.kitchen.yml +1 -1
  18. data/examples/{test-kitchen → kitchen-chef}/Berksfile +0 -0
  19. data/examples/{test-kitchen → kitchen-chef}/Gemfile +1 -2
  20. data/examples/{test-kitchen → kitchen-chef}/README.md +1 -1
  21. data/examples/{test-kitchen → kitchen-chef}/metadata.rb +0 -0
  22. data/examples/{test-kitchen → kitchen-chef}/recipes/default.rb +0 -0
  23. data/examples/{test-kitchen → kitchen-chef}/recipes/nginx.rb +0 -0
  24. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -0
  25. data/examples/kitchen-puppet/.kitchen.yml +22 -0
  26. data/examples/kitchen-puppet/Gemfile +21 -0
  27. data/examples/kitchen-puppet/Puppetfile +25 -0
  28. data/examples/kitchen-puppet/README.md +53 -0
  29. data/examples/kitchen-puppet/manifests/site.pp +33 -0
  30. data/examples/kitchen-puppet/metadata.json +11 -0
  31. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -0
  32. data/inspec.gemspec +2 -0
  33. data/lib/inspec/plugins/resource.rb +21 -0
  34. data/lib/inspec/shell.rb +73 -11
  35. data/lib/inspec/version.rb +1 -1
  36. data/lib/matchers/matchers.rb +43 -0
  37. data/lib/resources/apache_conf.rb +12 -9
  38. data/lib/resources/apt.rb +7 -0
  39. data/lib/resources/audit_policy.rb +6 -6
  40. data/lib/resources/auditd_conf.rb +6 -7
  41. data/lib/resources/auditd_rules.rb +9 -8
  42. data/lib/resources/bond.rb +6 -6
  43. data/lib/resources/bridge.rb +7 -0
  44. data/lib/resources/command.rb +10 -8
  45. data/lib/resources/csv.rb +6 -5
  46. data/lib/resources/directory.rb +6 -0
  47. data/lib/resources/etc_group.rb +9 -1
  48. data/lib/resources/file.rb +72 -61
  49. data/lib/resources/gem.rb +6 -4
  50. data/lib/resources/group.rb +7 -0
  51. data/lib/resources/host.rb +6 -0
  52. data/lib/resources/inetd_conf.rb +8 -8
  53. data/lib/resources/ini.rb +6 -6
  54. data/lib/resources/interface.rb +8 -8
  55. data/lib/resources/iptables.rb +6 -0
  56. data/lib/resources/json.rb +6 -5
  57. data/lib/resources/kernel_module.rb +6 -5
  58. data/lib/resources/kernel_parameter.rb +6 -4
  59. data/lib/resources/limits_conf.rb +6 -6
  60. data/lib/resources/login_def.rb +6 -0
  61. data/lib/resources/mysql_conf.rb +6 -0
  62. data/lib/resources/mysql_session.rb +7 -0
  63. data/lib/resources/npm.rb +6 -4
  64. data/lib/resources/ntp_conf.rb +7 -7
  65. data/lib/resources/oneget.rb +6 -0
  66. data/lib/resources/os.rb +8 -0
  67. data/lib/resources/os_env.rb +6 -0
  68. data/lib/resources/package.rb +8 -1
  69. data/lib/resources/parse_config.rb +14 -0
  70. data/lib/resources/passwd.rb +7 -0
  71. data/lib/resources/pip.rb +6 -0
  72. data/lib/resources/port.rb +22 -11
  73. data/lib/resources/postgres_conf.rb +6 -0
  74. data/lib/resources/postgres_session.rb +8 -0
  75. data/lib/resources/processes.rb +17 -1
  76. data/lib/resources/registry_key.rb +7 -0
  77. data/lib/resources/script.rb +11 -0
  78. data/lib/resources/security_policy.rb +6 -1
  79. data/lib/resources/service.rb +10 -0
  80. data/lib/resources/ssh_conf.rb +6 -0
  81. data/lib/resources/user.rb +9 -2
  82. data/lib/resources/windows_feature.rb +6 -0
  83. data/lib/resources/yaml.rb +6 -0
  84. data/lib/resources/yum.rb +7 -0
  85. data/lib/utils/find_files.rb +15 -7
  86. data/test/helper.rb +9 -0
  87. data/test/integration/.kitchen.yml +3 -0
  88. data/test/integration/test/integration/default/compare_matcher_spec.rb +19 -0
  89. data/test/integration/test/integration/default/etc_group.rb +13 -0
  90. data/test/integration/test/integration/default/os_spec.rb +13 -0
  91. data/test/integration/test/integration/default/port_spec.rb +1 -1
  92. data/test/unit/mock/cmd/find-apache2-conf-enabled +1 -0
  93. data/test/unit/mock/cmd/find-apache2-ports-conf +1 -0
  94. data/test/unit/mock/cmd/ps-aux +2 -0
  95. data/test/unit/mock/files/apache2.conf +14 -0
  96. data/test/unit/mock/files/ports.conf +6 -0
  97. data/test/unit/mock/files/serve-cgi-bin.conf +20 -0
  98. data/test/unit/resources/apache_conf_test.rb +31 -0
  99. data/test/unit/resources/file_test.rb +181 -0
  100. data/test/unit/resources/package_test.rb +9 -0
  101. data/test/unit/resources/port_test.rb +33 -13
  102. data/test/unit/resources/processes_test.rb +6 -0
  103. data/test/unit/resources/service_test.rb +10 -0
  104. data/test/unit/resources/user_test.rb +12 -0
  105. data/test/unit/utils/find_files_test.rb +23 -0
  106. metadata +61 -16
  107. data/bin/inspec.orig +0 -115
  108. data/lib/resources/.service.rb.swp +0 -0
  109. data/test/unit/mock/profiles/rules/metadata.rb +0 -2
  110. data/test/unit/mock/profiles/rules/test/test.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3fc1943a4f7b887acce7a49336b5d32aef1e4847
4
- data.tar.gz: 88da833cba32da598a683bd1fff826caf2809af2
3
+ metadata.gz: 2a0409ea39853cce8b89f828d6c639c48c0adfe4
4
+ data.tar.gz: a424f575ac78ec70775f6d84d577330f278be8fc
5
5
  SHA512:
6
- metadata.gz: c2d297e8107586f5657e7fb77e4973153e1beb9f1ad2d5f31db4135cb56006a5b8e311edc4d6a2e7f4cfbdb37db3bb26cb4337e550d5d9e3b5be8ffbc845a386
7
- data.tar.gz: 3943ace22dbed7065268d871c5dfd5b4e46048d3c33474a2938e6e65619db190ded570559f3b1256a9c5fdc998dfea8fc841b8796e5f3665178f144fd0cca988
6
+ metadata.gz: 4be07873774b1a7b9bb11160c9078d004808aaad09be4c91841cc5af5e4a896d0d3c5f6c83d184fadd88048e26c4611ff26e688bc499149e32b91c66fca27071
7
+ data.tar.gz: a11ee4ab19c53b5c7f8e3a8d30a1047655ffe62d562a8874818bb29050005e7cb917c7e7d93fd8e396535147530aae450ce24f4f31c36f5c7415c029362c9d83
@@ -1,15 +1,65 @@
1
1
  # Change Log
2
2
 
3
- ## [0.9.5](https://github.com/chef/inspec/tree/0.9.5) (2015-11-25)
4
- [Full Changelog](https://github.com/chef/inspec/compare/v0.9.4...0.9.5)
3
+ ## [0.9.6](https://github.com/chef/inspec/tree/0.9.6) (2015-12-11)
4
+ [Full Changelog](https://github.com/chef/inspec/compare/v0.9.5...0.9.6)
5
5
 
6
6
  **Implemented enhancements:**
7
7
 
8
- - Support the -i switch for key files as per ssh? [\#261](https://github.com/chef/inspec/issues/261)
8
+ - JSON configuration [\#292](https://github.com/chef/inspec/issues/292)
9
+ - Replace the `pry... ` bits in inspec shell [\#267](https://github.com/chef/inspec/issues/267)
10
+ - Better wording for check [\#260](https://github.com/chef/inspec/issues/260)
11
+ - OS resource with string and symbol support [\#227](https://github.com/chef/inspec/issues/227)
12
+ - matcher for less-restrictive comparison [\#318](https://github.com/chef/inspec/pull/318) ([chris-rock](https://github.com/chris-rock))
13
+ - add readme to examples [\#313](https://github.com/chef/inspec/pull/313) ([chris-rock](https://github.com/chris-rock))
14
+ - Minor `inspec shell` improvements [\#283](https://github.com/chef/inspec/pull/283) ([srenatus](https://github.com/srenatus))
15
+ - add kitchen-ansible inspec example [\#275](https://github.com/chef/inspec/pull/275) ([alexpop](https://github.com/alexpop))
16
+ - add kitchen-puppet example with inspec testing [\#273](https://github.com/chef/inspec/pull/273) ([alexpop](https://github.com/alexpop))
17
+ - Feature: Add shell `help resource` command [\#269](https://github.com/chef/inspec/pull/269) ([chris-rock](https://github.com/chris-rock))
18
+
19
+ **Fixed bugs:**
20
+
21
+ - auditd\_conf parameters should be case insensitive [\#307](https://github.com/chef/inspec/issues/307)
22
+ - Processes resource doesn't handle user or state [\#295](https://github.com/chef/inspec/issues/295)
23
+ - JSON configuration [\#292](https://github.com/chef/inspec/issues/292)
24
+ - Windows file matcher does not match existing files [\#288](https://github.com/chef/inspec/issues/288)
25
+ - Inspec hangs when executing some windows profiles against linux machine [\#279](https://github.com/chef/inspec/issues/279)
26
+ - Utils::FindFiles doesn't work [\#276](https://github.com/chef/inspec/issues/276)
27
+ - etc\_group not implemented for centos [\#266](https://github.com/chef/inspec/issues/266)
28
+ - Port resource returns arrays [\#256](https://github.com/chef/inspec/issues/256)
29
+ - Custom resource not available, undefined local variable or method `gordon\_config` [\#232](https://github.com/chef/inspec/issues/232)
30
+ - File permission checks should return false unless file exists [\#301](https://github.com/chef/inspec/pull/301) ([adamleff](https://github.com/adamleff))
31
+ - remove json doc for windows\_feature [\#272](https://github.com/chef/inspec/pull/272) ([chris-rock](https://github.com/chris-rock))
32
+ - improvement: add etc\_group support for centos and add integration test [\#270](https://github.com/chef/inspec/pull/270) ([chris-rock](https://github.com/chris-rock))
33
+
34
+ **Merged pull requests:**
35
+
36
+ - Bugfix: Properly initialize script resource [\#316](https://github.com/chef/inspec/pull/316) ([chris-rock](https://github.com/chris-rock))
37
+ - improve shell prompt and help [\#315](https://github.com/chef/inspec/pull/315) ([chris-rock](https://github.com/chris-rock))
38
+ - port resource: array attributes, resource alternative [\#303](https://github.com/chef/inspec/pull/303) ([srenatus](https://github.com/srenatus))
39
+ - support string and symbol for os resource [\#299](https://github.com/chef/inspec/pull/299) ([chris-rock](https://github.com/chris-rock))
40
+ - \[resources/apache\_conf\]: add tests, fix bug [\#298](https://github.com/chef/inspec/pull/298) ([srenatus](https://github.com/srenatus))
41
+ - \[resources/processes\] add user\(s\), state\(s\) attribute [\#297](https://github.com/chef/inspec/pull/297) ([srenatus](https://github.com/srenatus))
42
+ - fix small grammar error [\#294](https://github.com/chef/inspec/pull/294) ([juliandunn](https://github.com/juliandunn))
43
+ - read config from file/stdin [\#293](https://github.com/chef/inspec/pull/293) ([srenatus](https://github.com/srenatus))
44
+ - revert to old find\_files interface [\#291](https://github.com/chef/inspec/pull/291) ([srenatus](https://github.com/srenatus))
45
+ - Adding support for Wind River Linux [\#289](https://github.com/chef/inspec/pull/289) ([adamleff](https://github.com/adamleff))
46
+ - travis workarounds [\#286](https://github.com/chef/inspec/pull/286) ([srenatus](https://github.com/srenatus))
47
+ - Support mint in the integration tests [\#281](https://github.com/chef/inspec/pull/281) ([artem-sidorenko](https://github.com/artem-sidorenko))
48
+ - align cli documentation with cli [\#278](https://github.com/chef/inspec/pull/278) ([chris-rock](https://github.com/chris-rock))
49
+ - Remove description of custom resource [\#277](https://github.com/chef/inspec/pull/277) ([chris-rock](https://github.com/chris-rock))
50
+ - add rake tasks for showing and bumping the version of inspec [\#265](https://github.com/chef/inspec/pull/265) ([arlimus](https://github.com/arlimus))
51
+
52
+ ## [v0.9.5](https://github.com/chef/inspec/tree/v0.9.5) (2015-11-25)
53
+ [Full Changelog](https://github.com/chef/inspec/compare/v0.9.4...v0.9.5)
54
+
55
+ **Implemented enhancements:**
56
+
57
+ - Support the -i switch for key files as per ssh [\#261](https://github.com/chef/inspec/issues/261)
9
58
  - Add -p alias for --port like ssh [\#263](https://github.com/chef/inspec/pull/263) ([alexmanly](https://github.com/alexmanly))
10
59
 
11
60
  **Merged pull requests:**
12
61
 
62
+ - 0.9.5 [\#264](https://github.com/chef/inspec/pull/264) ([arlimus](https://github.com/arlimus))
13
63
  - Add -i alias for --key\_files like ssh [\#262](https://github.com/chef/inspec/pull/262) ([jcreedcmu](https://github.com/jcreedcmu))
14
64
 
15
65
  ## [v0.9.4](https://github.com/chef/inspec/tree/v0.9.4) (2015-11-24)
@@ -19,13 +69,10 @@
19
69
 
20
70
  - registry\_key needs to be case insensitive [\#254](https://github.com/chef/inspec/issues/254)
21
71
  - User resource doesn't handle group names with spaces [\#238](https://github.com/chef/inspec/issues/238)
72
+ - inspec does not extract section name from test file header [\#182](https://github.com/chef/inspec/issues/182)
22
73
  - bugfix: user resources support for group with whitespace [\#258](https://github.com/chef/inspec/pull/258) ([chris-rock](https://github.com/chris-rock))
23
74
  - Bugfix: make registry\_key resource case-insensitive [\#255](https://github.com/chef/inspec/pull/255) ([alexpop](https://github.com/alexpop))
24
75
 
25
- **Closed issues:**
26
-
27
- - inspec does not extract section name from test file header [\#182](https://github.com/chef/inspec/issues/182)
28
-
29
76
  **Merged pull requests:**
30
77
 
31
78
  - 0.9.4 [\#259](https://github.com/chef/inspec/pull/259) ([arlimus](https://github.com/arlimus))
@@ -39,9 +86,12 @@
39
86
 
40
87
  - Support the control keyword, synonymous to rule [\#188](https://github.com/chef/inspec/issues/188)
41
88
 
42
- **Closed issues:**
89
+ **Fixed bugs:**
43
90
 
44
91
  - Multiple computed calls to describe aren't registered [\#246](https://github.com/chef/inspec/issues/246)
92
+
93
+ **Closed issues:**
94
+
45
95
  - port resource does not work on CentOS [\#239](https://github.com/chef/inspec/issues/239)
46
96
  - os\_env not working [\#236](https://github.com/chef/inspec/issues/236)
47
97
  - service resource misbehaves on upstart hosts [\#226](https://github.com/chef/inspec/issues/226)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # InSpec: Inspect Your Infrastructure
2
2
 
3
- InSpec is open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements.
3
+ InSpec is an open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements.
4
4
 
5
5
  ```ruby
6
6
  # Disallow insecure protocols by testing
@@ -92,7 +92,7 @@ end
92
92
 
93
93
  describe port(443) do
94
94
    it { should be_listening }
95
-   its('protocol') {should eq 'tcp'}
95
+   its('protocols') {should include 'tcp'}
96
96
  end
97
97
  ```
98
98
 
@@ -152,43 +152,6 @@ Which will provide you with:
152
152
  {"family":"ubuntu","release":"14.04","arch":null}
153
153
  ```
154
154
 
155
- ## Custom InSpec resources
156
-
157
- You can easily create your own resources. Here is a custom resource for an
158
- application called Gordon. It is saved as `gordon_config.rb`.
159
-
160
- ```ruby
161
- require 'yaml'
162
-
163
- class GordonConfig < Inspec.resource(1)
164
- name 'gordon_config'
165
-
166
- def initialize
167
- @path = '/etc/gordon/config.yaml'
168
- @config = inspec.file(@path).content
169
- @params = YAML.load(@config)
170
- end
171
-
172
- def method_missing(name)
173
- @params[name.to_s]
174
- end
175
- end
176
- ```
177
-
178
- Include this file in your `test.rb`:
179
-
180
- ```ruby
181
- require_relative 'gordon_config'
182
- ```
183
-
184
- Now you can start using your new resource:
185
-
186
- ```ruby
187
- describe gordon_config do
188
- its('Version') { should eq('1.0') }
189
- end
190
- ```
191
-
192
155
  ## Documentation
193
156
 
194
157
  Documentation is available: https://github.com/chef/inspec/tree/master/docs
@@ -221,6 +184,12 @@ We perform `unit`, `resource` and `integration` tests.
221
184
  bundle exec rake test
222
185
  ```
223
186
 
187
+ If you like to run only one test, use
188
+
189
+ ```bash
190
+ bundle exec ruby -W -Ilib:test test/unit/resources/user_test.rb
191
+ ```
192
+
224
193
  ### Resource tests
225
194
 
226
195
  Resource tests make sure the backend execution layer behaves as expected. These tests will take a while, as a lot of different operating systems and configurations are being tested.
data/Rakefile CHANGED
@@ -48,14 +48,79 @@ namespace :test do
48
48
  end
49
49
  end
50
50
 
51
- # Automatically generate a changelog for this project. Only loaded if
52
- # the necessary gem is installed.
53
- begin
54
- require 'github_changelog_generator/task'
55
- require_relative 'lib/inspec/version'
56
- GitHubChangelogGenerator::RakeTask.new :changelog do |config|
57
- config.since_tag = '0.7.0'
58
- config.future_release = Inspec::VERSION
51
+ # Print the current version of this gem or update it.
52
+ #
53
+ # @param [Type] target the new version you want to set, or nil if you only want to show
54
+ def inspec_version(target = nil)
55
+ path = 'lib/inspec/version.rb'
56
+ require_relative path.sub(/.rb$/, '')
57
+
58
+ nu_version = target.nil? ? '' : " -> #{target}"
59
+ puts "Inspec: #{Inspec::VERSION}#{nu_version}"
60
+
61
+ unless target.nil?
62
+ raw = File.read(path)
63
+ nu = raw.sub(/VERSION.*/, "VERSION = '#{target}'")
64
+ File.write(path, nu)
65
+ load(path)
59
66
  end
60
- rescue LoadError
67
+ end
68
+
69
+ # Check if a command is available
70
+ #
71
+ # @param [Type] x the command you are interested in
72
+ # @param [Type] msg the message to display if the command is missing
73
+ def require_command(x, msg = nil)
74
+ return if system("command -v #{x} || exit 1")
75
+ msg ||= 'Please install it first!'
76
+ puts "\033[31;1mCan't find command #{x.inspect}. #{msg}\033[0m"
77
+ exit 1
78
+ end
79
+
80
+ # Check if a required environment variable has been set
81
+ #
82
+ # @param [String] x the variable you are interested in
83
+ # @param [String] msg the message you want to display if the variable is missing
84
+ def require_env(x, msg = nil)
85
+ exists = `env | grep "^#{x}="`
86
+ return unless exists.empty?
87
+ puts "\033[31;1mCan't find environment variable #{x.inspect}. #{msg}\033[0m"
88
+ exit 1
89
+ end
90
+
91
+ # Check the requirements for running an update of this repository.
92
+ def check_update_requirements
93
+ require_command 'git'
94
+ require_command 'github_changelog_generator', "\n"\
95
+ "For more information on how to install it see:\n"\
96
+ " https://github.com/skywinder/github-changelog-generator\n"
97
+ require_env 'CHANGELOG_GITHUB_TOKEN', "\n"\
98
+ "Please configure this token to make sure you can run all commands\n"\
99
+ "against GitHub.\n\n"\
100
+ "See github_changelog_generator homepage for more information:\n"\
101
+ " https://github.com/skywinder/github-changelog-generator\n"
102
+ end
103
+
104
+ # Show the current version of this gem.
105
+ desc 'Show the version of this gem'
106
+ task :version do
107
+ inspec_version
108
+ end
109
+
110
+ desc 'Generate the changelog'
111
+ task :changelog do
112
+ require_relative 'lib/inspec/version'
113
+ system "github_changelog_generator -u chef -p inspec --future-release #{Inspec::VERSION} --since-tag 0.7.0"
114
+ end
115
+
116
+ # Update the version of this gem and create an updated
117
+ # changelog. It covers everything short of actually releasing
118
+ # the gem.
119
+ desc 'Bump the version of this gem'
120
+ task :bump_version, [:version] do |_, args|
121
+ v = args[:version] || ENV['to']
122
+ fail "You must specify a target version! rake release[1.2.3]" if v.empty?
123
+ check_update_requirements
124
+ inspec_version(v)
125
+ Rake::Task['changelog'].invoke
61
126
  end
data/bin/inspec CHANGED
@@ -6,9 +6,13 @@
6
6
 
7
7
  require 'thor'
8
8
  require 'json'
9
+ require 'pp'
9
10
  require_relative '../lib/inspec'
10
11
 
11
- class InspecCLI < Thor
12
+ class InspecCLI < Thor # rubocop:disable Metrics/ClassLength
13
+ class_option :diagnose, type: :boolean,
14
+ desc: 'Show diagnostics (versions, configurations)'
15
+
12
16
  def self.target_options
13
17
  option :target, aliases: :t, type: :string, default: nil,
14
18
  desc: 'Simple targeting option using URIs, e.g. ssh://user:pass@host:port'
@@ -36,16 +40,20 @@ class InspecCLI < Thor
36
40
  desc: 'Use SSL for transport layer encryption (WinRM).'
37
41
  option :self_signed, type: :boolean, default: false,
38
42
  desc: 'Allow remote scans with self-signed certificates (WinRM).'
43
+ option :json_config, type: :string,
44
+ desc: 'Read configuration from JSON file (`-` reads from stdin).'
39
45
  end
40
46
 
41
- desc 'json PATH', 'read all tests in PATH and generate a JSON profile'
47
+ desc 'json PATH', 'read all tests in PATH and generate a JSON summary'
42
48
  option :id, type: :string,
43
49
  desc: 'Attach a profile ID to all test results'
44
50
  option :output, aliases: :o, type: :string,
45
51
  desc: 'Save the created profile to a path'
46
52
  def json(path)
47
- profile = Inspec::Profile.from_path(path, options)
48
- dst = options[:output].to_s
53
+ diagnose
54
+
55
+ profile = Inspec::Profile.from_path(path, opts)
56
+ dst = opts[:output].to_s
49
57
  if dst.empty?
50
58
  puts JSON.pretty_generate(profile.info)
51
59
  else
@@ -59,21 +67,25 @@ class InspecCLI < Thor
59
67
  end
60
68
  end
61
69
 
62
- desc 'check PATH', 'verify test structure in PATH'
70
+ desc 'check PATH', 'verify all tests at the specified PATH'
63
71
  def check(path)
64
- o = options.dup
72
+ diagnose
73
+
74
+ o = opts.dup
65
75
  o[:logger] = Logger.new(STDOUT)
66
76
  profile = Inspec::Profile.from_path(path, o)
67
77
  exit 1 unless profile.check
68
78
  end
69
79
 
70
- desc 'exec PATHS', 'run all test files'
80
+ desc 'exec PATHS', 'run all test files at the specified PATH.'
71
81
  option :id, type: :string,
72
82
  desc: 'Attach a profile ID to all test results'
73
83
  target_options
74
84
  option :format, type: :string, default: 'progress'
75
85
  def exec(*tests)
76
- runner = Inspec::Runner.new(options)
86
+ diagnose
87
+
88
+ runner = Inspec::Runner.new(opts)
77
89
  runner.add_tests(tests)
78
90
  runner.run
79
91
  rescue RuntimeError => e
@@ -83,7 +95,9 @@ class InspecCLI < Thor
83
95
  desc 'detect', 'detect the target OS'
84
96
  target_options
85
97
  def detect
86
- runner = Inspec::Runner.new(options)
98
+ diagnose
99
+
100
+ runner = Inspec::Runner.new(opts)
87
101
  rel = File.join(File.dirname(__FILE__), *%w{.. lib utils detect.rb})
88
102
  detect_util = File.expand_path(rel)
89
103
  runner.add_tests([detect_util])
@@ -94,8 +108,11 @@ class InspecCLI < Thor
94
108
 
95
109
  desc 'shell', 'open an interactive debugging shell'
96
110
  target_options
111
+ option :format, type: :string, default: Inspec::NoSummaryFormatter, hide: true
97
112
  def shell_func
98
- runner = Inspec::Runner.new(options)
113
+ diagnose
114
+
115
+ runner = Inspec::Runner.new(opts)
99
116
  Inspec::Shell.new(runner).start
100
117
  rescue RuntimeError => e
101
118
  puts e.message
@@ -105,5 +122,44 @@ class InspecCLI < Thor
105
122
  def version
106
123
  puts Inspec::VERSION
107
124
  end
125
+
126
+ private
127
+
128
+ def diagnose
129
+ return unless opts['diagnose']
130
+ puts "InSpec version: #{Inspec::VERSION}"
131
+ puts "Train version: #{Train::VERSION}"
132
+ puts 'Command line configuration:'
133
+ pp options
134
+ puts 'JSON configuration file:'
135
+ pp options_json
136
+ puts 'Merged configuration:'
137
+ pp opts
138
+ puts
139
+ end
140
+
141
+ def opts
142
+ # argv overrides json
143
+ Thor::CoreExt::HashWithIndifferentAccess.new(options_json.merge(options))
144
+ end
145
+
146
+ def options_json
147
+ conffile = options['json_config']
148
+ @json ||= conffile ? read_config(conffile) : {}
149
+ end
150
+
151
+ def read_config(file)
152
+ if file == '-'
153
+ puts 'WARN: reading JSON config from standard input' if STDIN.tty?
154
+ config = STDIN.read
155
+ else
156
+ config = File.read(file)
157
+ end
158
+
159
+ JSON.load(config)
160
+ rescue JSON::ParserError => e
161
+ puts "Failed to load JSON configuration: #{e}\nConfig was: #{config.inspect}"
162
+ exit 1
163
+ end
108
164
  end
109
165
  InspecCLI.start(ARGV)
@@ -47,11 +47,17 @@ The following options may be used with any of the InSpec CLI subcommands:
47
47
  ``--user``
48
48
  The login user for remote scanning.
49
49
 
50
+ ``--json_config``
51
+ A JSON file containing configuration options. Use `--json_config=-` to read from standard input. The file's format corresponds to the command line argument options. For example, `{"host": "example.com", "sudo": true}` is equivalent to `--host=example.com --sudo`. Command line switches override the configuration file.
52
+
53
+ ``--diagnose``
54
+ Dump configuration values from a command line options, the configuration file, and the merged effective options.
55
+
50
56
 
51
57
 
52
58
  check
53
59
  =====================================================
54
- Use ``inspec check`` to run all tests at the specified path.
60
+ Use ``inspec check`` to verify all tests the specified path.
55
61
 
56
62
  Syntax
57
63
  -----------------------------------------------------
@@ -64,7 +64,7 @@ One of the key differences is that InSpec targets more user groups. It is optimi
64
64
  insecure SSHv1 connections anymore.
65
65
  "
66
66
  describe sshd_config do
67
- its('Protocol') { should eq('2') }
67
+ its('Protocol') { should cmp 2 }
68
68
  end
69
69
  end
70
70
 
@@ -258,7 +258,7 @@ A ``auditd_conf`` |inspec resource| block declares configuration settings that s
258
258
  .. code-block:: ruby
259
259
 
260
260
  describe auditd_conf('path') do
261
- its('keyword') { should eq 'value' }
261
+ its('keyword') { should cmp 'value' }
262
262
  end
263
263
 
264
264
  where
@@ -269,11 +269,12 @@ where
269
269
 
270
270
  Matchers
271
271
  -----------------------------------------------------
272
- This |inspec resource| matches any keyword that is listed in the ``auditd.conf`` configuration file:
272
+ This |inspec resource| matches any keyword that is listed in the ``auditd.conf`` configuration file. Since all option names and values are case insensitive for ``auditd_conf``, we recommend to compare values with `cmp` instead of the `eq`:
273
273
 
274
274
  .. code-block:: ruby
275
275
 
276
- its('log_format') { should eq 'raw' }
276
+ its('log_format') { should cmp 'raw' }
277
+ its('max_log_file') { should cmp 6 }
277
278
 
278
279
  Examples
279
280
  -----------------------------------------------------
@@ -284,20 +285,20 @@ The following examples show how to use this InSpec audit resource.
284
285
  .. code-block:: ruby
285
286
 
286
287
  describe auditd_conf do
287
- its('log_file') { should eq '/full/path/to/file' }
288
- its('log_format') { should eq 'raw' }
289
- its('flush') { should eq 'none' }
290
- its('freq') { should eq '1' }
291
- its('num_logs') { should eq '0' }
292
- its('max_log_file') { should eq '6' }
293
- its('max_log_file_action') { should eq 'email' }
294
- its('space_left') { should eq '2' }
295
- its('action_mail_acct') { should eq 'root' }
296
- its('space_left_action') { should eq 'email' }
297
- its('admin_space_left') { should eq '1' }
298
- its('admin_space_left_action') { should eq 'halt' }
299
- its('disk_full_action') { should eq 'halt' }
300
- its('disk_error_action') { should eq 'halt' }
288
+ its('log_file') { should cmp '/full/path/to/file' }
289
+ its('log_format') { should cmp 'raw' }
290
+ its('flush') { should cmp 'none' }
291
+ its('freq') { should cmp 1 }
292
+ its('num_logs') { should cmp 0 }
293
+ its('max_log_file') { should cmp 6 }
294
+ its('max_log_file_action') { should cmp 'email' }
295
+ its('space_left') { should cmp 2 }
296
+ its('action_mail_acct') { should cmp 'root' }
297
+ its('space_left_action') { should cmp 'email' }
298
+ its('admin_space_left') { should cmp 1 }
299
+ its('admin_space_left_action') { should cmp 'halt' }
300
+ its('disk_full_action') { should cmp 'halt' }
301
+ its('disk_error_action') { should cmp 'halt' }
301
302
  end
302
303
 
303
304
 
@@ -3176,10 +3177,10 @@ A ``port`` |inspec resource| block declares a port, and then depending on what n
3176
3177
 
3177
3178
  describe port(514) do
3178
3179
  it { should be_listening }
3179
- its('process') {should eq 'syslog'}
3180
+ its('processes') {should include 'syslog'}
3180
3181
  end
3181
3182
 
3182
- where the ``process`` returns the process listening on port 514.
3183
+ where the ``processes`` returns the processes listening on port 514.
3183
3184
 
3184
3185
  Matchers
3185
3186
  -----------------------------------------------------
@@ -3195,33 +3196,33 @@ The ``be_listening`` matcher tests if the port is listening for traffic:
3195
3196
 
3196
3197
  pid
3197
3198
  +++++++++++++++++++++++++++++++++++++++++++++++++++++
3198
- The ``pid`` matcher tests the process identifier (PID):
3199
+ The ``pids`` matcher tests the process identifier (PID):
3199
3200
 
3200
3201
  .. code-block:: ruby
3201
3202
 
3202
- its('pid') { should eq '27808' }
3203
+ its('pids') { should eq ['27808'] }
3203
3204
 
3204
3205
  process
3205
3206
  +++++++++++++++++++++++++++++++++++++++++++++++++++++
3206
- The ``process`` matcher tests if the named process is running on the system:
3207
+ The ``processes`` matcher tests if the named process is running on the system:
3207
3208
 
3208
3209
  .. code-block:: ruby
3209
3210
 
3210
- its('process') { should eq 'syslog' }
3211
+ its('processes') { should eq ['syslog'] }
3211
3212
 
3212
3213
  protocol
3213
3214
  +++++++++++++++++++++++++++++++++++++++++++++++++++++
3214
- The ``protocol`` matcher tests the Internet protocol: |icmp| (``'icmp'``), |tcp| (``'tcp'`` or ``'tcp6'``), or |udp| (``'udp'`` or ``'udp6'``):
3215
+ The ``protocols`` matcher tests the Internet protocol: |icmp| (``'icmp'``), |tcp| (``'tcp'`` or ``'tcp6'``), or |udp| (``'udp'`` or ``'udp6'``):
3215
3216
 
3216
3217
  .. code-block:: ruby
3217
3218
 
3218
- its('protocol') { should eq 'tcp' }
3219
+ its('protocols') { should eq ['tcp'] }
3219
3220
 
3220
3221
  or for the |ipv6| protocol:
3221
3222
 
3222
3223
  .. code-block:: ruby
3223
3224
 
3224
- its('protocol') { should eq 'tcp6' }
3225
+ its('protocols') { should eq ['tcp6'] }
3225
3226
 
3226
3227
  Examples
3227
3228
  -----------------------------------------------------
@@ -3233,7 +3234,7 @@ The following examples show how to use this InSpec audit resource.
3233
3234
 
3234
3235
  describe port(80) do
3235
3236
  it { should be_listening }
3236
- its('protocol') {should eq 'tcp'}
3237
+ its('protocols') {should eq ['tcp']}
3237
3238
  end
3238
3239
 
3239
3240
  **Test port 80, listening with TCP version IPv6 protocol**
@@ -3242,7 +3243,7 @@ The following examples show how to use this InSpec audit resource.
3242
3243
 
3243
3244
  describe port(80) do
3244
3245
  it { should be_listening }
3245
- its('protocol') {should eq 'tcp6'}
3246
+ its('protocols') {should eq ['tcp6']}
3246
3247
  end
3247
3248
 
3248
3249
  **Test ports for HTTPs**
@@ -3255,7 +3256,22 @@ The following examples show how to use this InSpec audit resource.
3255
3256
 
3256
3257
  describe port(443) do
3257
3258
  it { should be_listening }
3258
- its('protocol') {should eq 'tcp'}
3259
+ its('protocols') {should eq ['tcp']}
3260
+ end
3261
+
3262
+ **Test port 80 on a specific address**
3263
+
3264
+ This check can be implemented in two equivalent ways:
3265
+
3266
+ .. code-block:: ruby
3267
+
3268
+ describe port(80) do
3269
+ it { should be_listening }
3270
+ its('addresses') {should include '0.0.0.0'}
3271
+ end
3272
+
3273
+ describe port('0.0.0.0', 80) do
3274
+ it { should be_listening }
3259
3275
  end
3260
3276
 
3261
3277
  postgres_conf
@@ -3424,7 +3440,7 @@ A ``processes`` |inspec resource| block declares the name of the process to be t
3424
3440
  where
3425
3441
 
3426
3442
  * ``processes('process_name')`` must specify the name of a process that is running on the system
3427
- * Multiple properties may be tested; for each property to be tested, use an ``its('property_name')`` statement
3443
+ * The ``user`` and ``state`` properties may be tested; they are exposed via ``users`` and ``states``, respectively.
3428
3444
 
3429
3445
  Matchers
3430
3446
  -----------------------------------------------------
@@ -3466,7 +3482,7 @@ The following examples show how to use this InSpec audit resource.
3466
3482
  .. code-block:: ruby
3467
3483
 
3468
3484
  describe processes('init') do
3469
- its('user') { should eq 'root' }
3485
+ its('users') { should eq ['root'] }
3470
3486
  end
3471
3487
 
3472
3488
  **Test if a high-priority process is running**
@@ -3474,7 +3490,7 @@ The following examples show how to use this InSpec audit resource.
3474
3490
  .. code-block:: ruby
3475
3491
 
3476
3492
  describe processes('some_process') do
3477
- its('state') { should eq 'R<' }
3493
+ its('states') { should eq ['R<'] }
3478
3494
  end
3479
3495
 
3480
3496
 
@@ -3895,7 +3911,7 @@ The following examples show how to use this InSpec audit resource.
3895
3911
  .. code-block:: ruby
3896
3912
 
3897
3913
  describe sshd_config do
3898
- its('Protocol') { should eq '2' }
3914
+ its('Protocol') { should cmp 2 }
3899
3915
  end
3900
3916
 
3901
3917
  **Test ciphers**
@@ -3911,7 +3927,7 @@ The following examples show how to use this InSpec audit resource.
3911
3927
  .. code-block:: ruby
3912
3928
 
3913
3929
  describe sshd_config do
3914
- its('Port') { should eq '22' }
3930
+ its('Port') { should cmp 22 }
3915
3931
  its('UsePAM') { should eq 'yes' }
3916
3932
  its('ListenAddress') { should eq nil }
3917
3933
  its('HostKey') { should eq [
@@ -4084,20 +4100,10 @@ The |nginx| user is typically ``www-data``, but on |centos| it's ``nginx``. The
4084
4100
 
4085
4101
  windows_feature
4086
4102
  =====================================================
4087
- Use the ``windows_feature`` |inspec resource| to test features on |windows|. The ``Get-WindowsFeature`` cmdlet returns the following values: ``Property Name``, ``DisplayName``, ``Description``, ``Installed``, and ``InstallState``, returned as a |json| object similar to:
4103
+ Use the ``windows_feature`` |inspec resource| to test features on |windows|. It uses the ``Get-WindowsFeature`` cmdlet under the hood.
4088
4104
 
4089
4105
  **Stability: Experimental**
4090
4106
 
4091
- .. code-block:: javascript
4092
-
4093
- {
4094
- "Name": "XPS-Viewer",
4095
- "DisplayName": "XPS Viewer",
4096
- "Description": "The XPS Viewer reads, sets permissions, and digitally signs XPS documents.",
4097
- "Installed": false,
4098
- "InstallState": 0
4099
- }
4100
-
4101
4107
  Syntax
4102
4108
  -----------------------------------------------------
4103
4109
  A ``windows_feature`` |inspec resource| block declares the name of the |windows| feature, tests if that feature is installed, and then returns information about that feature: