inspec-core 2.2.35 → 2.2.41

Sign up to get free protection for your applications and to get access to all the features.
data/docs/reporters.md CHANGED
@@ -116,12 +116,12 @@ This reporter includes all information from the rspec runner. Unlike the json re
116
116
 
117
117
  This renders html code to view your tests in a browser. It includes all the test and summary information.
118
118
 
119
-
120
119
  ## Automate Reporter
121
120
 
122
121
  The automate reporter type is a special reporter used with the Automate 2 suite. To use this reporter you must pass in the correct configuration via a json config `--json-config`.
123
122
 
124
123
  Example config:
124
+
125
125
  ```json
126
126
  "reporter": {
127
127
  "automate" : {
@@ -135,27 +135,36 @@ Example config:
135
135
  }
136
136
  ```
137
137
 
138
- ### Mandatory fields:
138
+ ### Mandatory fields
139
+
139
140
  #### stdout
141
+
140
142
  This will either suppress or show the automate report in the CLI screen on completion
141
143
 
142
144
  #### url
145
+
143
146
  This is your Automate 2 url. Append `data-collector/v0/` at the end.
144
147
 
145
148
  #### token
149
+
146
150
  This is your Automate 2 token. You can generate this token by navigating to the admin tab of A2 and then api keys.
147
151
 
148
152
  ### Optional fields
153
+
149
154
  #### insecure
155
+
150
156
  This will disable or enable the ssl check when accessing the Automate 2 instance.
151
157
 
152
- PLEASE NOTE: These fields are ONLY needed if you do not have chef-client attached to a chef server running on your node. The fields below will be automaticlly pulled from the chef server.
158
+ PLEASE NOTE: These fields are ONLY needed if you do not have chef-client attached to a chef server running on your node. The fields below will be automatically pulled from the chef server.
153
159
 
154
160
  #### node_name
161
+
155
162
  This will be the node name which shows up in Automate 2.
156
163
 
157
164
  #### node_uuid
165
+
158
166
  This overrides the node uuid sent up to Automate 2. On non-chef nodes we will try to generate a static node uuid for you from your hardware. This will almost never be needed unless your working with a unique virtual setup.
159
167
 
160
168
  #### environment
161
- This will set the enviroment metadata for Automate 2.
169
+
170
+ This will set the environment metadata for Automate 2.
@@ -124,6 +124,34 @@ Wix includes several tools -- such as `candle` (preprocesses and compiles source
124
124
  end
125
125
  end
126
126
 
127
+ ### Redacting Sensitive Commands
128
+
129
+ By default the command that is ran is shown in the InSpec output. This can be problematic if the command contains sensitive arguments such as a password. These sensitive parts can be redacted by passing in `redact_regex` and a regular expression to redact. Optionally, you can use 2 capture groups to fine tune what is redacted.
130
+
131
+ The following examples show how to use `redact_regex`:
132
+
133
+ # Example without capture groups
134
+ describe command('myapp -p secretpassword -d no_redact', redact_regex: /-p .* -d/) do
135
+ its('exit_status') { should cmp 0 }
136
+ end
137
+
138
+ # Result (no capture groups used)
139
+ Command: `myapp REDACTED no_redact`
140
+ ✔ exit_status should cmp == 0
141
+
142
+ # Example with capture groups
143
+ # Each set of parenthesis is a capture group.
144
+ # Anything in the two capture groups will not be 'REDACTED'
145
+ describe command('myapp -p secretpassword -d no_redact', redact_regex: /(-p ).*( -d)/) do
146
+ its('exit_status') { should cmp 0 }
147
+ end
148
+
149
+ # Result (capture groups used)
150
+ Command: `myapp -p REDACTED -d no_redact`
151
+ ✔ exit_status should cmp == 0
152
+
153
+ > For more info/help on regular expressions, we recommend [RegExr](https://regexr.com/)
154
+
127
155
  <br>
128
156
 
129
157
  ## Matchers
@@ -149,10 +149,13 @@ The `name` matcher tests the value for the specified registry setting:
149
149
 
150
150
 
151
151
  <p class="warning">
152
- Any name with a dot will not work as expected: <code>its('explorer.exe') { should eq 'test' }</code>. This issue is tracked in <a href="https://github.com/chef/inspec/issues/1281">https://github.com/chef/inspec/issues/1281</a>
152
+ Any name with a dot will not work as expected: <code>its('explorer.exe') { should eq 'test' }</code>. For details, see <a href="https://github.com/inspec/inspec/issues/1281">https://github.com/inspec/inspec/issues/1281</a>
153
153
  </p>
154
154
 
155
155
  # instead of:
156
156
  # its('explorer.exe') { should eq 'test' }
157
- # use the following solution:
157
+ # either use have_property_value...
158
158
  it { should have_property_value('explorer.exe', :string, 'test') }
159
+
160
+ # ...or provide the parts of the dot-separated name in an array
161
+ its(['explorer', 'exe']) { should eq 'test' }
@@ -13,7 +13,7 @@ Use the `xinetd_conf` InSpec audit resource to test services under `/etc/xinet.d
13
13
 
14
14
  An `xinetd_conf` resource block declares settings found in a `xinetd.conf` file for the named service:
15
15
 
16
- describe xinetd_conf('service_name') do
16
+ describe xinetd_conf.services('service_name') do
17
17
  it { should be_enabled } # or be_disabled
18
18
  its('setting') { should eq 'value' }
19
19
  end
data/docs/ruby_usage.md CHANGED
@@ -61,7 +61,6 @@ to process the output of `ls` executed on the target system, use
61
61
  Similarly, use `inspec.file(PATH)` to access files or directories from
62
62
  remote systems in your tests or custom resources.
63
63
 
64
-
65
64
  ## Using rubygems
66
65
 
67
66
  Ruby gems are self-contained programs and libraries. If you create a custom
@@ -158,7 +157,8 @@ When writing tests you can not use standard ruby methods to shellout as it tries
158
157
  However, the `command` resource has a `.stdout` method that will allow you to manipulate the results.
159
158
  Using the above example, you could check the writes on several subdirectories.
160
159
 
161
- ### Example 1:
160
+ ### Example 1
161
+
162
162
  ```ruby
163
163
  $ inspec shell
164
164
  Welcome to the interactive InSpec Shell
@@ -179,7 +179,8 @@ Version: (not specified)
179
179
  Test Summary: 1 successful, 0 failures, 0 skipped
180
180
  ```
181
181
 
182
- ### Example 2:
182
+ ### Example 2
183
+
183
184
  ```ruby
184
185
  $ inspec shell
185
186
  Welcome to the interactive InSpec Shell
@@ -5,4 +5,8 @@
5
5
  libdir = File.dirname(__FILE__)
6
6
  $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
7
7
 
8
+ module Init
9
+ autoload :Profile, 'inspec-init/profile'
10
+ end
11
+
8
12
  require 'inspec-init/cli'
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'pathname'
4
+ require_relative 'renderer'
4
5
 
5
6
  module Init
6
7
  class CLI < Inspec::BaseCLI
@@ -15,85 +16,21 @@ module Init
15
16
  namespace
16
17
  end
17
18
 
18
- # read template directoy
19
+ # Look in the 'template' directory, and register a subcommand
20
+ # for each template directory found there.
19
21
  template_dir = File.join(File.dirname(__FILE__), 'templates')
20
22
  Dir.glob(File.join(template_dir, '*')) do |template|
21
- relative = Pathname.new(template).relative_path_from(Pathname.new(template_dir))
23
+ template_name = Pathname.new(template).relative_path_from(Pathname.new(template_dir)).to_s
22
24
 
23
25
  # register command for the template
24
- desc "#{relative} NAME", "Create a new #{relative}"
26
+ desc "#{template_name} NAME", "Create a new #{template_name}"
25
27
  option :overwrite, type: :boolean, default: false,
26
- desc: 'Overwrites existing directory'
27
- define_method relative.to_s.to_sym do |name|
28
- generator(relative.to_s, { name: name }, options)
28
+ desc: 'Overwrites existing directory'
29
+ define_method template_name.to_sym do |name_for_new_structure|
30
+ renderer = Init::Renderer.new(self, options)
31
+ renderer.render_with_values(template_name, name: name_for_new_structure)
29
32
  end
30
33
  end
31
-
32
- private
33
-
34
- # 1. iterate over all files
35
- # 2. read content in erb
36
- # 3. write to target
37
- def generator(type, attributes = {}, options = {}) # rubocop:disable Metrics/AbcSize
38
- # path of this script
39
- dir = File.dirname(__FILE__)
40
- # look for template directory
41
- base_dir = File.join(dir, 'templates', type)
42
- # prepare glob for all subdirectories and files
43
- template = File.join(base_dir, '**', '{*,.*}')
44
- # Use the name attribute to define the path to the profile.
45
- profile_path = attributes[:name]
46
- # Use slashes (\, /) to split up the name into an Array then use the last entry
47
- # to reset the name of the profile.
48
- attributes[:name] = attributes[:name].split(%r{\\|\/}).last
49
- # Generate the full target path on disk
50
- target = Pathname.new(Dir.pwd).join(profile_path)
51
- puts "Create new #{type} at #{mark_text(target)}"
52
-
53
- # check that the directory does not exist
54
- if File.exist?(target) && !options['overwrite']
55
- error "#{mark_text(target)} exists already, use --overwrite"
56
- exit 1
57
- end
58
-
59
- # ensure that target directory is available
60
- FileUtils.mkdir_p(target)
61
-
62
- # iterate over files and write to target path
63
- Dir.glob(template) do |file|
64
- relative = Pathname.new(file).relative_path_from(Pathname.new(base_dir))
65
- destination = Pathname.new(target).join(relative)
66
- if File.directory?(file)
67
- li "Create directory #{mark_text(relative)}"
68
- FileUtils.mkdir_p(destination)
69
- elsif File.file?(file)
70
- li "Create file #{mark_text(relative)}"
71
- # read & render content
72
- content = render(File.read(file), attributes)
73
- # write file content
74
- File.write(destination, content)
75
- else
76
- puts "Ignore #{file}, because its not an file or directoy"
77
- end
78
- end
79
- end
80
-
81
- # This is a render helper to bind hash values to a ERB template
82
- def render(content, hash)
83
- # create a new binding class
84
- cls = Class.new do
85
- hash.each do |key, value|
86
- define_method key.to_sym do
87
- value
88
- end
89
- end
90
- # expose binding
91
- define_method :bind do
92
- binding
93
- end
94
- end
95
- ERB.new(content).result(cls.new.bind)
96
- end
97
34
  end
98
35
 
99
36
  # register the subcommand to Inspec CLI registry
@@ -0,0 +1,79 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+
4
+ module Init
5
+ class Renderer
6
+ # Creates a renderer able to render the given template type
7
+ # 1. iterate over all files
8
+ # 2. read content in erb
9
+ # 3. write to full_destination_root_path
10
+
11
+ attr_reader :overwrite_mode, :ui
12
+ def initialize(cli_ui, cli_options = {})
13
+ @ui = cli_ui
14
+ @overwrite_mode = cli_options['overwrite']
15
+ end
16
+
17
+ # rubocop: disable Metrics/AbcSize
18
+ def render_with_values(template_type, template_values = {})
19
+ # look for template directory
20
+ base_dir = File.join(File.dirname(__FILE__), 'templates', template_type)
21
+ # prepare glob for all subdirectories and files
22
+ template_glob = File.join(base_dir, '**', '{*,.*}')
23
+ # Use the name attribute to define the path to the profile.
24
+ profile_path = template_values[:name]
25
+ # Use slashes (\, /) to split up the name into an Array then use the last entry
26
+ # to reset the name of the profile.
27
+ template_values[:name] = template_values[:name].split(%r{\\|\/}).last
28
+ # Generate the full full_destination_root_path path on disk
29
+ full_destination_root_path = Pathname.new(Dir.pwd).join(profile_path)
30
+ ui.plain_text "Create new #{template_type} at #{ui.mark_text(full_destination_root_path)}"
31
+
32
+ # check that the directory does not exist
33
+ if File.exist?(full_destination_root_path) && !overwrite_mode
34
+ ui.plain_text "#{ui.mark_text(full_destination_root_path)} exists already, use --overwrite"
35
+ ui.exit(1)
36
+ end
37
+
38
+ # ensure that full_destination_root_path directory is available
39
+ FileUtils.mkdir_p(full_destination_root_path)
40
+
41
+ # iterate over files and write to full_destination_root_path
42
+ Dir.glob(template_glob) do |file|
43
+ relative_destination_item_path = Pathname.new(file).relative_path_from(Pathname.new(base_dir))
44
+ full_destination_item_path = Pathname.new(full_destination_root_path).join(relative_destination_item_path)
45
+ if File.directory?(file)
46
+ ui.li "Create directory #{ui.mark_text(relative_destination_item_path)}"
47
+ FileUtils.mkdir_p(full_destination_item_path)
48
+ elsif File.file?(file)
49
+ ui.li "Create file #{ui.mark_text(relative_destination_item_path)}"
50
+ # read & render content
51
+ content = render(File.read(file), template_values)
52
+ # write file content
53
+ File.write(full_destination_item_path, content)
54
+ else
55
+ ui.plain_text "Ignore #{file}, because its not an file or directoy"
56
+ end
57
+ end
58
+ end
59
+ # rubocop: enable Metrics/AbcSize
60
+
61
+ # This is a render helper to bind hash values to a ERB template
62
+ # ERB provides result_with_hash in ruby 2.5.0+, which does exactly this
63
+ def render(template_content, hash)
64
+ # create a new binding class
65
+ cls = Class.new do
66
+ hash.each do |key, value|
67
+ define_method key.to_sym do
68
+ value
69
+ end
70
+ end
71
+ # expose binding
72
+ define_method :bind do
73
+ binding
74
+ end
75
+ end
76
+ ERB.new(template_content).result(cls.new.bind)
77
+ end
78
+ end
79
+ end
@@ -210,6 +210,31 @@ module Inspec
210
210
  str
211
211
  end
212
212
 
213
+ # These need to be public methods on any BaseCLI instance,
214
+ # but Thor interprets all methods as subcommands. The no_commands block
215
+ # treats them as regular methods.
216
+ no_commands do
217
+ def mark_text(text)
218
+ "\e[0;36m#{text}\e[0m"
219
+ end
220
+
221
+ def headline(title)
222
+ puts "\n== #{title}\n\n"
223
+ end
224
+
225
+ def li(entry)
226
+ puts " #{mark_text('*')} #{entry}"
227
+ end
228
+
229
+ def exit(code)
230
+ Kernel.exit code
231
+ end
232
+
233
+ def plain_text(msg)
234
+ puts msg
235
+ end
236
+ end
237
+
213
238
  private
214
239
 
215
240
  def suppress_log_output?(opts)
@@ -363,17 +388,5 @@ module Inspec
363
388
  end
364
389
  o[:logger].level = get_log_level(o.log_level)
365
390
  end
366
-
367
- def mark_text(text)
368
- "\e[0;36m#{text}\e[0m"
369
- end
370
-
371
- def headline(title)
372
- puts "\n== #{title}\n\n"
373
- end
374
-
375
- def li(entry)
376
- puts " #{mark_text('*')} #{entry}"
377
- end
378
391
  end
379
392
  end
@@ -11,7 +11,14 @@ module Inspec
11
11
  end
12
12
 
13
13
  def to_ruby
14
- itsy = its.nil? ? 'it' : 'its(' + its.to_s.inspect + ')'
14
+ itsy = 'it'
15
+ unless its.nil?
16
+ if its.is_a? Array
17
+ itsy = 'its(' + its.inspect + ')'
18
+ else
19
+ itsy = 'its(' + its.to_s.inspect + ')'
20
+ end
21
+ end
15
22
  naughty = negated ? '_not' : ''
16
23
  xpect = if expectation.nil?
17
24
  ''
@@ -90,8 +90,8 @@ module Inspec
90
90
 
91
91
  def check_supports
92
92
  status = inspec.platform.supported?(@supports)
93
- skip_msg = "Resource #{@__resource_name__.capitalize} is not supported on platform #{inspec.platform.name}/#{inspec.platform.release}."
94
- skip_resource(skip_msg) unless status
93
+ fail_msg = "Resource #{@__resource_name__.capitalize} is not supported on platform #{inspec.platform.name}/#{inspec.platform.release}."
94
+ fail_resource(fail_msg) unless status
95
95
  status
96
96
  end
97
97
 
@@ -4,5 +4,5 @@
4
4
  # author: Christoph Hartmann
5
5
 
6
6
  module Inspec
7
- VERSION = '2.2.35'
7
+ VERSION = '2.2.41'
8
8
  end
@@ -22,11 +22,22 @@ module Inspec::Resources
22
22
 
23
23
  attr_reader :command
24
24
 
25
- def initialize(cmd)
25
+ def initialize(cmd, options = {})
26
26
  if cmd.nil?
27
27
  raise 'InSpec `command` was called with `nil` as the argument. This is not supported. Please provide a valid command instead.'
28
28
  end
29
+
29
30
  @command = cmd
31
+
32
+ if options[:redact_regex]
33
+ unless options[:redact_regex].is_a?(Regexp)
34
+ # Make sure command is replaced so sensitive output isn't shown
35
+ @command = 'ERROR'
36
+ raise Inspec::Exceptions::ResourceFailed,
37
+ 'The `redact_regex` option must be a regular expression'
38
+ end
39
+ @redact_regex = options[:redact_regex]
40
+ end
30
41
  end
31
42
 
32
43
  def result
@@ -67,7 +78,11 @@ module Inspec::Resources
67
78
  end
68
79
 
69
80
  def to_s
70
- "Command #{@command}"
81
+ output = "Command: `#{@command}`"
82
+ # Redact output if the `redact_regex` option is passed
83
+ # If no capture groups are passed then `\1` and `\2` are ignored
84
+ output.gsub!(@redact_regex, '\1REDACTED\2') unless @redact_regex.nil?
85
+ output
71
86
  end
72
87
  end
73
88
  end