inspec-core 7.0.107 → 7.1.7

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: d615f8a9108fd5631217d136cb8b29e8d1c44f6b049a53c2618907df84876fa8
4
+ data.tar.gz: 7745773bd58acc11ac0d8acc9cf7c7e3d1bcb945556a6686514d441a6b8375e0
5
5
  SHA512:
6
- metadata.gz: 5e15e616ac53c257b7f3b23744745798cb22fbaa91ff6668140bf40ecfee92da7931e31949429fe337984c8716538ff84c8ca03acbcf9303fc93d45b20a3f4df
7
- data.tar.gz: 63064836ca735a8ab3dfe01ccfb4c2cdc791dbf9474e2eff83df893ad04ef79979f5850bc7536967b5b2d871d31ad4cbc0ef61aa1ca92dbcde30eeef72a00fd2
6
+ metadata.gz: 4aad4bdd8864cb072120a838b7e342d4d667f24d30cb1a160627f125d6ab9968888f6dc30b0391fed5241afc81c75c4d3bea5868fa6d8f0b26e2847c899d1885
7
+ data.tar.gz: a2f4f3c01f19816fd77c65db3ac2a737d23093d71dac78ee82bbede8b39816f18efc6f94a5f7ae718533f065f9b87e9f577eeb42545f4b3fc5f75e4880ef8f98
data/Gemfile CHANGED
@@ -50,7 +50,7 @@ group :test do
50
50
  gem "nokogiri"
51
51
  gem "pry-byebug"
52
52
  gem "pry"
53
- gem "rake"
53
+ gem "rake", ">= 12.3.3"
54
54
  gem "simplecov"
55
55
  gem "simplecov_json_formatter"
56
56
  gem "webmock"
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"
@@ -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
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.1.7".freeze
3
3
  end
@@ -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
 
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.1.7
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-05-08 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