inspec-core 5.24.7 → 6.6.0
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/Chef-EULA +9 -0
- data/Gemfile +25 -36
- data/etc/features.sig +6 -0
- data/etc/features.yaml +94 -0
- data/inspec-core.gemspec +21 -19
- data/lib/inspec/archive/tar.rb +0 -1
- data/lib/inspec/backend.rb +2 -0
- data/lib/inspec/base_cli.rb +80 -14
- data/lib/inspec/cached_fetcher.rb +24 -3
- data/lib/inspec/cli.rb +292 -235
- data/lib/inspec/config.rb +24 -11
- data/lib/inspec/dependencies/cache.rb +33 -0
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dsl.rb +1 -1
- data/lib/inspec/enhanced_outcomes.rb +1 -0
- data/lib/inspec/errors.rb +5 -0
- data/lib/inspec/exceptions.rb +1 -0
- data/lib/inspec/feature/config.rb +75 -0
- data/lib/inspec/feature/runner.rb +26 -0
- data/lib/inspec/feature.rb +34 -0
- data/lib/inspec/fetcher/git.rb +6 -21
- data/lib/inspec/fetcher/url.rb +7 -29
- data/lib/inspec/file_provider.rb +0 -1
- data/lib/inspec/globals.rb +6 -0
- data/lib/inspec/input_registry.rb +1 -5
- data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +7 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +30 -2
- data/lib/inspec/profile.rb +49 -13
- data/lib/inspec/reporters/cli.rb +1 -1
- data/lib/inspec/reporters.rb +67 -54
- data/lib/inspec/resources/audit_policy.rb +2 -8
- data/lib/inspec/resources/groups.rb +0 -52
- data/lib/inspec/resources/mssql_session.rb +1 -13
- data/lib/inspec/resources/nftables.rb +1 -14
- data/lib/inspec/resources/oracledb_session.rb +11 -72
- data/lib/inspec/resources/postgres_session.rb +5 -9
- data/lib/inspec/resources/sybase_session.rb +2 -11
- data/lib/inspec/resources/virtualization.rb +1 -1
- data/lib/inspec/rule.rb +9 -14
- data/lib/inspec/run_data.rb +7 -5
- data/lib/inspec/runner.rb +35 -6
- data/lib/inspec/runner_rspec.rb +12 -9
- data/lib/inspec/secrets/yaml.rb +5 -1
- data/lib/inspec/shell.rb +10 -0
- data/lib/inspec/ui.rb +4 -0
- data/lib/inspec/utils/licensing_config.rb +9 -0
- data/lib/inspec/utils/profile_ast_helpers.rb +12 -39
- data/lib/inspec/utils/waivers/csv_file_reader.rb +1 -1
- data/lib/inspec/utils/waivers/excel_file_reader.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +18 -35
- data/lib/inspec.rb +2 -1
- data/lib/matchers/matchers.rb +3 -3
- data/lib/plugins/inspec-compliance/README.md +1 -11
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +189 -170
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +10 -3
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +23 -21
- data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +15 -13
- data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +15 -13
- data/lib/plugins/inspec-license/README.md +16 -0
- data/lib/plugins/inspec-license/inspec-license.gemspec +6 -0
- data/lib/plugins/inspec-license/lib/inspec-license/cli.rb +26 -0
- data/lib/plugins/inspec-license/lib/inspec-license.rb +14 -0
- data/lib/plugins/inspec-parallel/README.md +27 -0
- data/lib/plugins/inspec-parallel/inspec-parallel.gemspec +6 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/child_status_reporter.rb +61 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/cli.rb +39 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/command.rb +219 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/runner.rb +265 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/base.rb +24 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/silent.rb +7 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/status.rb +124 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/text.rb +23 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/validator.rb +170 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel.rb +18 -0
- data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +10 -11
- data/lib/plugins/inspec-sign/lib/inspec-sign/cli.rb +11 -4
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +6 -13
- data/lib/source_readers/inspec.rb +1 -1
- metadata +55 -47
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require "highline"
|
|
2
|
+
|
|
3
|
+
module InspecPlugins::Parallelism
|
|
4
|
+
class SuperReporter
|
|
5
|
+
class Status < InspecPlugins::Parallelism::SuperReporter::Base
|
|
6
|
+
|
|
7
|
+
attr_reader :status_by_pid, :slots
|
|
8
|
+
|
|
9
|
+
def initialize(job_count, invocations)
|
|
10
|
+
@status_by_pid = {}
|
|
11
|
+
@slots = Array.new(job_count)
|
|
12
|
+
paint_header(job_count, invocations)
|
|
13
|
+
paint
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# --------
|
|
17
|
+
# SuperReporter API
|
|
18
|
+
# --------
|
|
19
|
+
def child_spawned(pid, invocation)
|
|
20
|
+
new_child("spawned", pid, invocation)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def child_forked(pid, invocation)
|
|
24
|
+
new_child("forked", pid, invocation)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def child_exited(pid)
|
|
28
|
+
slots[status_by_pid[pid][:slot]] = "exited"
|
|
29
|
+
|
|
30
|
+
status_by_pid[pid][:pct] = 100.0
|
|
31
|
+
status_by_pid[pid][:slot] = nil
|
|
32
|
+
status_by_pid[pid][:exit] = $?
|
|
33
|
+
|
|
34
|
+
# TODO: consider holding slot in 100 status for UI grace
|
|
35
|
+
|
|
36
|
+
paint
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def child_status_update_line(pid, update_line)
|
|
40
|
+
control_serial, status, control_count, title = update_line.split("/")
|
|
41
|
+
percent = 100.0 * control_serial.to_i / control_count.to_i.to_f
|
|
42
|
+
|
|
43
|
+
status_by_pid[pid][:pct] = percent
|
|
44
|
+
status_by_pid[pid][:last_control] = title
|
|
45
|
+
status_by_pid[pid][:last_status] = status
|
|
46
|
+
|
|
47
|
+
paint
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# --------
|
|
51
|
+
# Utilities
|
|
52
|
+
# --------
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def new_child(how, pid, invocation)
|
|
56
|
+
# Update status by PID with new info
|
|
57
|
+
status_by_pid[pid] = {
|
|
58
|
+
pct: 0.0,
|
|
59
|
+
inv: invocation,
|
|
60
|
+
how: how,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Assign first empty slot
|
|
64
|
+
slots.each_index do |idx|
|
|
65
|
+
next unless slots[idx].nil? || slots[idx] == "exited"
|
|
66
|
+
|
|
67
|
+
slots[idx] = pid
|
|
68
|
+
status_by_pid[pid][:slot] = idx
|
|
69
|
+
break
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# TODO: consider printing log message
|
|
73
|
+
paint
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def terminal_width
|
|
77
|
+
return @terminal_width if @terminal_width
|
|
78
|
+
|
|
79
|
+
@highline ||= HighLine.new
|
|
80
|
+
width = @highline.output_cols.to_i
|
|
81
|
+
width = 80 if width < 1
|
|
82
|
+
@terminal_width = width
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def paint
|
|
86
|
+
# Determine the width of a slot
|
|
87
|
+
slot_width = terminal_width / slots.length
|
|
88
|
+
line = ""
|
|
89
|
+
# Loop over slots
|
|
90
|
+
slots.each_index do |idx|
|
|
91
|
+
if slots[idx].nil?
|
|
92
|
+
# line += "idle".center(slot_width)
|
|
93
|
+
# Need to improve UI
|
|
94
|
+
elsif slots[idx] == "exited"
|
|
95
|
+
line += "Done".center(slot_width)
|
|
96
|
+
else
|
|
97
|
+
pid = slots[idx]
|
|
98
|
+
with_pid = format("%s: %0.1f%%", pid, status_by_pid[pid][:pct])
|
|
99
|
+
if with_pid.length <= slot_width - 2
|
|
100
|
+
line += with_pid.center(slot_width)
|
|
101
|
+
else
|
|
102
|
+
line += format("%0.1f%%", status_by_pid[pid][:pct]).center(slot_width)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
print "\r" + (" " * terminal_width) + "\r"
|
|
108
|
+
print line
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def paint_header(jobs, invocations)
|
|
112
|
+
puts "InSpec Parallel".center(terminal_width)
|
|
113
|
+
puts "Running #{invocations.length} invocations in #{jobs} slots".center(terminal_width)
|
|
114
|
+
puts "-" * terminal_width
|
|
115
|
+
slot_width = terminal_width / slots.length
|
|
116
|
+
slots.each_index do |idx|
|
|
117
|
+
print "Slot #{idx + 1}".center(slot_width)
|
|
118
|
+
end
|
|
119
|
+
puts
|
|
120
|
+
puts "-" * terminal_width
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module InspecPlugins::Parallelism
|
|
2
|
+
class SuperReporter
|
|
3
|
+
class Text < InspecPlugins::Parallelism::SuperReporter::Base
|
|
4
|
+
def child_spawned(pid, _inv)
|
|
5
|
+
puts "[#{Time.now.iso8601}] Spawned child PID #{pid}"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def child_forked(pid, _inv)
|
|
9
|
+
puts "[#{Time.now.iso8601}] Forked child PID #{pid}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def child_exited(pid)
|
|
13
|
+
puts "[#{Time.now.iso8601}] Exited child PID #{pid} status #{$?}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def child_status_update_line(pid, update_line)
|
|
17
|
+
control_serial, _status, control_count, _title = update_line.split("/")
|
|
18
|
+
percent = 100.0 * control_serial.to_i / control_count.to_i.to_f
|
|
19
|
+
puts "[#{Time.now.iso8601}] #{pid} " + format("%.1f%%", percent)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
require "inspec/cli"
|
|
2
|
+
module InspecPlugins
|
|
3
|
+
module Parallelism
|
|
4
|
+
class Validator
|
|
5
|
+
|
|
6
|
+
# TODO: make this list dynamic so plugins can self-declare
|
|
7
|
+
PARALLEL_SAFE_REPORTERS = [
|
|
8
|
+
"automate", # Performs HTTP transactions, silent on STDOUT
|
|
9
|
+
"child-status", # Writes dedicated protocol to STDOUT, expected by parent
|
|
10
|
+
].freeze
|
|
11
|
+
|
|
12
|
+
attr_accessor :invocations, :sub_cmd, :thor_options_for_sub_cmd, :aliases_mapping, :cli_options, :config_content, :stdin_config
|
|
13
|
+
|
|
14
|
+
def initialize(invocations, cli_options, sub_cmd = "exec")
|
|
15
|
+
@invocations = invocations
|
|
16
|
+
@sub_cmd = sub_cmd
|
|
17
|
+
@thor_options_for_sub_cmd = Inspec::InspecCLI.commands[sub_cmd].options
|
|
18
|
+
@aliases_mapping = create_aliases_mapping
|
|
19
|
+
@cli_options = cli_options
|
|
20
|
+
@config_content = nil
|
|
21
|
+
@stdin_config = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate
|
|
25
|
+
invocations.each do |invocation_data|
|
|
26
|
+
invocation_data[:validation_errors] = []
|
|
27
|
+
|
|
28
|
+
convert_cli_to_thor_options(invocation_data)
|
|
29
|
+
check_for_spurious_options(invocation_data)
|
|
30
|
+
check_for_required_fields(invocation_data)
|
|
31
|
+
check_for_reporter_options(invocation_data)
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def validate_log_path
|
|
37
|
+
return [] unless cli_options["log_path"]
|
|
38
|
+
|
|
39
|
+
if File.directory?(cli_options["log_path"])
|
|
40
|
+
[]
|
|
41
|
+
else
|
|
42
|
+
[true, "Log path #{cli_options["log_path"]} is not accessible"]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def create_aliases_mapping
|
|
49
|
+
alias_mapping = {}
|
|
50
|
+
thor_options_for_sub_cmd.each do |_, sub_cmd_option|
|
|
51
|
+
aliases = sub_cmd_option.aliases
|
|
52
|
+
unless aliases.empty?
|
|
53
|
+
alias_mapping[aliases[0]] = sub_cmd_option.name
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
alias_mapping
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def check_for_spurious_options(invocation_data)
|
|
60
|
+
# LIMITATION: Assume the first arg is the profile name, and there is exactly one of them.
|
|
61
|
+
invalid_options = invocation_data[:thor_args][1..-1]
|
|
62
|
+
invocation_data[:validation_errors].push "No such option: #{invalid_options}" unless invalid_options.empty?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def check_for_required_fields(invocation_data)
|
|
66
|
+
required_fields = thor_options_for_sub_cmd.collect { |_, thor_option| thor_option.name if thor_option.required }.compact
|
|
67
|
+
option_keys = invocation_data[:thor_opts].keys
|
|
68
|
+
invocation_data[:thor_opts].keys.map { |key| option_keys.push(aliases_mapping[key.to_sym]) if aliases_mapping[key.to_sym] }
|
|
69
|
+
if !required_fields.empty? && (option_keys & required_fields).empty?
|
|
70
|
+
invocation_data[:validation_errors].push "No value provided for required options: #{required_fields}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def check_for_reporter_options(invocation_data)
|
|
75
|
+
# if no reporter option, that's an error
|
|
76
|
+
unless invocation_data[:thor_opts].include?("reporter")
|
|
77
|
+
# Check for config reporter validation only if --reporter option is missing from options file
|
|
78
|
+
return if check_reporter_options_in_config(invocation_data)
|
|
79
|
+
|
|
80
|
+
invocation_data[:validation_errors] << "A --reporter option must be specified for each invocation in the options file"
|
|
81
|
+
return
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
have_child_status_reporter = false
|
|
85
|
+
|
|
86
|
+
# Reporter option is formatted as an array
|
|
87
|
+
invocation_data[:thor_opts]["reporter"].each do |reporter_spec|
|
|
88
|
+
reporter_name, file_output = reporter_spec.split(":")
|
|
89
|
+
|
|
90
|
+
have_child_status_reporter = true if reporter_name == "child-status"
|
|
91
|
+
|
|
92
|
+
# if there is a reporter option, each entry must either write to a file or
|
|
93
|
+
# else be the special child-status reporter or the automate reporter
|
|
94
|
+
next if PARALLEL_SAFE_REPORTERS.include?(reporter_name)
|
|
95
|
+
|
|
96
|
+
unless file_output
|
|
97
|
+
invocation_data[:validation_errors] << "The #{reporter_name} reporter requires being directed to a file, like #{reporter_name}:filename.out"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# if there is no child-status reporter, add one to the raw value and the parsed array
|
|
102
|
+
unless have_child_status_reporter
|
|
103
|
+
# Eww
|
|
104
|
+
invocation_data[:thor_opts]["reporter"] << "child-status"
|
|
105
|
+
invocation_data[:value].gsub!("--reporter ", "--reporter child-status ")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def check_reporter_options_in_config(invocation_data)
|
|
110
|
+
config_opts = invocation_data[:thor_opts]["config"] || invocation_data[:thor_opts]["json_config"]
|
|
111
|
+
cfg_io = check_for_piped_config_from_stdin(config_opts)
|
|
112
|
+
|
|
113
|
+
if cfg_io == STDIN
|
|
114
|
+
# Scenario of using config from STDIN
|
|
115
|
+
@config_content ||= cfg_io.read
|
|
116
|
+
else
|
|
117
|
+
if config_opts.nil?
|
|
118
|
+
# Scenario of using default config.json file when path not provided
|
|
119
|
+
default_path = File.join(Inspec.config_dir, "config.json")
|
|
120
|
+
config_opts = default_path
|
|
121
|
+
return unless File.exist?(config_opts)
|
|
122
|
+
elsif !File.exist?(config_opts)
|
|
123
|
+
invocation_data[:validation_errors] << "Could not read configuration file at #{config_opts}"
|
|
124
|
+
return
|
|
125
|
+
end
|
|
126
|
+
@config_content = File.open(config_opts).read
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
reporter_config = JSON.parse(config_content)["reporter"] unless config_content.nil? || config_content.empty?
|
|
130
|
+
unless reporter_config
|
|
131
|
+
invocation_data[:validation_errors] << "Config should have reporter option specified for each invocation which is not using --reporter option in options file"
|
|
132
|
+
end
|
|
133
|
+
@config_content
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def check_for_piped_config_from_stdin(config_opts)
|
|
137
|
+
return nil unless config_opts
|
|
138
|
+
return nil unless config_opts == "-"
|
|
139
|
+
|
|
140
|
+
@stdin_config ||= STDIN
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
## Utility functions
|
|
144
|
+
|
|
145
|
+
# Parse the invocation string using Thor into Thor options
|
|
146
|
+
# This approach was reverse engineered from studying
|
|
147
|
+
# https://github.com/rails/thor/blob/ab3b5be455791f4efb79f0efb4f88cc6b59c8ccf/lib/thor/base.rb#L53
|
|
148
|
+
|
|
149
|
+
def convert_cli_to_thor_options(invocation_data)
|
|
150
|
+
invocation_words = invocation_data[:value].split(" ")
|
|
151
|
+
|
|
152
|
+
# LIMITATION: this approach is limited to having exactly one profile in the invocation
|
|
153
|
+
args = [invocation_words.shift] # That is, the profile path
|
|
154
|
+
|
|
155
|
+
# Here we're piggybacking on on a hook used by the start() method, and provides the
|
|
156
|
+
# specifics for the subcommand
|
|
157
|
+
config = { command_options: thor_options_for_sub_cmd }
|
|
158
|
+
|
|
159
|
+
# This performs the parse
|
|
160
|
+
thor = Inspec::InspecCLI.new(args, invocation_words, config)
|
|
161
|
+
|
|
162
|
+
# A hash (with indifferent access) of option names to option config data
|
|
163
|
+
invocation_data[:thor_opts] = thor.options
|
|
164
|
+
|
|
165
|
+
# A list of everything else it could not parse, including the profile
|
|
166
|
+
invocation_data[:thor_args] = thor.args
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module InspecPlugins
|
|
2
|
+
module Parallelism
|
|
3
|
+
class Plugin < ::Inspec.plugin(2)
|
|
4
|
+
plugin_name :"inspec-parallel"
|
|
5
|
+
|
|
6
|
+
cli_command :parallel do
|
|
7
|
+
require_relative "inspec-parallel/cli"
|
|
8
|
+
InspecPlugins::Parallelism::CLI
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
streaming_reporter :"child-status" do
|
|
12
|
+
require_relative "inspec-parallel/child_status_reporter"
|
|
13
|
+
InspecPlugins::Parallelism::StreamingReporter
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -36,15 +36,11 @@ module InspecPlugins
|
|
|
36
36
|
FileUtils.mkdir_p(path)
|
|
37
37
|
|
|
38
38
|
puts "Generating signing key in #{path}/#{options["keyname"]}.pem.key"
|
|
39
|
-
#
|
|
40
|
-
# https://github.com/inspec/inspec/security/code-scanning/2
|
|
41
|
-
# The following line was flagged by GitHub code scanning as a security vulnerability.
|
|
42
|
-
# Update the code to eliminate the vulnerability.
|
|
43
|
-
File.open("#{path}/#{options["keyname"]}.pem.key", "w") do |io|
|
|
39
|
+
open "#{path}/#{options["keyname"]}.pem.key", "w" do |io|
|
|
44
40
|
io.write key.to_pem
|
|
45
41
|
end
|
|
46
42
|
puts "Generating validation key in #{path}/#{options["keyname"]}.pem.pub"
|
|
47
|
-
|
|
43
|
+
open "#{path}/#{options["keyname"]}.pem.pub", "w" do |io|
|
|
48
44
|
io.write key.public_key.to_pem
|
|
49
45
|
end
|
|
50
46
|
end
|
|
@@ -71,8 +67,7 @@ module InspecPlugins
|
|
|
71
67
|
# Generating tar.gz file using archive method of Inspec Cli
|
|
72
68
|
Inspec::InspecCLI.new.archive(profile_path, "error")
|
|
73
69
|
tarfile = "#{filename}.tar.gz"
|
|
74
|
-
|
|
75
|
-
tar_content = File.binread(tarfile)
|
|
70
|
+
tar_content = IO.binread(tarfile)
|
|
76
71
|
FileUtils.rm(tarfile)
|
|
77
72
|
|
|
78
73
|
# Generate the signature
|
|
@@ -97,12 +92,16 @@ module InspecPlugins
|
|
|
97
92
|
Inspec::UI.new.exit(:usage_error)
|
|
98
93
|
end
|
|
99
94
|
|
|
100
|
-
def self.profile_verify(signed_profile_path)
|
|
95
|
+
def self.profile_verify(signed_profile_path, silent = false)
|
|
101
96
|
file_to_verify = signed_profile_path
|
|
102
|
-
puts "Verifying #{file_to_verify}"
|
|
97
|
+
puts "Verifying #{file_to_verify}" unless silent
|
|
103
98
|
|
|
104
99
|
iaf_file = Inspec::IafFile.new(file_to_verify)
|
|
105
100
|
if iaf_file.valid?
|
|
101
|
+
# Signed profile verification is called from runner and not from CLI
|
|
102
|
+
# Do not exit and do not print logs
|
|
103
|
+
return if silent
|
|
104
|
+
|
|
106
105
|
puts "Detected format version '#{iaf_file.version}'"
|
|
107
106
|
puts "Attempting to verify using key '#{iaf_file.key_name}'"
|
|
108
107
|
puts "Profile is valid."
|
|
@@ -157,7 +156,7 @@ module InspecPlugins
|
|
|
157
156
|
ui.exit(:usage_error)
|
|
158
157
|
end
|
|
159
158
|
|
|
160
|
-
lines =
|
|
159
|
+
lines = IO.readlines(p)
|
|
161
160
|
lines << "\nprofile_content_id: #{profile_content_id}\n"
|
|
162
161
|
|
|
163
162
|
File.open("#{p}", "w" ) do |f|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative "base"
|
|
2
2
|
require "inspec/dist"
|
|
3
|
+
require "inspec/feature"
|
|
3
4
|
|
|
4
5
|
#
|
|
5
6
|
# Notes:
|
|
@@ -85,8 +86,10 @@ module InspecPlugins
|
|
|
85
86
|
option :keydir, type: :string, default: "./",
|
|
86
87
|
desc: "Directory to search for keys"
|
|
87
88
|
def generate_keys
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
Inspec.with_feature("inspec-cli-sign-generate-keys") {
|
|
90
|
+
puts "Generating keys"
|
|
91
|
+
InspecPlugins::Sign::Base.keygen(options)
|
|
92
|
+
}
|
|
90
93
|
end
|
|
91
94
|
|
|
92
95
|
desc "profile PATH", "sign the profile in PATH and generate .iaf artifact."
|
|
@@ -95,12 +98,16 @@ module InspecPlugins
|
|
|
95
98
|
option :profile_content_id, type: :string,
|
|
96
99
|
desc: "UUID of the profile. This will write the profile_content_id in the metadata file if it does not already exist in the metadata file."
|
|
97
100
|
def profile(profile_path)
|
|
98
|
-
|
|
101
|
+
Inspec.with_feature("inspec-cli-sign-profile") {
|
|
102
|
+
InspecPlugins::Sign::Base.profile_sign(profile_path, options)
|
|
103
|
+
}
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
desc "verify PATH", "Verify a signed profile .iaf artifact at given path."
|
|
102
107
|
def verify(signed_profile_path)
|
|
103
|
-
|
|
108
|
+
Inspec.with_feature("inspec-cli-sign-verify") {
|
|
109
|
+
InspecPlugins::Sign::Base.profile_verify(signed_profile_path)
|
|
110
|
+
}
|
|
104
111
|
end
|
|
105
112
|
end
|
|
106
113
|
end
|
|
@@ -91,23 +91,20 @@ module InspecPlugins::StreamingReporterProgressBar
|
|
|
91
91
|
|
|
92
92
|
set_status_mapping(control_id, status)
|
|
93
93
|
collect_notifications(notification, control_id, status)
|
|
94
|
-
|
|
95
|
-
if control_ended
|
|
96
|
-
control_outcome = add_enhanced_outcomes(control_id) if enhanced_outcomes
|
|
97
|
-
show_progress(control_id, title, full_description, control_outcome)
|
|
98
|
-
end
|
|
94
|
+
show_progress(control_id, title, full_description) if control_ended?(notification, control_id)
|
|
99
95
|
end
|
|
100
96
|
|
|
101
|
-
def show_progress(control_id, title, full_description
|
|
97
|
+
def show_progress(control_id, title, full_description)
|
|
102
98
|
@bar ||= ProgressBar.new(controls_count, :bar, :counter, :percentage)
|
|
103
99
|
sleep 0.1
|
|
104
100
|
@bar.increment!
|
|
105
|
-
@bar.puts format_it(control_id, title, full_description
|
|
101
|
+
@bar.puts format_it(control_id, title, full_description)
|
|
106
102
|
rescue StandardError => e
|
|
107
103
|
raise "Exception in Progress Bar streaming reporter: #{e}"
|
|
108
104
|
end
|
|
109
105
|
|
|
110
|
-
def format_it(control_id, title, full_description
|
|
106
|
+
def format_it(control_id, title, full_description)
|
|
107
|
+
control_outcome = control_outcome(control_id)
|
|
111
108
|
if control_outcome
|
|
112
109
|
control_status = control_outcome
|
|
113
110
|
else
|
|
@@ -121,11 +118,7 @@ module InspecPlugins::StreamingReporterProgressBar
|
|
|
121
118
|
end
|
|
122
119
|
end
|
|
123
120
|
indicator = INDICATORS[control_status]
|
|
124
|
-
message_to_format =
|
|
125
|
-
message_to_format += "#{indicator} "
|
|
126
|
-
message_to_format += "#{control_id.to_s.strip.dup.force_encoding(Encoding::UTF_8)} "
|
|
127
|
-
message_to_format += "#{title.gsub(/\n*\s+/, " ").to_s.force_encoding(Encoding::UTF_8)} " if title
|
|
128
|
-
message_to_format += "#{full_description.gsub(/\n*\s+/, " ").to_s.force_encoding(Encoding::UTF_8)} " unless title
|
|
121
|
+
message_to_format = format_message(indicator, control_id, title, full_description)
|
|
129
122
|
format_with_color(control_status, message_to_format)
|
|
130
123
|
rescue Exception => e
|
|
131
124
|
raise "Exception in show_progress: #{e}"
|