inspec-core 4.7.24 → 4.10.4

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
  SHA256:
3
- metadata.gz: d8ebdd6aaafd9ef4f423418a420b3e46658f013f1f95c6117be5d1a19ae9a609
4
- data.tar.gz: 8e11217be61503e5f478a30586aad4b9247752f37354caebf7746fa0483da8b0
3
+ metadata.gz: 431744ec266e2ed0cbde565cc232ee4bb944ff76076d8c10d381c73346796337
4
+ data.tar.gz: a8a844283829729c5a886a9e324e7fc22b31a986eb25e36c0a01fe7a26fbda78
5
5
  SHA512:
6
- metadata.gz: c4cee03272408e51c0870fd0dc2fca4e743a94a5d8f2d3f1b4d423540062c1f913c6971526cd3c5f647eb5e6ac617dd9722f6ecd3d4788c49ac5e130b1e022ac
7
- data.tar.gz: 269f2962d1011a85f72a80fa3d22ca59bc727cb4d8e197e2bc2bb4bddc1941cc097a59ee2272ed4a104107597a977756be27ceea638bb436ade579fd7a48b066
6
+ metadata.gz: 3678f2a31c972d7e6e08c3352249ce9bc72b82b7989a1758b70a3bdc41912cc0eb048bd70cc4da0794b929f53aacdfe6227e5defc13aeb3465cc5cc744393a8c
7
+ data.tar.gz: 5ded1f1c7315194f7ae8a791aea4e21221b524debdc4136fe2e60911b9c050c9e948af0529aca1eff1dcfd1e68a8f3ab17be448b65aab202bf16c789d0e7b4a1
data/README.md CHANGED
@@ -7,8 +7,7 @@
7
7
  For more information on project states and SLAs, see [this documentation](https://github.com/chef/chef-oss-practices/blob/master/repo-management/repo-states.md).
8
8
 
9
9
  [![Slack](https://community-slack.chef.io/badge.svg)](https://community-slack.chef.io/)
10
- [![Build Status Master](https://travis-ci.org/inspec/inspec.svg?branch=master)](https://travis-ci.org/inspec/inspec)
11
- [![Build Status Master](https://ci.appveyor.com/api/projects/status/github/inspec/inspec?branch=master&svg=true&passingText=master%20-%20Ok&pendingText=master%20-%20Pending&failingText=master%20-%20Failing)](https://ci.appveyor.com/project/Chef/inspec/branch/master)
10
+ [![Build status](https://badge.buildkite.com/bf4c5fdc3858cc9f8c8bab8376e8e40d625ad046df9d4d8619.svg?branch=master)](https://buildkite.com/chef-oss/inspec-inspec-master-verify)
12
11
  [![Coverage Status](https://coveralls.io/repos/github/inspec/inspec/badge.svg?branch=master)](https://coveralls.io/github/inspec/inspec?branch=master)
13
12
 
14
13
  Chef InSpec is an open-source testing framework for infrastructure with a human- and machine-readable language for specifying compliance, security and policy requirements.
data/lib/fetchers/git.rb CHANGED
@@ -39,28 +39,65 @@ module Fetchers
39
39
  @branch = opts[:branch]
40
40
  @tag = opts[:tag]
41
41
  @ref = opts[:ref]
42
- @remote_url = remote_url
42
+ @remote_url = expand_local_path(remote_url)
43
43
  @repo_directory = nil
44
+ @relative_path = opts[:relative_path] if opts[:relative_path] && !opts[:relative_path].empty?
44
45
  end
45
46
 
46
- def fetch(dir)
47
- @repo_directory = dir
48
- FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
47
+ def expand_local_path(url_or_file_path)
48
+ # This paths to local on-disk repos, not relative paths within repos.
49
+ # This is especially needed with testing.
50
+
51
+ # We could try to do something clever with URI
52
+ # processing, but then again, if you passed a relative path
53
+ # to an on-disk repo, you probably expect it to exist.
54
+ return url_or_file_path unless File.exist?(url_or_file_path)
55
+ # It's important to expand this path, because it may be specified
56
+ # locally in the metadata files, and when we clone, we will be
57
+ # in a temp dir.
58
+ File.expand_path(url_or_file_path)
59
+ end
60
+
61
+ def fetch(destination_path)
62
+ @repo_directory = destination_path # Might be the cache, or vendoring, or something else
63
+ FileUtils.mkdir_p(destination_path) unless Dir.exist?(destination_path)
49
64
 
50
65
  if cloned?
51
66
  checkout
52
67
  else
53
- Dir.mktmpdir do |tmpdir|
54
- checkout(tmpdir)
55
- Inspec::Log.debug("Checkout of #{resolved_ref} successful. Moving checkout to #{dir}")
56
- FileUtils.cp_r(tmpdir + "/.", @repo_directory)
68
+ Dir.mktmpdir do |working_dir|
69
+ checkout(working_dir)
70
+ if @relative_path
71
+ perform_relative_path_fetch(destination_path, working_dir)
72
+ else
73
+ Inspec::Log.debug("Checkout of #{resolved_ref} successful. " \
74
+ "Moving checkout to #{destination_path}")
75
+ FileUtils.cp_r(working_dir + "/.", destination_path)
76
+ end
57
77
  end
58
78
  end
59
79
  @repo_directory
60
80
  end
61
81
 
82
+ def perform_relative_path_fetch(destination_path, working_dir)
83
+ Inspec::Log.debug("Checkout of #{resolved_ref} successful. " \
84
+ "Moving #{@relative_path} to #{destination_path}")
85
+ unless File.exist?("#{working_dir}/#{@relative_path}")
86
+ # Cleanup the destination path - otherwise we'll have an empty dir
87
+ # in the cache, which is enough to confuse the cache reader
88
+ # This is a courtesy, assuming we're writing to the cache; if we're
89
+ # vendoring to something more complex, don't bother.
90
+ FileUtils.rmdir(destination_path) if Dir.empty?(destination_path)
91
+
92
+ raise ArgumentError, "Cannot find relative path '#{@relative_path}' " \
93
+ "within profile in git repo specified by '#{@remote_url}'"
94
+ end
95
+ FileUtils.cp_r("#{working_dir}/#{@relative_path}", destination_path)
96
+ end
97
+
62
98
  def cache_key
63
- resolved_ref
99
+ return resolved_ref unless @relative_path
100
+ OpenSSL::Digest::SHA256.hexdigest(resolved_ref + @relative_path)
64
101
  end
65
102
 
66
103
  def archive_path
@@ -68,7 +105,9 @@ module Fetchers
68
105
  end
69
106
 
70
107
  def resolved_source
71
- { git: @remote_url, ref: resolved_ref }
108
+ source = { git: @remote_url, ref: resolved_ref }
109
+ source[:relative_path] = @relative_path if @relative_path
110
+ source
72
111
  end
73
112
 
74
113
  private
data/lib/inspec/cli.rb CHANGED
@@ -123,36 +123,32 @@ class Inspec::InspecCLI < Inspec::BaseCLI
123
123
  puts JSON.generate(result)
124
124
  else
125
125
  %w{location profile controls timestamp valid}.each do |item|
126
- puts format("%-12s %s", item.to_s.capitalize + ":",
127
- mark_text(result[:summary][item.to_sym]))
126
+ prepared_string = format("%-12s %s",
127
+ "#{item.to_s.capitalize} :",
128
+ result[:summary][item.to_sym])
129
+ ui.plain_line(prepared_string)
128
130
  end
129
131
  puts
130
132
 
131
133
  if result[:errors].empty? && result[:warnings].empty?
132
- puts "No errors or warnings"
134
+ ui.plain_line("No errors or warnings")
133
135
  else
134
- red = "\033[31m"
135
- yellow = "\033[33m"
136
- rst = "\033[0m"
137
-
138
136
  item_msg = lambda { |item|
139
137
  pos = [item[:file], item[:line], item[:column]].compact.join(":")
140
138
  pos.empty? ? item[:msg] : pos + ": " + item[:msg]
141
139
  }
142
- result[:errors].each do |item|
143
- puts "#{red} #{item_msg.call(item)}#{rst}"
144
- end
145
- result[:warnings].each do |item|
146
- puts "#{yellow} ! #{item_msg.call(item)}#{rst}"
147
- end
140
+
141
+ result[:errors].each { |item| ui.red " #{Inspec::UI::GLYPHS[:script_x]} #{item_msg.call(item)}\n" }
142
+ result[:warnings].each { |item| ui.yellow " ! #{item_msg.call(item)}\n" }
148
143
 
149
144
  puts
150
- puts format("Summary: %s%d errors%s, %s%d warnings%s",
151
- red, result[:errors].length, rst,
152
- yellow, result[:warnings].length, rst)
145
+
146
+ errors = ui.red("#{result[:errors].length} errors", print: false)
147
+ warnings = ui.yellow("#{result[:warnings].length} warnings", print: false)
148
+ ui.plain_line("Summary: #{errors}, #{warnings}")
153
149
  end
154
150
  end
155
- exit 1 unless result[:summary][:valid]
151
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR unless result[:summary][:valid]
156
152
  rescue StandardError => e
157
153
  pretty_handle_exception(e)
158
154
  end
@@ -203,11 +199,11 @@ class Inspec::InspecCLI < Inspec::BaseCLI
203
199
 
204
200
  if result && !o[:ignore_errors] == false
205
201
  o[:logger].info "Profile check failed. Please fix the profile before generating an archive."
206
- return exit 1
202
+ return ui.exit Inspec::UI::EXIT_USAGE_ERROR
207
203
  end
208
204
 
209
205
  # generate archive
210
- exit 1 unless profile.archive(o)
206
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR unless profile.archive(o)
211
207
  rescue StandardError => e
212
208
  pretty_handle_exception(e)
213
209
  end
@@ -294,10 +290,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI
294
290
  runner = Inspec::Runner.new(o)
295
291
  targets.each { |target| runner.add_target(target) }
296
292
 
297
- exit runner.run
293
+ ui.exit runner.run
298
294
  rescue ArgumentError, RuntimeError, Train::UserError => e
299
295
  $stderr.puts e.message
300
- exit 1
296
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
301
297
  rescue StandardError => e
302
298
  pretty_handle_exception(e)
303
299
  end
@@ -312,12 +308,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
312
308
  if o["format"] == "json"
313
309
  puts res.to_json
314
310
  else
315
- headline("Platform Details")
316
- puts Inspec::BaseCLI.format_platform_info(params: res, indent: 0, color: 36)
311
+ ui.headline("Platform Details")
312
+ ui.plain Inspec::BaseCLI.format_platform_info(params: res, indent: 0, color: 36)
317
313
  end
318
314
  rescue ArgumentError, RuntimeError, Train::UserError => e
319
315
  $stderr.puts e.message
320
- exit 1
316
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
321
317
  rescue StandardError => e
322
318
  pretty_handle_exception(e)
323
319
  end
@@ -348,12 +344,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
348
344
  end
349
345
 
350
346
  run_type, res = run_command(o)
351
- exit res unless run_type == :ruby_eval
347
+ ui.exit res unless run_type == :ruby_eval
352
348
 
353
349
  # No InSpec tests - just print evaluation output.
354
350
  res = (res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)) if o["reporter"]&.keys&.include?("json")
355
351
  puts res
356
- exit 0
352
+ ui.exit Inspec::UI::EXIT_NORMAL
357
353
  rescue RuntimeError, Train::UserError => e
358
354
  $stderr.puts e.message
359
355
  rescue StandardError => e
@@ -385,14 +381,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
385
381
  v = { version: Inspec::VERSION }
386
382
  puts v.to_json
387
383
  else
388
- require "inspec/utils/latest_version"
389
384
  puts Inspec::VERSION
390
- # display outdated version
391
- # TODO: remove this. Don't notify of update to a gem when they install omnibus
392
- latest = LatestInSpecVersion.new.latest || Inspec::VERSION
393
- if Gem::Version.new(Inspec::VERSION) < Gem::Version.new(latest)
394
- puts "\nYour version of #{Inspec::Dist::PRODUCT_NAME} is out of date! The latest version is #{latest}."
395
- end
396
385
  end
397
386
  end
398
387
  map %w{-v --version} => :version
@@ -470,5 +459,5 @@ rescue Inspec::Plugin::V2::Exception => v2ex
470
459
  else
471
460
  Inspec::Log.error "Run again with --debug for a stacktrace."
472
461
  end
473
- exit 2
462
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
474
463
  end
@@ -88,6 +88,11 @@ module Inspec::Resources
88
88
  return nil
89
89
  end
90
90
 
91
+ # If multiple triggers are defined, `schtasks` returns a list.
92
+ # This merges that list with the latest item taking precedence.
93
+ # This is the same behavior as `Get-ScheduledTask`.
94
+ params = params.reduce(:merge) if params.is_a?(Array)
95
+
91
96
  @cache = {
92
97
  uri: params["URI"],
93
98
  state: params["State"],
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.7.24".freeze
2
+ VERSION = "4.10.4".freeze
3
3
  end
@@ -64,18 +64,6 @@ module InspecPlugins
64
64
  habitat_origin: read_habitat_config["origin"],
65
65
  }
66
66
  create_file_from_template(plan_file, "plan.sh.erb", vars)
67
-
68
- run_hook_file = File.join(path, "habitat", "hooks", "run")
69
- logger.info("Generating a Habitat run hook at #{run_hook_file}...")
70
- create_file_from_template(run_hook_file, "hooks/run.erb")
71
-
72
- default_toml = File.join(path, "habitat", "default.toml")
73
- logger.info("Generating a Habitat default.toml at #{default_toml}...")
74
- create_file_from_template(default_toml, "default.toml.erb")
75
-
76
- config = File.join(path, "habitat", "config", "inspec_exec_config.json")
77
- logger.info("Generating #{config} for `#{EXEC_NAME} exec`...")
78
- create_file_from_template(config, "config/inspec_exec_config.json.erb")
79
67
  end
80
68
 
81
69
  def upload
@@ -5,81 +5,4 @@ pkg_deps=(chef/inspec)
5
5
  pkg_build_deps=(chef/inspec core/jq-static)
6
6
  pkg_svc_user=root
7
7
  <%= "pkg_license='#{profile.metadata.params[:license]}'" if profile.metadata.params[:license]%>
8
-
9
- do_before() {
10
- # Exit with error if not in the directory with 'inspec.yml'.
11
- # This can happen if someone does 'hab studio enter' from within the
12
- # 'habitat/' directory.
13
- if [ ! -f "$PLAN_CONTEXT/../inspec.yml" ]; then
14
- message="ERROR: Cannot find inspec.yml."
15
- message="$message Please build from the profile root"
16
- build_line "$message"
17
-
18
- return 1
19
- fi
20
-
21
- # Execute an '<%= Inspec::Dist::EXEC_NAME %> compliance login' if a profile needs to be fetched from
22
- # the Automate server
23
- if [ "$(grep "compliance: " "$PLAN_CONTEXT/../inspec.yml")" ]; then
24
- _do_compliance_login;
25
- fi
26
- }
27
-
28
- do_setup_environment() {
29
- set_buildtime_env PROFILE_CACHE_DIR "$HAB_CACHE_SRC_PATH/$pkg_dirname"
30
- set_buildtime_env ARCHIVE_NAME "$pkg_name-$pkg_version.tar.gz"
31
-
32
- # <%= Inspec::Dist::PRODUCT_NAME %> loads `pry` which tries to expand `~`. This fails if HOME isn't set.
33
- set_runtime_env HOME "$pkg_svc_var_path"
34
-
35
- # <%= Inspec::Dist::PRODUCT_NAME %> will create a `.inspec` directory in the user's home directory.
36
- # This overrides that to write to a place within the running service's path.
37
- # NOTE: Setting HOME does the same currently. This is here to be explicit.
38
- set_runtime_env INSPEC_CONFIG_DIR "$pkg_svc_var_path"
39
- }
40
-
41
- do_unpack() {
42
- # Change directory to where the profile files are
43
- pushd "$PLAN_CONTEXT/../" > /dev/null
44
-
45
- # Get a list of all files in the profile except those that are Habitat related
46
- profile_files=($(ls -I habitat -I results -I "*.hart"))
47
-
48
- mkdir -p "$PROFILE_CACHE_DIR" > /dev/null
49
-
50
- # Copy just the profile files to the profile cache directory
51
- cp -r ${profile_files[@]} "$PROFILE_CACHE_DIR"
52
- }
53
-
54
- do_build() {
55
- <%= Inspec::Dist::EXEC_NAME %> archive "$PROFILE_CACHE_DIR" \
56
- --overwrite \
57
- -o "$PROFILE_CACHE_DIR/$ARCHIVE_NAME"
58
- }
59
-
60
- do_install() {
61
- cp "$PROFILE_CACHE_DIR/$ARCHIVE_NAME" "$pkg_prefix"
62
- }
63
-
64
- _do_compliance_login() {
65
- if [ -z $COMPLIANCE_CREDS ]; then
66
- message="ERROR: Please perform an '<%= Inspec::Dist::EXEC_NAME %> compliance login' and set"
67
- message="$message \$HAB_STUDIO_SECRET_COMPLIANCE_CREDS to the contents of"
68
- message="$message '~/.inspec/compliance/config.json'"
69
- build_line "$message"
70
- return 1
71
- fi
72
-
73
- user=$(echo $COMPLIANCE_CREDS | jq .user | sed 's/"//g')
74
- token=$(echo $COMPLIANCE_CREDS | jq .token | sed 's/"//g')
75
- automate_server=$(echo $COMPLIANCE_CREDS | \
76
- jq .server | \
77
- sed 's/\/api\/v0//' | \
78
- sed 's/"//g'
79
- )
80
- insecure=$(echo $COMPLIANCE_CREDS | jq .insecure)
81
- <%= Inspec::Dist::EXEC_NAME %> compliance login --insecure $insecure \
82
- --user $user \
83
- --token $token \
84
- $automate_server
85
- }
8
+ pkg_scaffolding="chef/scaffolding-chef-inspec"
@@ -1,4 +1,3 @@
1
- require "term/ansicolor"
2
1
  require "pathname"
3
2
  require "inspec/plugin/v2"
4
3
  require "inspec/plugin/v2/installer"
@@ -7,7 +6,6 @@ require "inspec/dist"
7
6
  module InspecPlugins
8
7
  module PluginManager
9
8
  class CliCommand < Inspec.plugin(2, :cli_command)
10
- include Term::ANSIColor
11
9
  include Inspec::Dist
12
10
 
13
11
  subcommand_desc "plugin SUBCOMMAND", "Manage #{PRODUCT_NAME} and Train plugins"
@@ -22,15 +20,17 @@ module InspecPlugins
22
20
  plugin_statuses = Inspec::Plugin::V2::Registry.instance.plugin_statuses
23
21
  plugin_statuses.reject! { |s| %i{core bundle}.include?(s.installation_type) } unless options[:all]
24
22
 
25
- # TODO: ui object support
26
23
  puts
27
- puts(bold { format(" %-30s%-10s%-8s%-6s", "Plugin Name", "Version", "Via", "ApiVer") })
28
- puts "-" * 55
24
+ ui.bold(format(" %-30s%-10s%-8s%-6s", "Plugin Name", "Version", "Via", "ApiVer"))
25
+ ui.line
29
26
  plugin_statuses.sort_by(&:name).each do |status|
30
- puts(format(" %-30s%-10s%-8s%-6s", status.name, make_pretty_version(status), status.installation_type, status.api_generation.to_s))
27
+ ui.plain(format(" %-30s%-10s%-8s%-6s", status.name,
28
+ make_pretty_version(status),
29
+ status.installation_type,
30
+ status.api_generation.to_s))
31
31
  end
32
- puts "-" * 55
33
- puts(" #{plugin_statuses.count} plugin(s) total")
32
+ ui.line
33
+ ui.plain(" #{plugin_statuses.count} plugin(s) total")
34
34
  puts
35
35
  end
36
36
 
@@ -59,23 +59,22 @@ module InspecPlugins
59
59
  search_results.delete("train-test-fixture")
60
60
  end
61
61
 
62
- # TODO: ui object support
63
62
  puts
64
- puts(bold { format(" %-30s%-50s", "Plugin Name", "Versions Available") })
65
- puts "-" * 55
63
+ ui.bold(format(" %-30s%-50s", "Plugin Name", "Versions Available"))
64
+ ui.line
66
65
  search_results.keys.sort.each do |plugin_name|
67
66
  versions = options[:all] ? search_results[plugin_name] : [search_results[plugin_name].first]
68
67
  versions = "(" + versions.join(", ") + ")"
69
- puts(format(" %-30s%-50s", plugin_name, versions))
68
+ ui.plain(format(" %-30s%-50s", plugin_name, versions))
70
69
  end
71
- puts "-" * 55
72
- puts(" #{search_results.count} plugin(s) found")
70
+ ui.line
71
+ ui.plain(" #{search_results.count} plugin(s) found")
73
72
  puts
74
73
 
75
- exit 2 if search_results.empty?
74
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR if search_results.empty?
76
75
  rescue Inspec::Plugin::V2::SearchError => ex
77
76
  Inspec::Log.error ex.message
78
- exit 1
77
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
79
78
  end
80
79
 
81
80
  #==================================================================#
@@ -119,13 +118,14 @@ module InspecPlugins
119
118
  begin
120
119
  installer.update(plugin_name)
121
120
  rescue Inspec::Plugin::V2::UpdateError => ex
122
- puts(red { "Update error: " } + ex.message + " - update failed")
123
- exit 1
121
+ ui.plain("#{ui.red('Update error:')} #{ex.message} - update failed")
122
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
124
123
  end
125
124
  post_update_versions = installer.list_installed_plugin_gems.select { |spec| spec.name == plugin_name }.map { |spec| spec.version.to_s }
126
125
  new_version = (post_update_versions - pre_update_versions).first
127
126
 
128
- puts(bold { plugin_name } + " plugin, version #{old_version} -> #{new_version}, updated from rubygems.org")
127
+ ui.bold(plugin_name + " plugin, version #{old_version} -> " \
128
+ "#{new_version}, updated from rubygems.org")
129
129
  end
130
130
 
131
131
  #--------------------------
@@ -144,9 +144,9 @@ module InspecPlugins
144
144
  def uninstall(plugin_name)
145
145
  status = Inspec::Plugin::V2::Registry.instance[plugin_name.to_sym]
146
146
  unless status
147
- puts(red { "No such plugin installed: " } + "#{plugin_name} is not installed - uninstall failed")
148
-
149
- exit 1
147
+ ui.plain("#{ui.red('No such plugin installed:')} #{plugin_name} is not " \
148
+ "installed - uninstall failed")
149
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
150
150
  end
151
151
  installer = Inspec::Plugin::V2::Installer.instance
152
152
 
@@ -156,11 +156,13 @@ module InspecPlugins
156
156
  installer.uninstall(plugin_name)
157
157
 
158
158
  if status.installation_type == :path
159
- puts(bold { plugin_name } + " path-based plugin install has been uninstalled")
159
+ ui.bold(plugin_name + " path-based plugin install has been " \
160
+ "uninstalled")
160
161
  else
161
- puts(bold { plugin_name } + " plugin, version #{old_version}, has been uninstalled")
162
+ ui.bold(plugin_name + " plugin, version #{old_version}, has " \
163
+ "been uninstalled")
162
164
  end
163
- exit 0
165
+ ui.exit Inspec::UI::EXIT_NORMAL
164
166
  end
165
167
 
166
168
  private
@@ -172,8 +174,8 @@ module InspecPlugins
172
174
 
173
175
  def install_from_gemfile(gem_file)
174
176
  unless File.exist? gem_file
175
- puts(red { "No such plugin gem file " } + gem_file + " - installation failed.")
176
- exit 1
177
+ ui.red("No such plugin gem file #{gem_file} - installation failed.")
178
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
177
179
  end
178
180
 
179
181
  plugin_name_parts = File.basename(gem_file, ".gem").split("-")
@@ -183,14 +185,15 @@ module InspecPlugins
183
185
 
184
186
  installer.install(plugin_name, gem_file: gem_file)
185
187
 
186
- puts(bold { plugin_name } + " plugin, version #{version}, installed from local .gem file")
187
- exit 0
188
+ ui.bold("#{plugin_name} plugin, version #{version}, installed from " \
189
+ "local .gem file")
190
+ ui.exit Inspec::UI::EXIT_NORMAL
188
191
  end
189
192
 
190
193
  def install_from_path(path)
191
194
  unless File.exist? path
192
- puts(red { "No such source code path " } + path + " - installation failed.")
193
- exit 1
195
+ ui.red("No such source code path #{path} - installation failed.")
196
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
194
197
  end
195
198
 
196
199
  plugin_name = File.basename(path, ".rb")
@@ -204,8 +207,10 @@ module InspecPlugins
204
207
 
205
208
  # Already installed?
206
209
  if registry.known_plugin?(plugin_name.to_sym)
207
- puts(red { "Plugin already installed" } + " - #{plugin_name} - Use '#{EXEC_NAME} plugin list' to see previously installed plugin - installation failed.")
208
- exit 2
210
+ ui.red("Plugin already installed - #{plugin_name} - Use '#{EXEC_NAME} " \
211
+ "plugin list' to see previously installed plugin - " \
212
+ "installation failed.")
213
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
209
214
  end
210
215
 
211
216
  # Can we figure out how to load it?
@@ -217,8 +222,9 @@ module InspecPlugins
217
222
  # OK, install it!
218
223
  installer.install(plugin_name, path: entry_point)
219
224
 
220
- puts(bold { plugin_name } + " plugin installed via source path reference, resolved to entry point " + entry_point)
221
- exit 0
225
+ ui.bold("#{plugin_name} plugin installed via source path reference, " \
226
+ "resolved to entry point #{entry_point}")
227
+ ui.exit Inspec::UI::EXIT_NORMAL
222
228
  end
223
229
 
224
230
  # Rationale for rubocop variances: It's a heuristics method, and will be full of
@@ -229,6 +235,7 @@ module InspecPlugins
229
235
  given = given.expand_path # Resolve any relative paths
230
236
  name_regex = /^(inspec|train)-/
231
237
  versioned_regex = /^(inspec|train)-[a-z0-9\-\_]+-\d+\.\d+\.\d+$/
238
+ sha_ref_regex = /^(inspec|train)-[a-z0-9\-\_]+-[0-9a-f]{5,40}$/
232
239
 
233
240
  # What are the last four things like?
234
241
  parts = [
@@ -257,14 +264,14 @@ module InspecPlugins
257
264
  # In that case, we'll have a version on the plugin name in part 0
258
265
  # /home/you/.gems/2.4.0/gems/inspec-something-3.45.1/lib/inspec-something.rb
259
266
  # parts index: ^0^ ^1^ ^2^ ^3^
260
- if parts[0] =~ versioned_regex && parts[1] == "lib" && parts[0].start_with?(parts[2]) && parts[3] == ".rb"
267
+ if (parts[0] =~ versioned_regex || parts[0] =~ sha_ref_regex) && parts[1] == "lib" && parts[0].start_with?(parts[2]) && parts[3] == ".rb"
261
268
  return given.to_s
262
269
  end
263
270
 
264
271
  # Case 4: Like case 3, but missing the .rb
265
272
  # /home/you/.gems/2.4.0/gems/inspec-something-3.45.1/lib/inspec-something
266
273
  # parts index: ^0^ ^1^ ^2^ ^3^ (empty)
267
- if parts[0] =~ versioned_regex && parts[1] == "lib" && parts[0].start_with?(parts[2]) && parts[3].empty?
274
+ if (parts[0] =~ versioned_regex || parts[0] =~ sha_ref_regex) && parts[1] == "lib" && parts[0].start_with?(parts[2]) && parts[3].empty?
268
275
  return given.to_s + ".rb"
269
276
  end
270
277
 
@@ -279,8 +286,10 @@ module InspecPlugins
279
286
 
280
287
  # Well, if we got here, parts[2] matches an inspec/train prefix, but we have no idea about anything.
281
288
  # Give up.
282
- puts(red { "Unrecognizable plugin structure" } + " - #{parts[2]} - When installing from a path, please provide the path of the entry point file - installation failed.")
283
- exit 1
289
+ ui.red("Unrecognizable plugin structure - #{parts[2]} - When " \
290
+ "installing from a path, please provide the path of the " \
291
+ "entry point file - installation failed.")
292
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
284
293
  end
285
294
 
286
295
  def install_from_path__probe_load(entry_point, plugin_name)
@@ -288,9 +297,11 @@ module InspecPlugins
288
297
  begin
289
298
  require entry_point
290
299
  rescue LoadError => ex
291
- puts(red { "Plugin contains errors" } + " - #{plugin_name} - Encountered errors while trying to test load the plugin entry point, resolved to #{entry_point} - installation failed")
292
- puts ex.message
293
- exit 1
300
+ ui.red("Plugin contains errors - #{plugin_name} - Encountered " \
301
+ "errors while trying to test load the plugin entry point, " \
302
+ "resolved to #{entry_point} - installation failed")
303
+ ui.plain ex.message
304
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
294
305
  end
295
306
 
296
307
  # OK, the wheels didn't fall off. But is it a plugin?
@@ -299,13 +310,19 @@ module InspecPlugins
299
310
  # And the registry is keyed on Strings
300
311
  registry_key = plugin_name.to_s.sub(/^train-/, "")
301
312
  unless Train::Plugins.registry.key?(registry_key)
302
- puts(red { "Does not appear to be a plugin" } + " - #{plugin_name} - After probe-loading the supposed plugin, it did not register itself to Train. Ensure something inherits from 'Train.plugin(1)' - installation failed.")
303
- exit 1
313
+ ui.red("Does not appear to be a plugin - #{plugin_name} - After " \
314
+ "probe-loading the supposed plugin, it did not register " \
315
+ "itself to Train. Ensure something inherits from " \
316
+ "'Train.plugin(1)' - installation failed.")
317
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
304
318
  end
305
319
  else
306
320
  unless registry.known_plugin?(plugin_name.to_sym)
307
- puts(red { "Does not appear to be a plugin" } + " - #{plugin_name} - After probe-loading the supposed plugin, it did not register itself to InSpec. Ensure something inherits from 'Inspec.plugin(2)' - installation failed.")
308
- exit 1
321
+ ui.red("Does not appear to be a plugin - #{plugin_name} - After " \
322
+ "probe-loading the supposed plugin, it did not register " \
323
+ "itself to InSpec. Ensure something inherits from " \
324
+ "'Inspec.plugin(2)' - installation failed.")
325
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
309
326
  end
310
327
  end
311
328
  end
@@ -325,8 +342,9 @@ module InspecPlugins
325
342
  post_installed_versions = installer.list_installed_plugin_gems.select { |spec| spec.name == plugin_name }.map { |spec| spec.version.to_s }
326
343
  new_version = (post_installed_versions - pre_installed_versions).first
327
344
 
328
- puts(bold { plugin_name } + " plugin, version #{new_version}, installed from rubygems.org")
329
- exit 0
345
+ ui.bold("#{plugin_name} plugin, version #{new_version}, installed " \
346
+ "from rubygems.org")
347
+ ui.exit Inspec::UI::EXIT_NORMAL
330
348
  end
331
349
 
332
350
  def install_from_remote_gem_verson_preflight_check(plugin_name, requested_version, pre_installed_versions)
@@ -348,38 +366,50 @@ module InspecPlugins
348
366
  they_explicitly_asked_for_a_version = !options[:version].nil?
349
367
  what_we_would_install_is_already_installed = pre_installed_versions.include?(requested_version)
350
368
  if what_we_would_install_is_already_installed && they_explicitly_asked_for_a_version
351
- puts(red { "Plugin already installed at requested version" } + " - plugin #{plugin_name} #{requested_version} - refusing to install.")
369
+ ui.red("Plugin already installed at requested version - plugin " \
370
+ "#{plugin_name} #{requested_version} - refusing to install.")
352
371
  elsif what_we_would_install_is_already_installed && !they_explicitly_asked_for_a_version
353
- puts(red { "Plugin already installed at latest version" } + " - plugin #{plugin_name} #{requested_version} - refusing to install.")
372
+ ui.red("Plugin already installed at latest version - plugin " \
373
+ "#{plugin_name} #{requested_version} - refusing to install.")
354
374
  else
355
375
  # There are existing versions installed, but none of them are what was requested
356
- puts(red { "Update required" } + " - plugin #{plugin_name}, requested #{requested_version}, have #{pre_installed_versions.join(", ")}; use `inspec plugin update` - refusing to install.")
376
+ ui.red("Update required - plugin #{plugin_name}, requested " \
377
+ "#{requested_version}, have " \
378
+ "#{pre_installed_versions.join(', ')}; use `inspec " \
379
+ "plugin update` - refusing to install.")
357
380
  end
358
381
 
359
- exit 2
382
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
360
383
  end
361
384
 
362
385
  # Rationale for RuboCop variance: This is a one-line method with heavy UX-focused error handling.
363
386
  def install_attempt_install(plugin_name) # rubocop: disable Metrics/AbcSize
364
387
  installer.install(plugin_name, version: options[:version])
365
388
  rescue Inspec::Plugin::V2::PluginExcludedError => ex
366
- puts(red { "Plugin on Exclusion List" } + " - #{plugin_name} is listed as an incompatible gem - refusing to install.")
367
- puts "Rationale: #{ex.details.rationale}"
368
- puts "Exclusion list location: " + File.join(Inspec.src_root, "etc", "plugin_filters.json")
369
- puts "If you disagree with this determination, please accept our apologies for the misunderstanding, and open an issue at https://github.com/inspec/inspec/issues/new"
370
- exit 2
389
+ ui.red("Plugin on Exclusion List - #{plugin_name} is listed as an " \
390
+ "incompatible gem - refusing to install.")
391
+ ui.plain("Rationale: #{ex.details.rationale}")
392
+ ui.plain("Exclusion list location: " +
393
+ File.join(Inspec.src_root, "etc", "plugin_filters.json"))
394
+ ui.plain("If you disagree with this determination, please accept " \
395
+ "our apologies for the misunderstanding, and open an issue " \
396
+ "at https://github.com/inspec/inspec/issues/new")
397
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
371
398
  rescue Inspec::Plugin::V2::InstallError
372
399
  raise if Inspec::Log.level == :debug
373
400
 
374
401
  results = installer.search(plugin_name, exact: true)
375
402
  if results.empty?
376
- puts(red { "No such plugin gem " } + plugin_name + " could be found on rubygems.org - installation failed.")
403
+ ui.red("No such plugin gem #{plugin_name} could be found on " \
404
+ "rubygems.org - installation failed.")
377
405
  elsif options[:version] && !results[plugin_name].include?(options[:version])
378
- puts(red { "No such version" } + " - " + plugin_name + " exists, but no such version #{options[:version]} found on rubygems.org - installation failed.")
406
+ ui.red("No such version - #{plugin_name} exists, but no such " \
407
+ "version #{options[:version]} found on rubygems.org - " \
408
+ "installation failed.")
379
409
  else
380
- puts(red { "Unknown error occured " } + " - installation failed.")
410
+ ui.red("Unknown error occured - installation failed.")
381
411
  end
382
- exit 1
412
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
383
413
  end
384
414
 
385
415
  #==================================================================#
@@ -390,11 +420,14 @@ module InspecPlugins
390
420
  # Check for path install
391
421
  status = Inspec::Plugin::V2::Registry.instance[plugin_name.to_sym]
392
422
  if !status
393
- puts(red { "No such plugin installed: " } + "#{plugin_name} - update failed")
394
- exit 1
423
+ ui.plain("#{ui.red('No such plugin installed:')} #{plugin_name} - update failed")
424
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
395
425
  elsif status.installation_type == :path
396
- puts(red { "Cannot update path-based install: " } + "#{plugin_name} is installed via path reference; use `inspec plugin uninstall` to remove - refusing to update")
397
- exit 2
426
+ ui.plain("#{ui.red('Cannot update path-based install:')} " \
427
+ "#{plugin_name} is installed via path reference; " \
428
+ "use `inspec plugin uninstall` to remove - refusing to" \
429
+ "update")
430
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
398
431
  end
399
432
  end
400
433
 
@@ -403,8 +436,10 @@ module InspecPlugins
403
436
  latest_version = latest_version[plugin_name]&.last
404
437
 
405
438
  if pre_update_versions.include?(latest_version)
406
- puts(red { "Already installed at latest version: " } + "#{plugin_name} is at #{latest_version}, which the latest - refusing to update")
407
- exit 2
439
+ ui.plain("#{ui.red('Already installed at latest version:')} " \
440
+ "#{plugin_name} is at #{latest_version}, which the " \
441
+ "latest - refusing to update")
442
+ ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
408
443
  end
409
444
  end
410
445
 
@@ -421,8 +456,10 @@ module InspecPlugins
421
456
 
422
457
  def check_plugin_name(plugin_name, action)
423
458
  unless plugin_name =~ /^(inspec|train)-/
424
- puts(red { "Invalid plugin name" } + " - #{plugin_name} - All inspec plugins must begin with either 'inspec-' or 'train-' - #{action} failed.")
425
- exit 1
459
+ ui.red("Invalid plugin name - #{plugin_name} - All inspec " \
460
+ "plugins must begin with either 'inspec-' or 'train-' " \
461
+ "- #{action} failed.")
462
+ ui.exit Inspec::UI::EXIT_USAGE_ERROR
426
463
  end
427
464
  end
428
465
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.24
4
+ version: 4.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-25 00:00:00.000000000 Z
11
+ date: 2019-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train-core
@@ -598,7 +598,6 @@ files:
598
598
  - lib/inspec/utils/find_files.rb
599
599
  - lib/inspec/utils/hash.rb
600
600
  - lib/inspec/utils/json_log.rb
601
- - lib/inspec/utils/latest_version.rb
602
601
  - lib/inspec/utils/modulator.rb
603
602
  - lib/inspec/utils/nginx_parser.rb
604
603
  - lib/inspec/utils/object_traversal.rb
@@ -633,9 +632,6 @@ files:
633
632
  - lib/plugins/inspec-habitat/lib/inspec-habitat.rb
634
633
  - lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb
635
634
  - lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb
636
- - lib/plugins/inspec-habitat/templates/habitat/config/inspec_exec_config.json.erb
637
- - lib/plugins/inspec-habitat/templates/habitat/default.toml.erb
638
- - lib/plugins/inspec-habitat/templates/habitat/hooks/run.erb
639
635
  - lib/plugins/inspec-habitat/templates/habitat/plan.sh.erb
640
636
  - lib/plugins/inspec-init/README.md
641
637
  - lib/plugins/inspec-init/lib/inspec-init.rb
@@ -1,13 +0,0 @@
1
- require "json"
2
- require "open-uri"
3
-
4
- class LatestInSpecVersion
5
- # fetches the latest version from rubygems server
6
- def latest
7
- uri = URI("https://rubygems.org/api/v1/gems/inspec.json")
8
- inspec_info = JSON.parse(uri.read(open_timeout: 1.5, read_timeout: 1.5))
9
- inspec_info["version"]
10
- rescue StandardError
11
- nil
12
- end
13
- end
@@ -1,25 +0,0 @@
1
- {
2
- "target_id": "{{ sys.member_id }}",
3
- "reporter": {
4
- "cli": {
5
- "stdout": {{cfg.report_to_stdout}}
6
- },
7
- "json": {
8
- "file": "{{pkg.svc_path}}/logs/inspec_last_run.json"
9
- }{{#if cfg.automate.token ~}},
10
- "automate" : {
11
- "url": "{{cfg.automate.url}}/data-collector/v0/",
12
- "token": "{{cfg.automate.token}}",
13
- "node_name": "{{ sys.hostname }}",
14
- "verify_ssl": false
15
- }{{/if ~}}
16
- }
17
- {{#if cfg.automate.token }},
18
- "compliance": {
19
- "server" : "{{cfg.automate.url}}",
20
- "token" : "{{cfg.automate.token}}",
21
- "user" : "{{cfg.automate.user}}",
22
- "insecure" : true,
23
- "ent" : "automate"
24
- }{{/if }}
25
- }
@@ -1,9 +0,0 @@
1
- interval = 300
2
- report_to_stdout = true
3
-
4
- # Uncomment and replace values to report to Automate.
5
- # This can also be applied at runtime via `hab config apply`
6
- #[automate]
7
- #url = 'https://chef-automate.test'
8
- #token = 'TOKEN'
9
- #user = 'admin'
@@ -1,32 +0,0 @@
1
- #!/bin/sh
2
-
3
- exec 2>&1
4
-
5
- CONFIG="{{pkg.svc_config_path}}/inspec_exec_config.json"
6
- INTERVAL="{{cfg.interval}}"
7
- LOG_FILE="{{pkg.svc_path}}/logs/inspec_log.txt"
8
- PROFILE_IDENT="{{pkg.origin}}/{{pkg.name}}"
9
- PROFILE_PATH="{{pkg.path}}/{{pkg.name}}-{{pkg.version}}.tar.gz"
10
-
11
- while true; do
12
- echo "Executing ${PROFILE_IDENT}"
13
- exec <%= Inspec::Dist::EXEC_NAME %> exec ${PROFILE_PATH} --json-config ${CONFIG} 2>&1 | tee ${LOG_FILE}
14
-
15
- exit_code=$?
16
- if [ $exit_code -eq 1 ]; then
17
- echo "<%= Inspec::Dist::PRODUCT_NAME %> run failed."
18
- else
19
- echo "<%= Inspec::Dist::PRODUCT_NAME %> run completed successfully."
20
- if [ $exit_code -eq 0 ]; then
21
- echo "No controls failed or were skipped."
22
- elif [ $exit_code -eq 100 ]; then
23
- echo "At least 1 control failed."
24
- elif [ $exit_code -eq 101 ]; then
25
- echo "No controls failed but at least 1 skipped."
26
- fi
27
- fi
28
- echo "Results are logged here: ${LOG_FILE}"
29
-
30
- echo "Sleeping for ${INTERVAL} seconds"
31
- sleep ${INTERVAL}
32
- done