inspec-core 4.7.24 → 4.10.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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