inspec-core 5.18.14 → 5.22.3
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 +4 -4
- data/Gemfile +19 -17
- data/inspec-core.gemspec +22 -22
- data/lib/inspec/base_cli.rb +19 -17
- data/lib/inspec/cli.rb +27 -25
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dsl.rb +9 -5
- data/lib/inspec/enhanced_outcomes.rb +19 -0
- data/lib/inspec/env_printer.rb +1 -1
- data/lib/inspec/exceptions.rb +2 -0
- data/lib/inspec/formatters/base.rb +69 -16
- data/lib/inspec/plugin/v2/loader.rb +19 -8
- data/lib/inspec/plugin/v2/plugin_types/reporter.rb +1 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +54 -0
- data/lib/inspec/profile.rb +9 -8
- data/lib/inspec/reporters/base.rb +1 -0
- data/lib/inspec/reporters/cli.rb +94 -3
- data/lib/inspec/reporters/json.rb +3 -1
- data/lib/inspec/reporters/yaml.rb +3 -1
- data/lib/inspec/reporters.rb +2 -1
- data/lib/inspec/resources/file.rb +1 -1
- data/lib/inspec/resources/http.rb +5 -5
- data/lib/inspec/resources/lxc.rb +65 -9
- data/lib/inspec/resources/mongodb_session.rb +5 -0
- data/lib/inspec/resources/nftables.rb +251 -0
- data/lib/inspec/resources/oracledb_session.rb +13 -4
- data/lib/inspec/resources/podman.rb +353 -0
- data/lib/inspec/resources/podman_container.rb +84 -0
- data/lib/inspec/resources/podman_image.rb +108 -0
- data/lib/inspec/resources/podman_network.rb +81 -0
- data/lib/inspec/resources/podman_pod.rb +101 -0
- data/lib/inspec/resources/podman_volume.rb +87 -0
- data/lib/inspec/resources/postgres_session.rb +2 -1
- data/lib/inspec/resources/service.rb +1 -1
- data/lib/inspec/resources.rb +1 -0
- data/lib/inspec/rule.rb +54 -17
- data/lib/inspec/run_data/control.rb +6 -0
- data/lib/inspec/run_data/statistics.rb +8 -2
- data/lib/inspec/runner.rb +18 -8
- data/lib/inspec/runner_rspec.rb +3 -2
- data/lib/inspec/schema/exec_json.rb +78 -2
- data/lib/inspec/schema/output_schema.rb +4 -1
- data/lib/inspec/schema/profile_json.rb +46 -0
- data/lib/inspec/schema.rb +91 -0
- data/lib/inspec/utils/convert.rb +8 -0
- data/lib/inspec/utils/podman.rb +24 -0
- data/lib/inspec/utils/simpleconfig.rb +10 -2
- data/lib/inspec/utils/waivers/csv_file_reader.rb +34 -0
- data/lib/inspec/utils/waivers/excel_file_reader.rb +39 -0
- data/lib/inspec/utils/waivers/json_file_reader.rb +15 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +61 -0
- data/lib/matchers/matchers.rb +15 -2
- data/lib/plugins/inspec-init/templates/profiles/alicloud/README.md +27 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/controls/example.rb +10 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/inputs.yml +1 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/inspec.yml +14 -0
- data/lib/plugins/inspec-reporter-html2/README.md +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +7 -1
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +10 -6
- data/lib/plugins/inspec-reporter-html2/templates/default.css +12 -0
- data/lib/plugins/inspec-reporter-html2/templates/selector.html.erb +7 -1
- data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +5 -2
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +39 -13
- metadata +26 -9
@@ -178,7 +178,19 @@ module Inspec::Plugin::V2
|
|
178
178
|
# TODO: enforce first-level version pinning
|
179
179
|
plugin_deps = [Gem::Dependency.new(plugin_gem_name.to_s, version_constraint)]
|
180
180
|
managed_gem_set = Gem::Resolver::VendorSet.new
|
181
|
-
|
181
|
+
|
182
|
+
list_managed_gems.each do |spec|
|
183
|
+
if Gem::Specification.load spec.gem_dir
|
184
|
+
managed_gem_set.add_vendor_gem(spec.name, spec.gem_dir)
|
185
|
+
else
|
186
|
+
# In case of invalid gemspec as mentioned in this PR https://github.com/brianmario/yajl-ruby/pull/223
|
187
|
+
# the add_vendor_gem breaks. So this is patch to fix the loading issue.
|
188
|
+
# Horribly, chdir to gemspec path to honor . in gemspec
|
189
|
+
Dir.chdir(spec.gem_dir) do |dir|
|
190
|
+
managed_gem_set.add_vendor_gem(spec.name, spec.gem_dir)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
182
194
|
|
183
195
|
# TODO: Next two lines merge our managed gems with the other gems available
|
184
196
|
# in our "local universe" - which may be the system, or it could be in a Bundler microcosm,
|
@@ -278,7 +290,12 @@ module Inspec::Plugin::V2
|
|
278
290
|
when :user_gem
|
279
291
|
status.entry_point = status.name.to_s
|
280
292
|
status.version = plugin_entry[:version]
|
281
|
-
|
293
|
+
# Fetch the summary of the gem from local gemspec file instead of remote call using Gem::SpecFetcher.fetcher.
|
294
|
+
unless plugin_entry[:version].nil? # safe check very rare case.
|
295
|
+
version_string = plugin_entry[:version].gsub(/[=,~,>,<]/, "").strip
|
296
|
+
plugin_name_with_version = "#{status.name}-#{version_string}"
|
297
|
+
status.description = fetch_gemspec(File.join(plugin_gem_path, "gems", plugin_name_with_version, "/", status.name.to_s + ".gemspec"))&.summary
|
298
|
+
end
|
282
299
|
when :path
|
283
300
|
status.entry_point = plugin_entry[:installation_path]
|
284
301
|
end
|
@@ -287,12 +304,6 @@ module Inspec::Plugin::V2
|
|
287
304
|
end
|
288
305
|
end
|
289
306
|
|
290
|
-
def fetch_plugin_specs(plugin_name)
|
291
|
-
fetcher = Gem::SpecFetcher.fetcher
|
292
|
-
plugin_dependency = Gem::Dependency.new(plugin_name)
|
293
|
-
fetcher.spec_for_dependency(plugin_dependency).flatten.first
|
294
|
-
end
|
295
|
-
|
296
307
|
def fixup_train_plugin_status(status)
|
297
308
|
status.api_generation = :'train-1'
|
298
309
|
if status.installation_type == :user_gem
|
@@ -11,6 +11,7 @@ module Inspec::Plugin::V2::PluginType
|
|
11
11
|
@running_controls_list = []
|
12
12
|
@control_checks_count_map = {}
|
13
13
|
@controls_count = nil
|
14
|
+
@notifications = {}
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
@@ -49,5 +50,58 @@ module Inspec::Plugin::V2::PluginType
|
|
49
50
|
@control_checks_count_map = RSpec.configuration.formatters.grep(Inspec::Formatters::Base).first.get_control_checks_count_map
|
50
51
|
end
|
51
52
|
end
|
53
|
+
|
54
|
+
def enhanced_outcomes
|
55
|
+
@enhanced_outcomes ||= RSpec.configuration.formatters.grep(Inspec::Formatters::Base).first.enhanced_outcomes
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_enhanced_outcomes(control_id)
|
59
|
+
if control_has_error(@notifications[control_id])
|
60
|
+
"error"
|
61
|
+
elsif control_has_impact_zero(@notifications[control_id])
|
62
|
+
"not_applicable"
|
63
|
+
elsif control_has_all_tests_skipped(@notifications[control_id])
|
64
|
+
"not_reviewed"
|
65
|
+
elsif control_has_any_tests_failed(@notifications[control_id])
|
66
|
+
"failed"
|
67
|
+
else
|
68
|
+
"passed"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def control_has_error(notifications)
|
73
|
+
notifications.any? do |notification_data|
|
74
|
+
notification, _status = notification_data
|
75
|
+
!notification.example.exception.nil? && !(notification.example.exception.is_a? RSpec::Expectations::ExpectationNotMetError) && !notification.example.exception.backtrace.nil? && (!notification.description.include? "No-op") # No-op exception occurs in case of not_applicable_if
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def control_has_all_tests_skipped(notifications)
|
80
|
+
notifications.all? do |notification_data|
|
81
|
+
_notification, status = notification_data
|
82
|
+
status == "skipped"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def control_has_any_tests_failed(notifications)
|
87
|
+
notifications.any? do |notification_data|
|
88
|
+
_notification, status = notification_data
|
89
|
+
status == "failed"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def control_has_impact_zero(notifications)
|
94
|
+
notification_data = notifications.first
|
95
|
+
notification_impact = notification_data.first.example.metadata[:impact]
|
96
|
+
notification_data && !notification_impact.nil? && notification_impact.to_f == 0.0
|
97
|
+
end
|
98
|
+
|
99
|
+
def collect_notifications(notification, control_id, status)
|
100
|
+
if @notifications[control_id].nil?
|
101
|
+
@notifications[control_id] = [[notification, status]]
|
102
|
+
else
|
103
|
+
@notifications[control_id].push([notification, status])
|
104
|
+
end
|
105
|
+
end
|
52
106
|
end
|
53
107
|
end
|
data/lib/inspec/profile.rb
CHANGED
@@ -383,24 +383,25 @@ module Inspec
|
|
383
383
|
@runner_context
|
384
384
|
end
|
385
385
|
|
386
|
-
|
386
|
+
# This collects the gem dependencies data from parent and its dependent profiles
|
387
|
+
def collect_gem_dependencies
|
387
388
|
gem_dependencies = []
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
end
|
392
|
-
all_profiles << self
|
393
|
-
all_profiles.each do |profile|
|
389
|
+
# This collects the dependent profiles gem dependencies if any
|
390
|
+
locked_dependencies.dep_list.each do |_name, dep|
|
391
|
+
profile = dep.profile
|
394
392
|
gem_dependencies << profile.metadata.gem_dependencies unless profile.metadata.gem_dependencies.empty?
|
395
393
|
end
|
394
|
+
# Appends the parent profile gem dependencies which are available through metadata
|
395
|
+
gem_dependencies << metadata.gem_dependencies unless metadata.gem_dependencies.empty?
|
396
396
|
gem_dependencies.flatten.uniq
|
397
397
|
end
|
398
398
|
|
399
399
|
# Loads the required gems specified in the Profile's metadata file from default inspec gems path i.e. ~/.inspec/gems
|
400
400
|
# else installs and loads them.
|
401
401
|
def load_gem_dependencies
|
402
|
-
gem_dependencies = collect_gem_dependencies
|
402
|
+
gem_dependencies = collect_gem_dependencies
|
403
403
|
gem_dependencies.each do |gem_data|
|
404
|
+
|
404
405
|
dependency_loader = DependencyLoader.new
|
405
406
|
if dependency_loader.gem_version_installed?(gem_data[:name], gem_data[:version]) ||
|
406
407
|
dependency_loader.gem_installed?(gem_data[:name])
|
data/lib/inspec/reporters/cli.rb
CHANGED
@@ -9,6 +9,9 @@ module Inspec::Reporters
|
|
9
9
|
"passed" => "\033[0;1;32m",
|
10
10
|
"skipped" => "\033[0;37m",
|
11
11
|
"reset" => "\033[0m",
|
12
|
+
"error" => "\033[34m",
|
13
|
+
"not_applicable" => "\033[36m",
|
14
|
+
"not_reviewed" => "\033[33m",
|
12
15
|
}.freeze
|
13
16
|
|
14
17
|
# Most currently available Windows terminals have poor support
|
@@ -18,6 +21,9 @@ module Inspec::Reporters
|
|
18
21
|
"skipped" => "[SKIP]",
|
19
22
|
"passed" => "[PASS]",
|
20
23
|
"unknown" => "[UNKN]",
|
24
|
+
"error" => "[ERR]",
|
25
|
+
"not_applicable" => "[N/A]",
|
26
|
+
"not_reviewed" => "[N/R]",
|
21
27
|
}.freeze
|
22
28
|
else
|
23
29
|
# Extended colors for everyone else
|
@@ -26,6 +32,9 @@ module Inspec::Reporters
|
|
26
32
|
"passed" => "\033[38;5;41m",
|
27
33
|
"skipped" => "\033[38;5;247m",
|
28
34
|
"reset" => "\033[0m",
|
35
|
+
"error" => "\033[0;38;5;21m",
|
36
|
+
"not_applicable" => "\033[0;38;5;117m",
|
37
|
+
"not_reviewed" => "\033[0;38;5;214m",
|
29
38
|
}.freeze
|
30
39
|
|
31
40
|
# Groovy UTF-8 characters for everyone else...
|
@@ -35,6 +44,9 @@ module Inspec::Reporters
|
|
35
44
|
"skipped" => "↺",
|
36
45
|
"passed" => "✔",
|
37
46
|
"unknown" => "?",
|
47
|
+
"error" => "ERR",
|
48
|
+
"not_applicable" => "N/A",
|
49
|
+
"not_reviewed" => "N/R",
|
38
50
|
}.freeze
|
39
51
|
end
|
40
52
|
|
@@ -63,7 +75,11 @@ module Inspec::Reporters
|
|
63
75
|
end
|
64
76
|
|
65
77
|
output("")
|
66
|
-
|
78
|
+
if enhanced_outcomes
|
79
|
+
print_control_outcomes_summary
|
80
|
+
else
|
81
|
+
print_profile_summary
|
82
|
+
end
|
67
83
|
print_tests_summary
|
68
84
|
end
|
69
85
|
|
@@ -88,6 +104,7 @@ module Inspec::Reporters
|
|
88
104
|
def print_standard_control_results(profile)
|
89
105
|
standard_controls_from_profile(profile).each do |control_from_profile|
|
90
106
|
control = Control.new(control_from_profile)
|
107
|
+
control.enhanced_outcomes = enhanced_outcomes
|
91
108
|
next if control.results.nil?
|
92
109
|
|
93
110
|
output(format_control_header(control))
|
@@ -122,7 +139,7 @@ module Inspec::Reporters
|
|
122
139
|
end
|
123
140
|
|
124
141
|
def format_control_header(control)
|
125
|
-
impact = control.impact_string
|
142
|
+
impact = enhanced_outcomes ? control.impact_string_for_enhanced_outcomes : control.impact_string
|
126
143
|
format_message(
|
127
144
|
color: impact,
|
128
145
|
indicator: impact,
|
@@ -292,6 +309,68 @@ module Inspec::Reporters
|
|
292
309
|
}
|
293
310
|
end
|
294
311
|
|
312
|
+
def control_outcomes_summary
|
313
|
+
failed = 0
|
314
|
+
passed = 0
|
315
|
+
error = 0
|
316
|
+
not_reviewed = 0
|
317
|
+
not_applicable = 0
|
318
|
+
|
319
|
+
all_unique_controls.each do |control|
|
320
|
+
next if control[:status].empty?
|
321
|
+
|
322
|
+
if control[:status] == "failed"
|
323
|
+
failed += 1
|
324
|
+
elsif control[:status] == "error"
|
325
|
+
error += 1
|
326
|
+
elsif control[:status] == "not_reviewed"
|
327
|
+
not_reviewed += 1
|
328
|
+
elsif control[:status] == "not_applicable"
|
329
|
+
not_applicable += 1
|
330
|
+
else
|
331
|
+
passed += 1
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
total = failed + passed + error + not_reviewed + not_applicable
|
336
|
+
|
337
|
+
{
|
338
|
+
"total" => total,
|
339
|
+
"failed" => failed,
|
340
|
+
"passed" => passed,
|
341
|
+
"error" => error,
|
342
|
+
"not_reviewed" => not_reviewed,
|
343
|
+
"not_applicable" => not_applicable,
|
344
|
+
}
|
345
|
+
end
|
346
|
+
|
347
|
+
def print_control_outcomes_summary
|
348
|
+
summary = control_outcomes_summary
|
349
|
+
return unless summary["total"] > 0
|
350
|
+
|
351
|
+
success_str = summary["passed"] == 1 ? "1 successful control" : "#{summary["passed"]} successful controls"
|
352
|
+
failed_str = summary["failed"] == 1 ? "1 control failure" : "#{summary["failed"]} control failures"
|
353
|
+
error_str = summary["error"] == 1 ? "1 control has error" : "#{summary["error"]} controls have error"
|
354
|
+
not_rev_str = summary["not_reviewed"] == 1 ? "1 control not reviewed" : "#{summary["not_reviewed"]} controls not reviewed"
|
355
|
+
not_app_str = summary["not_applicable"] == 1 ? "1 control not applicable" : "#{summary["not_applicable"]} controls not applicable"
|
356
|
+
|
357
|
+
success_color = summary["passed"] > 0 ? "passed" : "no_color"
|
358
|
+
failed_color = summary["failed"] > 0 ? "failed" : "no_color"
|
359
|
+
error_color = summary["error"] > 0 ? "error" : "no_color"
|
360
|
+
not_rev_color = summary["not_reviewed"] > 0 ? "not_reviewed" : "no_color"
|
361
|
+
not_app_color = summary["not_applicable"] > 0 ? "not_applicable" : "no_color"
|
362
|
+
|
363
|
+
s = format(
|
364
|
+
"Profile Summary: %s, %s, %s, %s, %s",
|
365
|
+
format_with_color(success_color, success_str),
|
366
|
+
format_with_color(failed_color, failed_str),
|
367
|
+
format_with_color(not_rev_color, not_rev_str),
|
368
|
+
format_with_color(not_app_color, not_app_str),
|
369
|
+
format_with_color(error_color, error_str)
|
370
|
+
)
|
371
|
+
output(s) if summary["total"] > 0
|
372
|
+
end
|
373
|
+
|
295
374
|
def print_profile_summary
|
296
375
|
summary = profile_summary
|
297
376
|
return unless summary["total"] > 0
|
@@ -350,6 +429,7 @@ module Inspec::Reporters
|
|
350
429
|
|
351
430
|
class Control
|
352
431
|
attr_reader :data
|
432
|
+
attr_accessor :enhanced_outcomes
|
353
433
|
|
354
434
|
def initialize(control_hash)
|
355
435
|
@data = control_hash
|
@@ -379,6 +459,10 @@ module Inspec::Reporters
|
|
379
459
|
id.start_with?("(generated from ")
|
380
460
|
end
|
381
461
|
|
462
|
+
def status
|
463
|
+
data[:status]
|
464
|
+
end
|
465
|
+
|
382
466
|
def title_for_report
|
383
467
|
# if this is an anonymous control, just grab the resource title from any result entry
|
384
468
|
return results.first[:resource_title] if anonymous?
|
@@ -392,10 +476,17 @@ module Inspec::Reporters
|
|
392
476
|
# append a failure summary if appropriate.
|
393
477
|
title_for_report += " (#{failure_count} failed)" if failure_count > 0
|
394
478
|
title_for_report += " (#{skipped_count} skipped)" if skipped_count > 0
|
395
|
-
|
396
479
|
title_for_report
|
397
480
|
end
|
398
481
|
|
482
|
+
def impact_string_for_enhanced_outcomes
|
483
|
+
if impact.nil?
|
484
|
+
"unknown"
|
485
|
+
else
|
486
|
+
status
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
399
490
|
def impact_string
|
400
491
|
if anonymous?
|
401
492
|
nil
|
@@ -114,7 +114,7 @@ module Inspec::Reporters
|
|
114
114
|
|
115
115
|
def profile_controls(profile)
|
116
116
|
(profile[:controls] || []).map { |c|
|
117
|
-
{
|
117
|
+
control_hash = {
|
118
118
|
id: c[:id],
|
119
119
|
title: c[:title],
|
120
120
|
desc: c.dig(:descriptions, :default),
|
@@ -130,6 +130,8 @@ module Inspec::Reporters
|
|
130
130
|
waiver_data: c[:waiver_data] || {},
|
131
131
|
results: profile_results(c),
|
132
132
|
}
|
133
|
+
control_hash.merge!({ status: c[:status] }) if enhanced_outcomes
|
134
|
+
control_hash
|
133
135
|
}
|
134
136
|
end
|
135
137
|
|
@@ -3,7 +3,9 @@ require "yaml"
|
|
3
3
|
module Inspec::Reporters
|
4
4
|
class Yaml < Base
|
5
5
|
def render
|
6
|
-
|
6
|
+
json_reporter_obj = Inspec::Reporters::Json.new({ run_data: run_data })
|
7
|
+
json_reporter_obj.enhanced_outcomes = enhanced_outcomes
|
8
|
+
output(json_reporter_obj.report.to_yaml, false)
|
7
9
|
end
|
8
10
|
|
9
11
|
def report
|
data/lib/inspec/reporters.rb
CHANGED
@@ -7,7 +7,7 @@ require "inspec/reporters/yaml"
|
|
7
7
|
|
8
8
|
module Inspec::Reporters
|
9
9
|
# rubocop:disable Metrics/CyclomaticComplexity
|
10
|
-
def self.render(reporter, run_data)
|
10
|
+
def self.render(reporter, run_data, enhanced_outcomes = false)
|
11
11
|
name, config = reporter.dup
|
12
12
|
config[:run_data] = run_data
|
13
13
|
case name
|
@@ -29,6 +29,7 @@ module Inspec::Reporters
|
|
29
29
|
activator.activate!
|
30
30
|
reporter = activator.implementation_class.new(config)
|
31
31
|
end
|
32
|
+
reporter.enhanced_outcomes = enhanced_outcomes
|
32
33
|
|
33
34
|
# optional send_report method on reporter
|
34
35
|
return reporter.send_report if defined?(reporter.send_report)
|
@@ -66,7 +66,7 @@ module Inspec::Resources
|
|
66
66
|
def user_permissions
|
67
67
|
return {} unless exist?
|
68
68
|
|
69
|
-
return
|
69
|
+
return skip_resource "`user_permissions` is not supported on your OS yet." unless inspec.os.windows?
|
70
70
|
|
71
71
|
@perms_provider.user_permissions(file)
|
72
72
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
require "inspec/resources/command"
|
6
6
|
require "faraday" unless defined?(Faraday)
|
7
|
-
require "
|
7
|
+
require "faraday/follow_redirects"
|
8
8
|
require "hashie"
|
9
9
|
|
10
10
|
module Inspec::Resources
|
@@ -153,7 +153,7 @@ module Inspec::Resources
|
|
153
153
|
|
154
154
|
conn = Faraday.new(url: url, headers: request_headers, params: params, ssl: { verify: ssl_verify? }) do |builder|
|
155
155
|
builder.request :url_encoded
|
156
|
-
builder.use
|
156
|
+
builder.use Faraday::FollowRedirects::Middleware, limit: max_redirects unless max_redirects.nil?
|
157
157
|
builder.adapter Faraday.default_adapter
|
158
158
|
end
|
159
159
|
|
@@ -304,11 +304,11 @@ module Inspec::Resources
|
|
304
304
|
# Insecure not supported simply https://stackoverflow.com/questions/11696944/powershell-v3-invoke-webrequest-https-error
|
305
305
|
cmd << "-MaximumRedirection #{max_redirects}" unless max_redirects.nil?
|
306
306
|
request_headers["Authorization"] = """ '\"Basic ' + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(\"#{username}:#{password}\")) +'\"' """ unless username.nil? || password.nil?
|
307
|
-
|
307
|
+
request_header_array = []
|
308
308
|
request_headers.each do |k, v|
|
309
|
-
|
309
|
+
request_header_array << " '#{k}' = '#{v}'"
|
310
310
|
end
|
311
|
-
cmd << "-Headers @{#{
|
311
|
+
cmd << "-Headers @{#{request_header_array.join(";")}}" unless request_header_array.empty?
|
312
312
|
if params.nil?
|
313
313
|
cmd << "'#{url}'"
|
314
314
|
else
|
data/lib/inspec/resources/lxc.rb
CHANGED
@@ -9,14 +9,26 @@ module Inspec::Resources
|
|
9
9
|
describe lxc("ubuntu-container") do
|
10
10
|
it { should exist }
|
11
11
|
it { should be_running }
|
12
|
+
its("name") { should eq "ubuntu-container" }
|
13
|
+
its("status") { should cmp "Running" }
|
14
|
+
its("type") { should eq "container" }
|
15
|
+
its("architecture") { should eq "x86_64" }
|
16
|
+
its("pid") { should eq 1378 }
|
17
|
+
its("created_at") { should eq "2022/08/16 12:07 UTC" }
|
18
|
+
its("last_used_at") { should eq "2022/08/17 05:06 UTC" }
|
19
|
+
its("resources") { should include "Disk usage" }
|
12
20
|
end
|
13
21
|
EXAMPLE
|
14
22
|
|
23
|
+
attr_reader :container_info, :container_name
|
24
|
+
|
15
25
|
# Resource initialization.
|
16
26
|
def initialize(container_name)
|
17
27
|
@container_name = container_name
|
18
28
|
|
19
29
|
raise Inspec::Exceptions::ResourceSkipped, "The `lxc` resource is not supported on your OS yet." unless inspec.os.linux?
|
30
|
+
|
31
|
+
@container_info = populate_container_info
|
20
32
|
end
|
21
33
|
|
22
34
|
def resource_id
|
@@ -28,17 +40,60 @@ module Inspec::Resources
|
|
28
40
|
end
|
29
41
|
|
30
42
|
def exists?
|
31
|
-
|
43
|
+
!@container_info.empty?
|
32
44
|
end
|
33
45
|
|
34
46
|
def running?
|
35
|
-
container_info
|
36
|
-
|
47
|
+
@container_info.key?("Status") && @container_info["Status"].casecmp("Running") == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
def name
|
51
|
+
@container_info["Name"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def status
|
55
|
+
@container_info["Status"]
|
56
|
+
end
|
57
|
+
|
58
|
+
def type
|
59
|
+
@container_info["Type"]
|
60
|
+
end
|
61
|
+
|
62
|
+
def architecture
|
63
|
+
@container_info["Architecture"]
|
64
|
+
end
|
65
|
+
|
66
|
+
def pid
|
67
|
+
@container_info["PID"]
|
68
|
+
end
|
69
|
+
|
70
|
+
def created_at
|
71
|
+
@container_info["Created"]
|
72
|
+
end
|
73
|
+
|
74
|
+
def last_used_at
|
75
|
+
@container_info["Last Used"]
|
76
|
+
end
|
77
|
+
|
78
|
+
def resources
|
79
|
+
@container_info["Resources"]
|
37
80
|
end
|
38
81
|
|
39
82
|
private
|
40
83
|
|
41
|
-
|
84
|
+
def populate_container_info
|
85
|
+
lxc_util = find_lxc_or_error
|
86
|
+
lxc_info_cmd = inspec.command("#{lxc_util} info #{@container_name}")
|
87
|
+
|
88
|
+
if lxc_info_cmd.exit_status.to_i == 0
|
89
|
+
parse_command_output(lxc_info_cmd.stdout)
|
90
|
+
elsif lxc_info_cmd.stderr =~ /Error: Instance not found/
|
91
|
+
{}
|
92
|
+
else
|
93
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to retrieve information for #{container_name}.\n#{lxc_info_cmd.stderr}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
42
97
|
def find_lxc_or_error
|
43
98
|
%w{/usr/sbin/lxc /sbin/lxc lxc}.each do |cmd|
|
44
99
|
return cmd if inspec.command(cmd).exist?
|
@@ -47,11 +102,12 @@ module Inspec::Resources
|
|
47
102
|
raise Inspec::Exceptions::ResourceFailed, "Could not find `lxc`"
|
48
103
|
end
|
49
104
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
105
|
+
def parse_command_output(output)
|
106
|
+
require "yaml" unless defined?(YAML)
|
107
|
+
YAML.load(output)
|
108
|
+
rescue Psych::SyntaxError => e
|
109
|
+
warn "Could not parse the command output.\n#{e.message}"
|
110
|
+
{}
|
55
111
|
end
|
56
112
|
end
|
57
113
|
end
|
@@ -84,6 +84,11 @@ module Inspec::Resources
|
|
84
84
|
options[:ssl_cert] = @ssl_cert unless @ssl_cert.nil?
|
85
85
|
options[:ssl_ca_cert] = @ssl_ca_cert unless @ssl_ca_cert.nil?
|
86
86
|
|
87
|
+
# Setting the logger level to INFO as mongo gem version 2.13.2 is using DEBUG as the log level Ref: https://github.com/mongodb/mongo-ruby-driver/blob/v2.13.2/lib/mongo/logger.rb#L79
|
88
|
+
# Latest version of the mongo gem don't have this issue as it set to INFO level Ref: https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/logger.rb#L82
|
89
|
+
# We pinned the version to 2.13.2 as the latest version of the mongo gem has broken symlink https://jira.mongodb.org/browse/RUBY-2546 which causes omnibus build failure.
|
90
|
+
# Once we get the latest version working we can remove logger level set here.
|
91
|
+
Mongo::Logger.logger.level = Logger::INFO
|
87
92
|
@client = Mongo::Client.new([ "#{host}:#{port}" ], options)
|
88
93
|
|
89
94
|
rescue => e
|