inspec-core 7.0.107 → 7.2.1

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: 45c2a8606fc27e3246476e86b6d87ab22b5e9b0ea8f85d8381e71a5b74d1b0d0
4
- data.tar.gz: af209e2f16b169913314c0aee8bd2c4ed0a05d92a187ad421ef81c6a22d3cc26
3
+ metadata.gz: ed63ed9529571a4192cc3d69253bb303cddb5f6c07dd7f6c5009846e20fc2d74
4
+ data.tar.gz: e3f693766b0698bba07fc6ae2e823a51993484d88cd5f309dd83b6dd832a55d4
5
5
  SHA512:
6
- metadata.gz: 5e15e616ac53c257b7f3b23744745798cb22fbaa91ff6668140bf40ecfee92da7931e31949429fe337984c8716538ff84c8ca03acbcf9303fc93d45b20a3f4df
7
- data.tar.gz: 63064836ca735a8ab3dfe01ccfb4c2cdc791dbf9474e2eff83df893ad04ef79979f5850bc7536967b5b2d871d31ad4cbc0ef61aa1ca92dbcde30eeef72a00fd2
6
+ metadata.gz: 3c0bc69773b1376970e84b073b556731af530f4706779f5c5ccf3807a6ca5ba4e55a747f08581bb001ed796468108b0080df8197f8484d7a43594d3c4410e3c2
7
+ data.tar.gz: ee83f8a1efd8aca287f1c9fb426083cc1245f1174252747a1a88cb8c6c488d939b2797c415498a54bb4297249ca09ae43618f0a02e55c5fe7dcfee18cf821148
data/Gemfile CHANGED
@@ -43,14 +43,12 @@ group :test do
43
43
  gem "m"
44
44
  gem "minitest-sprint", "~> 1.0"
45
45
  gem "minitest"
46
- # Ruby 3.4+ extracts minitest-mock to a separate gem (bundled gem)
47
- # Adding unconditionally as it's compatible with all Ruby versions
48
- gem "minitest-mock"
46
+ gem "minitest-mock" # Ruby 3.4+ extracts minitest-mock to a separate gem (bundled gem). It's compatible with all Ruby versions.
49
47
  gem "mocha"
50
48
  gem "nokogiri"
51
49
  gem "pry-byebug"
52
50
  gem "pry"
53
- gem "rake"
51
+ gem "rake", ">= 12.3.3"
54
52
  gem "simplecov"
55
53
  gem "simplecov_json_formatter"
56
54
  gem "webmock"
@@ -130,6 +130,9 @@
130
130
  "renamed_to_inspec_export":{
131
131
  "action": "ignore",
132
132
  "prefix": "The `inspec json` command is deprecated in InSpec 5 and replaced with `inspec export` command."
133
+ },
134
+ "cli_option_compliance_overwrite": {
135
+ "action": "warn"
133
136
  }
134
137
  },
135
138
  "fallback_resource_packs":{
@@ -141,7 +144,7 @@
141
144
  "gem":"inspec-elasticsearch-resources",
142
145
  "message":"The `inspec-elasticsearch-resources` allows testing of elasticsearch using Inspec."
143
146
  },
144
- "docker.+":{
147
+ "docker.*":{
145
148
  "gem": "inspec-docker-resources",
146
149
  "message": "The Inspec docker resources are moved out of InSpec core and will be installed as gem"
147
150
  },
@@ -157,7 +160,7 @@
157
160
  "gem": "inspec-opa-resources",
158
161
  "message": "The Inspec opa resources are moved out of InSpec core and will be installed as gem"
159
162
  },
160
- "podman.+":{
163
+ "podman.*":{
161
164
  "gem": "inspec-podman-resources",
162
165
  "message": "The Inspec podman resources are moved out of InSpec core and will be installed as gem"
163
166
  },
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+
3
+ # Default environment variables for InSpec development
4
+ # Copy this file to etc/env.sh and uncomment/customize values as needed
5
+ # NEVER commit etc/env.sh to git
6
+
7
+ # The GitHub repo path for shared-context with optional branch specification
8
+ # export PROGRESS_SHARED_CONTEXT_REPO="progress-infra-poc/shared-context@main"
@@ -0,0 +1,2 @@
1
+ inspec/train
2
+ inspec/train-winrm
data/inspec-core.gemspec CHANGED
@@ -50,7 +50,7 @@ Source code obtained from the Chef GitHub repository is made available under Apa
50
50
  spec.add_dependency "tty-table", "~> 0.10"
51
51
  spec.add_dependency "tty-prompt", "~> 0.17"
52
52
  spec.add_dependency "tomlrb", ">= 1.3", "< 2.1"
53
- spec.add_dependency "addressable", "~> 2.4"
53
+ spec.add_dependency "addressable", "~> 2.9"
54
54
  spec.add_dependency "parslet", ">= 1.5", "< 3.0" # Pinned < 2.0, see #5389
55
55
  spec.add_dependency "semverse", "~> 3.0"
56
56
  spec.add_dependency "multipart-post", "~> 2.0"
@@ -68,7 +68,7 @@ Source code obtained from the Chef GitHub repository is made available under Apa
68
68
  # which was causing a LoadError ('cannot load such file -- ast') for users/applications using 'inspec-core'.
69
69
  spec.add_dependency "cookstyle"
70
70
 
71
- spec.add_dependency "train-core", "~> 3.16", ">= 3.16.1"
71
+ spec.add_dependency "train-core", "~> 3.16", ">= 3.16.5"
72
72
  # Minimum major version 1 is required for Chef licensing telemetry
73
73
  spec.add_dependency "chef-licensing", ">= 1.2.0"
74
74
  end
@@ -45,7 +45,7 @@ module Inspec
45
45
 
46
46
  def self.fetch_validation_key_from_github(keyname)
47
47
  URI.open("https://raw.githubusercontent.com/inspec/inspec/main/etc/keys/#{keyname}.pem.pub") do |r|
48
- puts "Fetching validation key '#{keyname}' from github"
48
+ Inspec::Log.debug "Fetching validation key '#{keyname}' from github"
49
49
  dir = File.join(Inspec.config_dir, "keys")
50
50
  FileUtils.mkdir_p dir
51
51
  key_file = File.join(dir, "#{keyname}.pem.pub")
@@ -55,6 +55,11 @@ module Inspec::Reporters
55
55
  def extract_resource_id(r)
56
56
  # According to the RunData API, this is supposed to be an anonymous
57
57
  # class that represents a resource, with embedded instance methods....
58
+ # Prefer resource object if present and exposes resource_id
59
+ resource_candidate = r[:resource]
60
+ return resource_candidate.resource_id if resource_candidate.respond_to?(:resource_id)
61
+
62
+ # Fall back to resource_title
58
63
  resource_obj = r[:resource_title]
59
64
  return resource_obj.resource_id if resource_obj.respond_to?(:resource_id)
60
65
 
@@ -62,8 +67,13 @@ module Inspec::Reporters
62
67
  if resource_obj.is_a?(String)
63
68
  orig_str = resource_obj
64
69
  # Try to trim off the resource class - eg "File /some/path" => "/some/path"
65
- trimmed_str = orig_str.sub(/^#{r[:resource_class]}/i, "").strip
66
- trimmed_str.empty? ? orig_str : trimmed_str
70
+ resource_class = r[:resource_class].to_s
71
+ trimmed_str = orig_str.sub(/^#{Regexp.escape(resource_class)}/i, "").strip
72
+
73
+ # Cap the resource_id to a reasonable length to avoid bloating reports
74
+ max_length = 256
75
+ candidate = trimmed_str.empty? ? orig_str : trimmed_str
76
+ candidate.length > max_length ? candidate[0, max_length] : candidate
67
77
  else
68
78
  # Boo, InSpec is crazy, and we don't know what it possibly could be.
69
79
  # Failsafe for resource_id is empty string.
@@ -30,9 +30,15 @@ module Inspec::Resources
30
30
  its('value') { should_not be_empty }
31
31
  its('value') { should cmp == 1 }
32
32
  end
33
+
34
+ # Trust the SQL Server TLS certificate when using sqlcmd
35
+ sql_tls = mssql_session(user: 'myuser', password: 'mypassword', trust_server_certificate: true)
36
+ describe sql_tls.query(\"SELECT SERVERPROPERTY('ProductVersion') as \\\"version\\\";\").row(0).column('version') do
37
+ its('value') { should_not be_empty }
38
+ end
33
39
  EXAMPLE
34
40
 
35
- attr_reader :user, :password, :host, :port, :instance, :local_mode, :db_name
41
+ attr_reader :user, :password, :host, :port, :instance, :local_mode, :db_name, :trust_server_certificate
36
42
  def initialize(opts = {})
37
43
  @user = opts[:user]
38
44
  @password = opts[:password] || opts[:pass]
@@ -46,6 +52,7 @@ module Inspec::Resources
46
52
  end
47
53
  @instance = opts[:instance]
48
54
  @db_name = opts[:db_name]
55
+ @trust_server_certificate = !!opts[:trust_server_certificate] # rubocop:disable Style/DoubleNegation
49
56
 
50
57
  # check if sqlcmd is available
51
58
  raise Inspec::Exceptions::ResourceSkipped, "sqlcmd is missing" unless inspec.command("sqlcmd").exist?
@@ -57,6 +64,7 @@ module Inspec::Resources
57
64
  escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '""').gsub(/\$/, '\\$')
58
65
  # surpress 'x rows affected' in SQLCMD with 'set nocount on;'
59
66
  cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','"
67
+ cmd_string += " -C" if trust_server_certificate?
60
68
  cmd_string += " -U '#{@user}' -P '#{@password}'" unless @user.nil? || @password.nil?
61
69
  cmd_string += " -d '#{@db_name}'" unless @db_name.nil?
62
70
  unless local_mode?
@@ -94,6 +102,10 @@ module Inspec::Resources
94
102
  !!@local_mode # rubocop:disable Style/DoubleNegation
95
103
  end
96
104
 
105
+ def trust_server_certificate?
106
+ @trust_server_certificate
107
+ end
108
+
97
109
  def test_connection
98
110
  !query("select getdate()").empty?
99
111
  end
@@ -376,8 +376,15 @@ module Inspec::Resources
376
376
  'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
377
377
  ]
378
378
 
379
- # add 64 bit search paths
380
- if inspec.os.arch == "x86_64"
379
+ # Add WOW6432Node paths for 32-bit apps on 64-bit Windows.
380
+ # Include these unless the system is explicitly 32-bit (i386) — on 32-bit
381
+ # Windows, WOW6432Node does not exist since all apps register under the
382
+ # main Uninstall key.
383
+ # When os.arch is nil (e.g., train falls back to read_cmd_os in a PowerShell
384
+ # WinRM session where %PROCESSOR_ARCHITECTURE% is not expanded), we still
385
+ # include the WOW6432Node paths since virtually all modern Windows systems
386
+ # are 64-bit.
387
+ unless inspec.os.arch == "i386"
381
388
  search_paths << 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
382
389
  search_paths << 'HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
383
390
  end
data/lib/inspec/rule.rb CHANGED
@@ -48,12 +48,23 @@ module Inspec
48
48
  return unless block_given?
49
49
 
50
50
  begin
51
- instance_eval(&block)
52
-
53
- # By applying waivers *after* the instance eval, we assure that
54
- # waivers have higher precedence than only_if.
51
+ # Pre-check: apply waivers before evaluating the control block.
52
+ # If the control is waived with run: false, skip the block entirely
53
+ # to avoid eager resource evaluation (e.g., `command('find /').stdout`
54
+ # executing expensive commands for waived controls).
55
55
  __apply_waivers
56
56
 
57
+ unless @__skip_rule[:result] && @__skip_rule[:type] == :waiver
58
+ instance_eval(&block)
59
+
60
+ # Re-apply waivers after instance eval. This is a no-op in practice:
61
+ # run:false waivers are already handled by the pre-check above (the
62
+ # unless guard prevents instance_eval from running at all), and
63
+ # run:true / no-run-key waivers do not set a skip flag. Kept for
64
+ # defensive correctness in case waiver state changes during eval.
65
+ __apply_waivers
66
+ end
67
+
57
68
  rescue SystemStackError, StandardError => e
58
69
  # We've encountered an exception while trying to eval the code inside the
59
70
  # control block. We need to prevent the exception from bubbling up, and
@@ -6,7 +6,6 @@ module Inspec
6
6
  def guess_install_context
7
7
  # These all work by simple path recognition
8
8
  return "chef-workstation" if chef_workstation_install?
9
- return "omnibus" if omnibus_install?
10
9
  return "chefdk" if chefdk_install?
11
10
  return "habitat" if habitat_install?
12
11
 
@@ -36,10 +35,6 @@ module Inspec
36
35
  !!src_root.match(%r{hab/pkgs/chef/inspec/\d+\.\d+\.\d+/\d{14}})
37
36
  end
38
37
 
39
- def omnibus_install?
40
- !!(src_root.start_with?("/opt/inspec") || src_root.start_with?("C:/opscode/inspec"))
41
- end
42
-
43
38
  def rubygem_install?
44
39
  !!src_root.match(%r{gems/inspec-\d+\.\d+\.\d+})
45
40
  end
@@ -24,6 +24,37 @@ module Inspec
24
24
  @memo = memo
25
25
  end
26
26
 
27
+ def extract_node_value(node)
28
+ case node.class.to_s
29
+ when "RuboCop::AST::HashNode"
30
+ # Handle hash nodes
31
+ values = {}
32
+ node.children.each do |pair_node|
33
+ values.merge!(pair_node.key.value => extract_node_value(pair_node.value))
34
+ end
35
+ values
36
+ when "RuboCop::AST::ArrayNode"
37
+ # Handle array nodes
38
+ node.children.map { |element| extract_node_value(element) }
39
+ else
40
+ # Handle simple nodes (strings, numbers, symbols, booleans, nil, etc.)
41
+ if node.respond_to?(:type)
42
+ case node.type
43
+ when :true
44
+ true
45
+ when :false
46
+ false
47
+ when :nil
48
+ nil
49
+ else
50
+ node.respond_to?(:value) ? node.value : node
51
+ end
52
+ else
53
+ node.respond_to?(:value) ? node.value : node
54
+ end
55
+ end
56
+ end
57
+
27
58
  def collect_input(input_children)
28
59
  input_name = input_children.children[2].value
29
60
 
@@ -39,15 +70,9 @@ module Inspec
39
70
  if VALID_INPUT_OPTIONS.include?(child_node.key.value)
40
71
  if child_node.value.class == RuboCop::AST::Node && REQUIRED_VALUES_MAP.key?(child_node.value.type)
41
72
  opts.merge!(child_node.key.value => REQUIRED_VALUES_MAP[child_node.value.type])
42
- elsif child_node.value.class == RuboCop::AST::HashNode
43
- # Here value will be a hash
44
- values = {}
45
- child_node.value.children.each do |grand_child_node|
46
- values.merge!(grand_child_node.key.value => grand_child_node.value.value)
47
- end
48
- opts.merge!(child_node.key.value => values)
49
73
  else
50
- opts.merge!(child_node.key.value => child_node.value.value)
74
+ # Use the helper method to recursively extract values from any node type
75
+ opts.merge!(child_node.key.value => extract_node_value(child_node.value))
51
76
  end
52
77
  end
53
78
  end
@@ -313,8 +338,11 @@ module Inspec
313
338
  collectors.push InputCollectorWithinControlBlock.new(@memo)
314
339
  collectors.push TestsCollector.new(control_data) if include_tests
315
340
 
316
- begin_block.each_node do |node_within_control|
317
- collectors.each { |collector| collector.process(node_within_control) }
341
+ # Handle empty control blocks (e.g., control "id" do end)
342
+ if begin_block
343
+ begin_block.each_node do |node_within_control|
344
+ collectors.each { |collector| collector.process(node_within_control) }
345
+ end
318
346
  end
319
347
 
320
348
  memo[:controls].push control_data
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "7.0.107".freeze
2
+ VERSION = "7.2.1".freeze
3
3
  end
@@ -140,6 +140,10 @@ module InspecPlugins
140
140
  desc: "Enable legacy functionality, activating both legacy export and legacy check."
141
141
  def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
142
142
  Inspec.with_feature("inspec-cli-compliance-upload") {
143
+ if options["overwrite"]
144
+ Inspec.deprecate(:cli_option_compliance_overwrite, "The --overwrite option is deprecated because it does not work with Automate as expected.")
145
+ end
146
+
143
147
  config = InspecPlugins::Compliance::Configuration.new
144
148
  return unless loggedin(config)
145
149
 
@@ -57,7 +57,7 @@ module InspecPlugins
57
57
  path = profile.root_path
58
58
  logger.debug("Setting up #{path} for Habitat...")
59
59
 
60
- plan_file = File.join(path, "habitat", "plan.sh")
60
+ plan_file = File.join(path, "habitat", "x86_64-linux", "plan.sh")
61
61
  logger.info("Generating Habitat plan at #{plan_file}...")
62
62
  vars = {
63
63
  profile: profile,
@@ -426,7 +426,7 @@ module InspecPlugins
426
426
  "at https://github.com/inspec/inspec/issues/new")
427
427
  ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
428
428
  rescue Inspec::Plugin::V2::InstallError => e
429
- # This change is required for Ruby 3.3 upgrade
429
+ # This change is compatible with various versions of Ruby, including Ruby 3.3
430
430
  # Using Inspec::Log::level breaks with error `undefined method nil` in Ruby log library
431
431
  Inspec::Log.debug e.backtrace
432
432
 
@@ -7,7 +7,11 @@ module SourceReaders
7
7
  priority 20
8
8
 
9
9
  def self.resolve(target)
10
- return new(target) unless target.files.grep(/gemspec/).empty?
10
+ # Only match if gemspec is at root level, not in vendor directories
11
+ # This prevents archived/vendored profiles from being treated as gem profiles
12
+ gemspec_files = target.files.grep(/gemspec/)
13
+ root_gemspec = gemspec_files.reject { |f| f.start_with?("vendor/") }
14
+ return new(target) unless root_gemspec.empty?
11
15
 
12
16
  nil
13
17
  end
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: 7.0.107
4
+ version: 7.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-20 00:00:00.000000000 Z
11
+ date: 2026-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -314,14 +314,14 @@ dependencies:
314
314
  requirements:
315
315
  - - "~>"
316
316
  - !ruby/object:Gem::Version
317
- version: '2.4'
317
+ version: '2.9'
318
318
  type: :runtime
319
319
  prerelease: false
320
320
  version_requirements: !ruby/object:Gem::Requirement
321
321
  requirements:
322
322
  - - "~>"
323
323
  - !ruby/object:Gem::Version
324
- version: '2.4'
324
+ version: '2.9'
325
325
  - !ruby/object:Gem::Dependency
326
326
  name: parslet
327
327
  requirement: !ruby/object:Gem::Requirement
@@ -441,7 +441,7 @@ dependencies:
441
441
  version: '3.16'
442
442
  - - ">="
443
443
  - !ruby/object:Gem::Version
444
- version: 3.16.1
444
+ version: 3.16.5
445
445
  type: :runtime
446
446
  prerelease: false
447
447
  version_requirements: !ruby/object:Gem::Requirement
@@ -451,7 +451,7 @@ dependencies:
451
451
  version: '3.16'
452
452
  - - ">="
453
453
  - !ruby/object:Gem::Version
454
- version: 3.16.1
454
+ version: 3.16.5
455
455
  - !ruby/object:Gem::Dependency
456
456
  name: chef-licensing
457
457
  requirement: !ruby/object:Gem::Requirement
@@ -484,10 +484,12 @@ files:
484
484
  - Gemfile
485
485
  - LICENSE
486
486
  - etc/deprecations.json
487
+ - etc/env.default.sh
487
488
  - etc/features.sig
488
489
  - etc/features.yaml
489
490
  - etc/keys/progress-2022-05-04.pem.pub
490
491
  - etc/plugin_filters.json
492
+ - etc/reference-repos.txt
491
493
  - inspec-core.gemspec
492
494
  - lib/bundles/README.md
493
495
  - lib/bundles/inspec-compliance/api.rb