inspec-core 4.46.13 → 4.49.0

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: 1cc013914b6503c547eeb5fbba13ce8398cf039236b82a0422339a8b7d178649
4
- data.tar.gz: bb763eb39cb82fa264417d15147769d9d4b3fe1dff34ac40351712a35c6dbcb3
3
+ metadata.gz: 31dcab9ba9621f43755fc390ad061c08b7e6ab19466d26a38921d33960e1bbf5
4
+ data.tar.gz: eecdf0ec772ef012bfbf5185b379c47dd008fe902b9e91d4feee6979b0294c0f
5
5
  SHA512:
6
- metadata.gz: 492c4bbde3afe3c8be2d7640bb5e6a04f973a762aa2b541231dc61a3862d2d4d3248a49ff9b149ca66fa07eba83e1cd61260185a61fb073ba6a3cc9b542ac04f
7
- data.tar.gz: 89b55b1c8d8da24e1266bf6e19f688d284b88b18ec36c97f3f088c6f0422ac6ae6b0ddcab867bcb174ae789fc8e5bb334ed40cfd49adb26c7c3eb401c3164123
6
+ metadata.gz: 1059703ad59c2bf7c213a0914f94a8852cc550b1d305f634e07a08b364edae5c0f550927a8bcec9e712cd313949388082fdebf5c3164147ef12c21df952281b9
7
+ data.tar.gz: 1d4e6e64b8851c40349b7d696d46904fa73c0683d19c70afaa942a4c4bef4591a3ed4d7ec2c89aa5f7717da70617d70f182a7e9b894338da77592231b4c62234
@@ -174,6 +174,10 @@ module Inspec
174
174
  desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
175
175
  option :filter_empty_profiles, type: :boolean, default: false,
176
176
  desc: "Filter empty profiles (profiles without controls) from the report."
177
+ option :filter_waived_controls, type: :boolean,
178
+ desc: "Do not execute waived controls in InSpec at all. Must use with --waiver-file. Ignores `run` setting of waiver file."
179
+ option :retain_waiver_data, type: :boolean,
180
+ desc: "EXPERIMENTAL: Only works in conjunction with --filter-waived-controls, retains waiver data about controls that were skipped"
177
181
  option :command_timeout, type: :numeric,
178
182
  desc: "Maximum seconds to allow commands to run during execution.",
179
183
  long_desc: "Maximum seconds to allow commands to run during execution. A timed out command is considered an error."
data/lib/inspec/cli.rb CHANGED
@@ -122,8 +122,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
122
122
  end
123
123
  puts
124
124
 
125
- if result[:errors].empty? && result[:warnings].empty?
126
- ui.plain_line("No errors or warnings")
125
+ if result[:errors].empty? && result[:warnings].empty? && result[:offenses].empty?
126
+ ui.plain_line("No errors, warnings, or offenses")
127
127
  else
128
128
  item_msg = lambda { |item|
129
129
  pos = [item[:file], item[:line], item[:column]].compact.join(":")
@@ -135,11 +135,18 @@ class Inspec::InspecCLI < Inspec::BaseCLI
135
135
 
136
136
  puts
137
137
 
138
+ unless result[:offenses].empty?
139
+ puts "Offenses:\n"
140
+ result[:offenses].each { |item| ui.cyan(" #{Inspec::UI::GLYPHS[:script_x]} #{item_msg.call(item)}\n\n") }
141
+ end
142
+
143
+ offenses = ui.cyan("#{result[:offenses].length} offenses", print: false)
138
144
  errors = ui.red("#{result[:errors].length} errors", print: false)
139
145
  warnings = ui.yellow("#{result[:warnings].length} warnings", print: false)
140
- ui.plain_line("Summary: #{errors}, #{warnings}")
146
+ ui.plain_line("Summary: #{errors}, #{warnings}, #{offenses}")
141
147
  end
142
148
  end
149
+
143
150
  ui.exit Inspec::UI::EXIT_USAGE_ERROR unless result[:summary][:valid]
144
151
  rescue StandardError => e
145
152
  pretty_handle_exception(e)
@@ -217,6 +217,9 @@ module Inspec
217
217
 
218
218
  locked_dependencies.each(&:collect_tests)
219
219
 
220
+ tests = filter_waived_controls
221
+
222
+ # Collect tests
220
223
  tests.each do |path, content|
221
224
  next if content.nil? || content.empty?
222
225
 
@@ -233,6 +236,65 @@ module Inspec
233
236
  @runner_context.all_rules
234
237
  end
235
238
 
239
+ # Wipe out waived controls
240
+ def filter_waived_controls
241
+ cfg = Inspec::Config.cached
242
+ return tests unless cfg["filter_waived_controls"]
243
+
244
+ ## Find the waivers file
245
+ # - TODO: cli_opts and instance_variable_get could be exposed
246
+ waiver_paths = cfg.instance_variable_get(:@cli_opts)["waiver_file"]
247
+ if waiver_paths.blank?
248
+ Inspec::Log.error "Must use --waiver-file with --filter-waived-controls"
249
+ Inspec::UI.new.exit(:usage_error)
250
+ end
251
+
252
+ # # Pull together waiver
253
+ waived_control_ids = []
254
+ waiver_paths.each do |waiver_path|
255
+ waiver_content = YAML.load_file(waiver_path)
256
+ unless waiver_content
257
+ # Note that we will have already issued a detailed warning
258
+ Inspec::Log.error "YAML parsing error in #{waiver_path}"
259
+ Inspec::UI.new.exit(:usage_error)
260
+ end
261
+ waived_control_ids << waiver_content.keys
262
+ end
263
+ waived_control_id_regex = "(#{waived_control_ids.join("|")})"
264
+
265
+ ## Purge tests (this could be doone in next block for performance)
266
+ ## TODO: implement earlier with pure AST and pure autocorrect AST
267
+ filtered_tests = {}
268
+ if cfg["retain_waiver_data"]
269
+ # VERY EXPERIMENTAL, but an empty describe block at the top level
270
+ # of the control blocks evaluation of ruby code until later-term
271
+ # waivers (behind the scenes this tells RSpec to hold on and use its internals to lazy load the code). This allows current waiver-data (e.g. skips) to still
272
+ # be processed and rendered
273
+ tests.each do |control_filename, source_code|
274
+ cleared_tests = source_code.scan(/control\s+['"].+?['"].+?(?=(?:control\s+['"].+?['"])|\z)/m).collect do |element|
275
+ next if element.blank?
276
+
277
+ if element&.match?(waived_control_id_regex)
278
+ splitlines = element.split("\n")
279
+ splitlines[0] + "\ndescribe '---' do\n" + splitlines[1..-1].join("\n") + "\nend\n"
280
+ else
281
+ element
282
+ end
283
+ end.join("")
284
+ filtered_tests[control_filename] = cleared_tests
285
+ end
286
+ else
287
+ tests.each do |control_filename, source_code|
288
+ cleared_tests = source_code.scan(/control\s+['"].+?['"].+?(?=(?:control\s+['"].+?['"])|\z)/m).select do |control_code|
289
+ !control_code.match?(waived_control_id_regex)
290
+ end.join("")
291
+
292
+ filtered_tests[control_filename] = cleared_tests
293
+ end
294
+ end
295
+ filtered_tests
296
+ end
297
+
236
298
  # This creates the list of controls provided in the --controls options which need to be include
237
299
  # for evaluation.
238
300
  def include_controls_list
@@ -386,6 +448,43 @@ module Inspec
386
448
  res
387
449
  end
388
450
 
451
+ def cookstyle_linting_check
452
+ msgs = []
453
+ output = cookstyle_rake_output.split("Offenses:").last
454
+ msgs = output.split("\n").select { |x| x =~ /[A-Z]:/ } unless output.nil?
455
+ msgs
456
+ end
457
+
458
+ # Cookstyle linting rake run output
459
+ def cookstyle_rake_output
460
+ require "cookstyle"
461
+ require "rubocop/rake_task"
462
+ begin
463
+ RuboCop::RakeTask.new(:cookstyle_lint) do |spec|
464
+ spec.options += [
465
+ "--display-cop-names",
466
+ "--parallel",
467
+ "--only=InSpec/Deprecations",
468
+ ]
469
+ spec.patterns += Dir.glob("#{@target}/**/*.rb").reject { |f| File.directory?(f) }
470
+ spec.fail_on_error = false
471
+ end
472
+ rescue LoadError
473
+ puts "Rubocop is not available. Install the rubocop gem to run the lint tests."
474
+ end
475
+ begin
476
+ stdout = StringIO.new
477
+ $stdout = stdout
478
+ Rake::Task["cookstyle_lint"].invoke
479
+ $stdout = STDOUT
480
+ Rake.application["cookstyle_lint"].reenable
481
+ stdout.string
482
+ rescue => e
483
+ puts "Cookstyle lint checks could not be performed. Error while running cookstyle - #{e}"
484
+ ""
485
+ end
486
+ end
487
+
389
488
  # Check if the profile is internally well-structured. The logger will be
390
489
  # used to print information on errors and warnings which are found.
391
490
  #
@@ -402,6 +501,7 @@ module Inspec
402
501
  },
403
502
  errors: [],
404
503
  warnings: [],
504
+ offenses: [],
405
505
  }
406
506
 
407
507
  entry = lambda { |file, line, column, control, msg|
@@ -424,6 +524,10 @@ module Inspec
424
524
  result[:errors].push(entry.call(file, line, column, control, msg))
425
525
  }
426
526
 
527
+ offense = lambda { |file, line, column, control, msg|
528
+ result[:offenses].push(entry.call(file, line, column, control, msg))
529
+ }
530
+
427
531
  @logger.info "Checking profile in #{@target}"
428
532
  meta_path = @source_reader.target.abs_path(@source_reader.metadata.ref)
429
533
 
@@ -486,8 +590,15 @@ module Inspec
486
590
  warn.call(sfile, sline, nil, id, "Control #{id} has no tests defined") if control[:checks].nil? || control[:checks].empty?
487
591
  end
488
592
 
489
- # profile is valid if we could not find any error
490
- result[:summary][:valid] = result[:errors].empty?
593
+ # Running cookstyle to check for code offenses
594
+ cookstyle_linting_check.each do |lint_output|
595
+ data = lint_output.split(":")
596
+ msg = "#{data[-2]}:#{data[-1]}"
597
+ offense.call(data[0], data[1], data[2], nil, msg)
598
+ end
599
+
600
+ # profile is valid if we could not find any error & offenses
601
+ result[:summary][:valid] = result[:errors].empty? && result[:offenses].empty?
491
602
 
492
603
  @logger.info "Control definitions OK." if result[:warnings].empty?
493
604
  result
@@ -0,0 +1,64 @@
1
+ module Inspec::Resources
2
+ class Cassandra < Inspec.resource(1)
3
+ name "cassandra"
4
+ supports platform: "unix"
5
+ supports platform: "windows"
6
+
7
+ desc "The 'cassandra' resource is a helper for the 'cql_conf'"
8
+
9
+ attr_reader :conf_path
10
+
11
+ def initialize
12
+ case inspec.os[:family]
13
+ when "debian", "redhat", "linux", "suse"
14
+ determine_conf_dir_and_path_in_linux
15
+ when "windows"
16
+ determine_conf_dir_and_path_in_windows
17
+ end
18
+ end
19
+
20
+ def to_s
21
+ "CassandraDB"
22
+ end
23
+
24
+ private
25
+
26
+ def determine_conf_dir_and_path_in_linux
27
+ cassandra_home = inspec.os_env("CASSANDRA_HOME").content
28
+
29
+ if cassandra_home.nil? || cassandra_home.empty?
30
+ warn "$CASSANDRA_HOME environment variable not set in the system"
31
+ nil
32
+ else
33
+ conf_path = "#{cassandra_home}/cassandra.yaml"
34
+ if !inspec.file(conf_path).exist?
35
+ warn "Cassandra conf file not found in #{cassandra_home} directory."
36
+ nil
37
+ else
38
+ @conf_path = conf_path
39
+ end
40
+ end
41
+ rescue => e
42
+ fail_resource "Errors reading cassandra conf file: #{e}"
43
+ end
44
+
45
+ def determine_conf_dir_and_path_in_windows
46
+ cassandra_home = inspec.os_env("CASSANDRA_HOME").content
47
+
48
+ if cassandra_home.nil? || cassandra_home.empty?
49
+ warn "CASSANDRA_HOME environment variable not set in the system"
50
+ nil
51
+ else
52
+ conf_path = "#{cassandra_home}\\conf\\cassandra.yaml"
53
+ if !inspec.file(conf_path).exist?
54
+ warn "Cassandra conf file not found in #{cassandra_home}\\conf directory."
55
+ nil
56
+ else
57
+ @conf_path = conf_path
58
+ end
59
+ end
60
+ rescue => e
61
+ fail_resource "Errors reading cassandra conf file: #{e}"
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,47 @@
1
+ require "inspec/resources/json"
2
+ require "inspec/resources/cassandra"
3
+
4
+ module Inspec::Resources
5
+ class CassandradbConf < JsonConfig
6
+ name "cassandradb_conf"
7
+ supports platform: "unix"
8
+ supports platform: "windows"
9
+ desc "Use the cql_conf InSpec audit resource to test the contents of the configuration file for Cassandra DB"
10
+ example <<~EXAMPLE
11
+ describe cassandradb_conf do
12
+ its('listen_address') { should eq '0.0.0.0' }
13
+ end
14
+ EXAMPLE
15
+
16
+ def initialize(conf_path = nil)
17
+ cassandra = nil
18
+ if conf_path.nil?
19
+ cassandra = inspec.cassandra
20
+ @conf_path = cassandra.conf_path
21
+ else
22
+ @conf_path = conf_path
23
+ end
24
+
25
+ if cassandra && cassandra.resource_failed?
26
+ raise cassandra.resource_exception_message
27
+ elsif @conf_path.nil?
28
+ return skip_resource "Cassandra db conf path is not set"
29
+ end
30
+
31
+ super(@conf_path)
32
+ end
33
+
34
+ private
35
+
36
+ def parse(content)
37
+ YAML.load(content)
38
+ rescue => e
39
+ raise Inspec::Exceptions::ResourceFailed, "Unable to parse `cassandra.yaml` file: #{e.message}"
40
+ end
41
+
42
+ def resource_base_name
43
+ "Cassandra Configuration"
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,68 @@
1
+ module Inspec::Resources
2
+ class Lines
3
+ attr_reader :output
4
+
5
+ def initialize(raw, desc)
6
+ @output = raw
7
+ @desc = desc
8
+ end
9
+
10
+ def to_s
11
+ @desc
12
+ end
13
+ end
14
+
15
+ class CassandradbSession < Inspec.resource(1)
16
+ name "cassandradb_session"
17
+ supports platform: "unix"
18
+ supports platform: "windows"
19
+ desc "Use the cassandradb_session InSpec resource to test commands against an Cassandra database"
20
+ example <<~EXAMPLE
21
+ cql = cassandradb_session(user: 'my_user', password: 'password', host: 'host', port: 'port')
22
+ describe cql.query("SELECT cluster_name FROM system.local") do
23
+ its('output') { should match /Test Cluster/ }
24
+ end
25
+ EXAMPLE
26
+
27
+ attr_reader :user, :password, :host, :port
28
+
29
+ def initialize(opts = {})
30
+ @user = opts[:user] || "cassandra"
31
+ @password = opts[:password] || "cassandra"
32
+ @host = opts[:host]
33
+ @port = opts[:port]
34
+ end
35
+
36
+ def query(q)
37
+ cassandra_cmd = create_cassandra_cmd(q)
38
+ cmd = inspec.command(cassandra_cmd)
39
+ out = cmd.stdout + "\n" + cmd.stderr
40
+ if cmd.exit_status != 0 || out =~ /Unable to connect to any servers/ || out.downcase =~ /^error:.*/
41
+ raise Inspec::Exceptions::ResourceFailed, "Cassandra query with errors: #{out}"
42
+ else
43
+ Lines.new(cmd.stdout.strip, "Cassandra query: #{q}")
44
+ end
45
+ end
46
+
47
+ def to_s
48
+ "Cassandra DB Session"
49
+ end
50
+
51
+ private
52
+
53
+ def create_cassandra_cmd(q)
54
+ # TODO: simple escape, must be handled by a library
55
+ # that does this securely
56
+ escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '\\"').gsub(/\$/, '\\$')
57
+
58
+ # construct the query
59
+ command = "cqlsh"
60
+ command += " #{@host}" unless @host.nil?
61
+ command += " #{@port}" unless @port.nil?
62
+ command += " -u #{@user}"
63
+ command += " -p #{@password}"
64
+ command += " --execute '#{escaped_query}'"
65
+ command
66
+ end
67
+ end
68
+ end
@@ -22,6 +22,18 @@ module Inspec::Resources
22
22
  end
23
23
  end
24
24
 
25
+ # Class defined to check for members without case-sensitivity
26
+ class Members < Array
27
+ def initialize(group_members)
28
+ @group_members = group_members
29
+ super
30
+ end
31
+
32
+ def include?(user)
33
+ !(@group_members.select { |group_member| group_member.casecmp?(user) }.empty?)
34
+ end
35
+ end
36
+
25
37
  class Groups < Inspec.resource(1)
26
38
  include GroupManagementSelector
27
39
 
@@ -82,6 +94,7 @@ module Inspec::Resources
82
94
  # its('gid') { should eq 0 }
83
95
  # end
84
96
  #
97
+
85
98
  class Group < Inspec.resource(1)
86
99
  include GroupManagementSelector
87
100
 
@@ -118,11 +131,13 @@ module Inspec::Resources
118
131
  end
119
132
 
120
133
  def members
121
- flatten_entry(group_info, "members") || empty_value_for_members
134
+ members_list = flatten_entry(group_info, "members") || empty_value_for_members
135
+ inspec.os.windows? ? Members.new(members_list) : members_list
122
136
  end
123
137
 
124
138
  def members_array
125
- flatten_entry(group_info, "members_array") || []
139
+ members_list = flatten_entry(group_info, "members_array") || []
140
+ inspec.os.windows? ? Members.new(members_list) : members_list
126
141
  end
127
142
 
128
143
  def local
@@ -150,7 +165,11 @@ module Inspec::Resources
150
165
  def group_info
151
166
  # we need a local copy for the block
152
167
  group = @group.dup
153
- @groups_cache ||= inspec.groups.where { name == group }
168
+ if inspec.os.windows?
169
+ @groups_cache ||= inspec.groups.where { name.casecmp?(group) }
170
+ else
171
+ @groups_cache ||= inspec.groups.where { name == group }
172
+ end
154
173
  end
155
174
 
156
175
  def empty_value_for_members
@@ -42,6 +42,7 @@ module Inspec::Resources
42
42
  end
43
43
 
44
44
  def query(sql)
45
+ raise Inspec::Exceptions::ResourceSkipped, "#{resource_exception_message}" if resource_skipped?
45
46
  raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
46
47
 
47
48
  if @sqlcl_bin && inspec.command(@sqlcl_bin).exist?
@@ -78,7 +79,14 @@ module Inspec::Resources
78
79
  # using a db_role
79
80
  # su, using a db_role
80
81
  def command_builder(format_options, query)
81
- verified_query = verify_query(query)
82
+ if @db_role.nil? || @su_user.nil?
83
+ verified_query = verify_query(query)
84
+ else
85
+ escaped_query = query.gsub(/\\\\/, "\\").gsub(/"/, '\\"')
86
+ escaped_query = escaped_query.gsub("$", '\\$') unless escaped_query.include? "\\$"
87
+ verified_query = verify_query(escaped_query)
88
+ end
89
+
82
90
  sql_prefix, sql_postfix = "", ""
83
91
  if inspec.os.windows?
84
92
  sql_prefix = %{@'\n#{format_options}\n#{verified_query}\nEXIT\n'@ | }
@@ -87,11 +95,14 @@ module Inspec::Resources
87
95
  end
88
96
 
89
97
  if @db_role.nil?
90
- "#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}"
98
+ %{#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}}
91
99
  elsif @su_user.nil?
92
- "#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}"
100
+ %{#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}}
93
101
  else
94
- "su - #{@su_user} -c env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"
102
+ # oracle_query_string is echoed to be able to extract the query output clearly
103
+ # su - su_user in certain versions of oracle returns a message
104
+ # Example of msg with query output: The Oracle base remains unchanged with value /oracle\n\nVALUE\n3\n
105
+ %{su - #{@su_user} -c "echo 'oracle_query_string'; env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"}
95
106
  end
96
107
  end
97
108
 
@@ -101,9 +112,15 @@ module Inspec::Resources
101
112
  end
102
113
 
103
114
  def parse_csv_result(stdout)
104
- output = stdout.sub(/\r/, "").strip
115
+ output = stdout.split("oracle_query_string")[-1]
116
+ # comma_query_sub replaces the csv delimiter "," in the output.
117
+ # Handles CSV parsing of data like this (DROP,3) etc
118
+ output = output.sub(/\r/, "").strip.gsub(",", "comma_query_sub")
105
119
  converter = ->(header) { header.downcase }
106
- CSV.parse(output, headers: true, header_converters: converter).map { |row| Hashie::Mash.new(row.to_h) }
120
+ CSV.parse(output, headers: true, header_converters: converter).map do |row|
121
+ revised_row = row.entries.flatten.map { |entry| entry.gsub("comma_query_sub", ",") }
122
+ Hashie::Mash.new([revised_row].to_h)
123
+ end
107
124
  end
108
125
  end
109
126
  end
@@ -204,7 +204,9 @@ module Inspec::Resources
204
204
  alias group groupname
205
205
 
206
206
  def groups
207
- identity[:groups] unless identity.nil?
207
+ unless identity.nil?
208
+ inspec.os.windows? ? UserGroups.new(identity[:groups]) : identity[:groups]
209
+ end
208
210
  end
209
211
 
210
212
  def home
@@ -314,6 +316,18 @@ module Inspec::Resources
314
316
  end
315
317
  end
316
318
 
319
+ # Class defined to compare for groups without case-sensitivity
320
+ class UserGroups < Array
321
+ def initialize(user_groups)
322
+ @user_groups = user_groups
323
+ super
324
+ end
325
+
326
+ def include?(group)
327
+ !(@user_groups.select { |user_group| user_group.casecmp?(group) }.empty?)
328
+ end
329
+ end
330
+
317
331
  # This is an abstract class that every user provoider has to implement.
318
332
  # A user provider implements a system abstracts and helps the InSpec resource
319
333
  # hand-over system specific behavior to those providers
@@ -622,7 +636,7 @@ module Inspec::Resources
622
636
  name, _domain = parse_windows_account(username)
623
637
  return if collect_user_details.nil?
624
638
 
625
- res = collect_user_details.select { |user| user[:username] == name }
639
+ res = collect_user_details.select { |user| user[:username].casecmp? name }
626
640
  res[0] unless res.empty?
627
641
  end
628
642
 
@@ -77,7 +77,7 @@ module Inspec::Resources
77
77
 
78
78
  def load_firewall_profile(profile_name)
79
79
  <<-EOH
80
- Remove-TypeData System.Array # workaround for PS bug here: https://bit.ly/2SRMQ8M
80
+ Get-TypeData -TypeName System.Array | Remove-TypeData # workaround for PS bug here: https://bit.ly/2SRMQ8M
81
81
  $profile = Get-NetFirewallProfile -Name "#{profile_name}"
82
82
  $count = @($profile | Get-NetFirewallRule).Count
83
83
  ([PSCustomObject]@{
@@ -37,6 +37,9 @@ require "inspec/resources/chocolatey_package"
37
37
  require "inspec/resources/command"
38
38
  require "inspec/resources/cran"
39
39
  require "inspec/resources/cpan"
40
+ require "inspec/resources/cassandradb_session"
41
+ require "inspec/resources/cassandradb_conf"
42
+ require "inspec/resources/cassandra"
40
43
  require "inspec/resources/crontab"
41
44
  require "inspec/resources/dh_params"
42
45
  require "inspec/resources/directory"
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.46.13".freeze
2
+ VERSION = "4.49.0".freeze
3
3
  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: 4.46.13
4
+ version: 4.49.0
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: 2021-09-28 00:00:00.000000000 Z
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -505,6 +505,9 @@ files:
505
505
  - lib/inspec/resources/bond.rb
506
506
  - lib/inspec/resources/bridge.rb
507
507
  - lib/inspec/resources/bsd_service.rb
508
+ - lib/inspec/resources/cassandra.rb
509
+ - lib/inspec/resources/cassandradb_conf.rb
510
+ - lib/inspec/resources/cassandradb_session.rb
508
511
  - lib/inspec/resources/chocolatey_package.rb
509
512
  - lib/inspec/resources/chrony_conf.rb
510
513
  - lib/inspec/resources/command.rb