inspec 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: 17d4755a71b5ff3f54c357d4f1af43aa021f9bf451352b26796532b82eff8171
4
- data.tar.gz: b6adb4d407d16e0c458247f6f66df68d34defee4d237b68e491733c16be6172a
3
+ metadata.gz: 2be41b8620f4c1d6121a602f39c068ad59168ad95f2d15d0cd470ebba2ce249f
4
+ data.tar.gz: 883c88f79780d101b26925c1a67c14b8ba36f18b2514e5974bd947ce7192cf39
5
5
  SHA512:
6
- metadata.gz: 2ff8d76a9eba7a9d4fb62ccd28e3832b86f2d9c0e462e2c5725010182785a9308f0f5a157011008145578742189a3820d9912ddac3e34e3f7be7495e5ee71e4b
7
- data.tar.gz: 121d494b210eecbb5cc8a82484efb017b8f6f16317172a916b4f62a2519b3a3ce8253e50d1cd15063230f1f9a081da3f06811db2c11ef5c3bfc4f69c1c23e8d7
6
+ metadata.gz: 61e4f19e37a19cc4492d890798a323f3f8c9127dc64e4e0469a92f7182b07dd1134d84ce87ba80d60940f40656378f215ee8a332fc1abf965585183e48b9c680
7
+ data.tar.gz: 298f688326827ee7871d3379ff016be74e2ce710bddebd7eccba4866292519443d0f95f8e36bcb8dc5ec65f336d70d8752c7e5f9bf5ddf7490946f8733542897
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
@@ -5,19 +5,17 @@ require "securerandom"
5
5
  class ArtifactCli < Minitest::Test
6
6
  include CorePluginFunctionalHelper
7
7
 
8
- before do
9
- skip_windows!
10
- end
11
-
12
8
  def test_generating_archive_keys
13
9
  Dir.mktmpdir do |dir|
14
10
  unique_key_name = SecureRandom.uuid
15
11
  out = run_inspec_process("artifact generate --keyname #{unique_key_name}", prefix: "cd #{dir} &&")
16
- assert_equal 0, out.exit_status
17
12
 
18
13
  stdout = out.stdout.force_encoding(Encoding::UTF_8)
14
+ skip_windows!
19
15
  assert_includes stdout, "Generating private key"
20
16
  assert_includes stdout, "Generating public key"
17
+
18
+ assert_exit_code 0, out
21
19
  end
22
20
  end
23
21
 
@@ -32,13 +30,14 @@ class ArtifactCli < Minitest::Test
32
30
  run_inspec_process("init profile artifact-profile", prefix: "cd #{dir} &&")
33
31
 
34
32
  out = run_inspec_process("artifact generate --keyname #{unique_key_name}", prefix: "cd #{dir} &&")
35
- assert_equal 0, out.exit_status
33
+ skip_windows!
34
+ assert_exit_code 0, out
36
35
 
37
36
  out = run_inspec_process("artifact sign-profile --profile #{profile} --keyname #{unique_key_name}", prefix: "cd #{dir} &&")
38
- assert_equal 0, out.exit_status
37
+ assert_exit_code 0, out
39
38
 
40
39
  out = run_inspec_process("artifact install-profile --infile artifact-profile-0.1.0.iaf --destdir #{install_dir}", prefix: "cd #{dir} &&")
41
- assert_equal 0, out.exit_status
40
+ assert_exit_code 0, out
42
41
 
43
42
  assert_includes out.stdout.force_encoding(Encoding::UTF_8), "Installing to #{install_dir}"
44
43
  assert_includes Dir.entries(install_dir).join, "inspec.yml"
@@ -5,37 +5,49 @@ class ComplianceCli < Minitest::Test
5
5
 
6
6
  def test_help_output
7
7
  out = run_inspec_process("compliance help")
8
- assert_equal out.exit_status, 0
8
+
9
9
  assert_includes out.stdout, "inspec compliance exec PROFILE"
10
+
11
+ assert_exit_code 0, out
10
12
  end
11
13
 
12
14
  def test_logout_command
13
15
  out = run_inspec_process("compliance logout")
14
- assert_equal out.exit_status, 0
16
+
15
17
  assert_includes out.stdout, ""
18
+
19
+ assert_exit_code 0, out
16
20
  end
17
21
 
18
22
  def test_error_login_with_invalid_url
19
23
  out = run_inspec_process("compliance login")
20
- assert_equal out.exit_status, 1
24
+
21
25
  assert_includes out.stderr, 'ERROR: "inspec compliance login" was called with no arguments'
26
+
27
+ assert_exit_code 1, out
22
28
  end
23
29
 
24
30
  def test_profile_list_without_auth
25
31
  out = run_inspec_process("compliance profiles")
26
- assert_equal out.exit_status, 0 # TODO: make this error
32
+
27
33
  assert_includes out.stdout, "You need to login first with `inspec compliance login`"
34
+
35
+ assert_exit_code 0, out # TODO: make this error
28
36
  end
29
37
 
30
38
  def test_error_upload_without_args
31
39
  out = run_inspec_process("compliance upload")
32
- assert_equal out.exit_status, 1
40
+
33
41
  assert_includes out.stderr, 'ERROR: "inspec compliance upload" was called with no arguments'
42
+
43
+ assert_exit_code 1, out
34
44
  end
35
45
 
36
46
  def test_error_upload_with_fake_path
37
47
  out = run_inspec_process("compliance upload /path/to/dir")
38
- assert_equal out.exit_status, 0 # TODO: make this error
48
+
39
49
  assert_includes out.stdout, "You need to login first with `inspec compliance login`"
50
+
51
+ assert_exit_code 0, out # TODO: make this error
40
52
  end
41
53
  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"