inspec 2.2.61 → 2.2.64
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/CHANGELOG.md +22 -15
- data/README.md +0 -1
- data/docs/dev/plugins.md +321 -0
- data/docs/profiles.md +20 -18
- data/lib/bundles/inspec-artifact/cli.rb +1 -0
- data/lib/bundles/inspec-compliance/cli.rb +1 -0
- data/lib/bundles/inspec-habitat/cli.rb +1 -0
- data/lib/bundles/inspec-init/cli.rb +1 -0
- data/lib/bundles/inspec-supermarket/cli.rb +1 -0
- data/lib/inspec.rb +4 -2
- data/lib/inspec/base_cli.rb +1 -0
- data/lib/inspec/cli.rb +35 -16
- data/lib/inspec/control_eval_context.rb +7 -6
- data/lib/inspec/dependencies/requirement.rb +0 -1
- data/lib/inspec/fetcher.rb +1 -2
- data/lib/inspec/library_eval_context.rb +1 -1
- data/lib/inspec/plugin/v1.rb +2 -0
- data/lib/inspec/{plugins → plugin/v1/plugin_types}/cli.rb +2 -0
- data/lib/inspec/{plugins → plugin/v1/plugin_types}/fetcher.rb +1 -1
- data/lib/inspec/{plugins → plugin/v1/plugin_types}/resource.rb +0 -0
- data/lib/inspec/{plugins → plugin/v1/plugin_types}/secret.rb +1 -1
- data/lib/inspec/{plugins → plugin/v1/plugin_types}/source_reader.rb +1 -1
- data/lib/inspec/{plugins.rb → plugin/v1/plugins.rb} +7 -5
- data/lib/{utils/plugin_registry.rb → inspec/plugin/v1/registry.rb} +0 -0
- data/lib/inspec/plugin/v2.rb +30 -0
- data/lib/inspec/plugin/v2/activator.rb +16 -0
- data/lib/inspec/plugin/v2/loader.rb +204 -0
- data/lib/inspec/plugin/v2/plugin_base.rb +98 -0
- data/lib/inspec/plugin/v2/plugin_types/cli.rb +27 -0
- data/lib/inspec/plugin/v2/plugin_types/mock.rb +12 -0
- data/lib/inspec/plugin/v2/registry.rb +76 -0
- data/lib/inspec/plugin/v2/status.rb +29 -0
- data/lib/inspec/reporters.rb +5 -1
- data/lib/inspec/reporters/automate.rb +1 -1
- data/lib/inspec/reporters/{json_merged.rb → json_automate.rb} +1 -1
- data/lib/inspec/resource.rb +1 -1
- data/lib/inspec/rule.rb +14 -8
- data/lib/inspec/secrets.rb +1 -2
- data/lib/inspec/source_reader.rb +1 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apache_conf.rb +1 -1
- metadata +20 -10
data/lib/inspec.rb
CHANGED
|
@@ -16,9 +16,11 @@ require 'inspec/shell'
|
|
|
16
16
|
require 'inspec/formatters'
|
|
17
17
|
require 'inspec/reporters'
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
require 'inspec/plugin/v2'
|
|
20
|
+
require 'inspec/plugin/v1'
|
|
21
|
+
|
|
22
|
+
# all utils that may be required by legacy plugins
|
|
20
23
|
require 'inspec/base_cli'
|
|
21
24
|
require 'inspec/fetcher'
|
|
22
25
|
require 'inspec/source_reader'
|
|
23
26
|
require 'inspec/resource'
|
|
24
|
-
require 'inspec/plugins'
|
data/lib/inspec/base_cli.rb
CHANGED
data/lib/inspec/cli.rb
CHANGED
|
@@ -10,7 +10,8 @@ require 'pp'
|
|
|
10
10
|
require 'utils/json_log'
|
|
11
11
|
require 'utils/latest_version'
|
|
12
12
|
require 'inspec/base_cli'
|
|
13
|
-
require 'inspec/
|
|
13
|
+
require 'inspec/plugin/v1'
|
|
14
|
+
require 'inspec/plugin/v2'
|
|
14
15
|
require 'inspec/runner_mock'
|
|
15
16
|
require 'inspec/env_printer'
|
|
16
17
|
require 'inspec/schema'
|
|
@@ -20,7 +21,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
|
20
21
|
desc: 'Set the log level: info (default), debug, warn, error'
|
|
21
22
|
|
|
22
23
|
class_option :log_location, type: :string,
|
|
23
|
-
desc: 'Location to send diagnostic log messages to. (default: STDOUT or
|
|
24
|
+
desc: 'Location to send diagnostic log messages to. (default: STDOUT or Inspec::Log.error)'
|
|
24
25
|
|
|
25
26
|
class_option :diagnose, type: :boolean,
|
|
26
27
|
desc: 'Show diagnostics (versions, configurations)'
|
|
@@ -282,17 +283,35 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
|
282
283
|
end
|
|
283
284
|
end
|
|
284
285
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
286
|
+
begin
|
|
287
|
+
# Load v2 plugins
|
|
288
|
+
v2_loader = Inspec::Plugin::V2::Loader.new
|
|
289
|
+
v2_loader.load_all
|
|
290
|
+
v2_loader.exit_on_load_error
|
|
291
|
+
v2_loader.activate_mentioned_cli_plugins
|
|
292
|
+
|
|
293
|
+
# Load v1 plugins on startup
|
|
294
|
+
ctl = Inspec::PluginCtl.new
|
|
295
|
+
ctl.list.each { |x| ctl.load(x) }
|
|
296
|
+
|
|
297
|
+
# load v1 CLI plugins before the Inspec CLI has been started
|
|
298
|
+
Inspec::Plugins::CLI.subcommands.each { |_subcommand, params|
|
|
299
|
+
Inspec::InspecCLI.register(
|
|
300
|
+
params[:klass],
|
|
301
|
+
params[:subcommand_name],
|
|
302
|
+
params[:usage],
|
|
303
|
+
params[:description],
|
|
304
|
+
params[:options],
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
rescue Inspec::Plugin::V2::Exception => v2ex
|
|
308
|
+
Inspec::Log.error v2ex.message
|
|
309
|
+
|
|
310
|
+
if ARGV.include?('--debug')
|
|
311
|
+
Inspec::Log.error v2ex.class.name
|
|
312
|
+
Inspec::Log.error v2ex.backtrace.join("\n")
|
|
313
|
+
else
|
|
314
|
+
Inspec::Log.error 'Run again with --debug for a stacktrace.'
|
|
315
|
+
end
|
|
316
|
+
exit 2
|
|
317
|
+
end
|
|
@@ -52,6 +52,7 @@ module Inspec
|
|
|
52
52
|
@conf = conf
|
|
53
53
|
@dependencies = dependencies
|
|
54
54
|
@require_loader = require_loader
|
|
55
|
+
@skip_file_message = nil
|
|
55
56
|
@skip_file = false
|
|
56
57
|
@skip_only_if_eval = skip_only_if_eval
|
|
57
58
|
end
|
|
@@ -118,18 +119,18 @@ module Inspec
|
|
|
118
119
|
|
|
119
120
|
define_method :register_control do |control, &block|
|
|
120
121
|
if @skip_file
|
|
121
|
-
::Inspec::Rule.set_skip_rule(control, true)
|
|
122
|
+
::Inspec::Rule.set_skip_rule(control, true, @skip_file_message)
|
|
122
123
|
end
|
|
123
124
|
|
|
124
125
|
unless profile_context_owner.profile_supports_platform?
|
|
125
126
|
platform = inspec.platform
|
|
126
127
|
msg = "Profile #{profile_context_owner.profile_id} is not supported on platform #{platform.name}/#{platform.release}."
|
|
127
|
-
::Inspec::Rule.set_skip_rule(control, msg)
|
|
128
|
+
::Inspec::Rule.set_skip_rule(control, true, msg)
|
|
128
129
|
end
|
|
129
130
|
|
|
130
131
|
unless profile_context_owner.profile_supports_inspec_version?
|
|
131
132
|
msg = "Profile #{profile_context_owner.profile_id} is not supported on InSpec version (#{Inspec::VERSION})."
|
|
132
|
-
::Inspec::Rule.set_skip_rule(control, msg)
|
|
133
|
+
::Inspec::Rule.set_skip_rule(control, true, msg)
|
|
133
134
|
end
|
|
134
135
|
|
|
135
136
|
profile_context_owner.register_rule(control, &block) unless control.nil?
|
|
@@ -144,19 +145,19 @@ module Inspec
|
|
|
144
145
|
profile_context_owner.unregister_rule(id)
|
|
145
146
|
end
|
|
146
147
|
|
|
147
|
-
define_method :only_if do
|
|
148
|
+
define_method :only_if do |message = nil, &block|
|
|
148
149
|
return unless block
|
|
149
150
|
return if @skip_file == true
|
|
150
151
|
return if @skip_only_if_eval == true
|
|
151
152
|
|
|
152
153
|
return if block.yield == true
|
|
153
|
-
|
|
154
154
|
# Apply `set_skip_rule` for other rules in the same file
|
|
155
155
|
profile_context_owner.rules.values.each do |r|
|
|
156
156
|
sources_match = r.source_file == block.source_location[0]
|
|
157
|
-
Inspec::Rule.set_skip_rule(r, true) if sources_match
|
|
157
|
+
Inspec::Rule.set_skip_rule(r, true, message) if sources_match
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
+
@skip_file_message = message
|
|
160
161
|
@skip_file = true
|
|
161
162
|
end
|
|
162
163
|
|
data/lib/inspec/fetcher.rb
CHANGED
|
File without changes
|
|
@@ -6,12 +6,14 @@ require 'forwardable'
|
|
|
6
6
|
|
|
7
7
|
module Inspec
|
|
8
8
|
# Resource Plugins
|
|
9
|
+
# NOTE: the autoloading here is rendered moot by the fact that
|
|
10
|
+
# all core plugins are `require`'d by the base inspec.rb
|
|
9
11
|
module Plugins
|
|
10
|
-
autoload :Resource, 'inspec/
|
|
11
|
-
autoload :CLI, 'inspec/
|
|
12
|
-
autoload :Fetcher, 'inspec/
|
|
13
|
-
autoload :SourceReader, 'inspec/
|
|
14
|
-
autoload :Secret, 'inspec/
|
|
12
|
+
autoload :Resource, 'inspec/plugin/v1/plugin_types/resource'
|
|
13
|
+
autoload :CLI, 'inspec/plugin/v1/plugin_types/cli'
|
|
14
|
+
autoload :Fetcher, 'inspec/plugin/v1/plugin_types/fetcher'
|
|
15
|
+
autoload :SourceReader, 'inspec/plugin/v1/plugin_types/source_reader'
|
|
16
|
+
autoload :Secret, 'inspec/plugin/v1/plugin_types/secret'
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
# PLEASE NOTE: The Plugin system is an internal mechanism for connecting
|
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'inspec/errors'
|
|
2
|
+
|
|
3
|
+
module Inspec
|
|
4
|
+
module Plugin
|
|
5
|
+
module V2
|
|
6
|
+
class Exception < Inspec::Error; end
|
|
7
|
+
class ConfigError < Inspec::Plugin::V2::Exception; end
|
|
8
|
+
class LoadError < Inspec::Plugin::V2::Exception; end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
require_relative 'v2/registry'
|
|
14
|
+
require_relative 'v2/loader'
|
|
15
|
+
require_relative 'v2/plugin_base'
|
|
16
|
+
|
|
17
|
+
# Load all plugin type base classes
|
|
18
|
+
Dir.glob(File.join(__dir__, 'v2', 'plugin_types', '*.rb')).each { |file| require file }
|
|
19
|
+
|
|
20
|
+
module Inspec
|
|
21
|
+
# Provides the base class that plugin implementors should use.
|
|
22
|
+
def self.plugin(version, plugin_type = nil)
|
|
23
|
+
unless version == 2
|
|
24
|
+
raise 'Only plugins version 2 is supported!'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
return Inspec::Plugin::V2::PluginBase if plugin_type.nil?
|
|
28
|
+
Inspec::Plugin::V2::PluginBase.base_class_for_type(plugin_type)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Inspec::Plugin::V2
|
|
2
|
+
Activator = Struct.new(
|
|
3
|
+
:plugin_name,
|
|
4
|
+
:plugin_type,
|
|
5
|
+
:activator_name,
|
|
6
|
+
:activated,
|
|
7
|
+
:exception,
|
|
8
|
+
:activation_proc,
|
|
9
|
+
:implementation_class,
|
|
10
|
+
) do
|
|
11
|
+
def initialize(*)
|
|
12
|
+
super
|
|
13
|
+
self[:activated] = false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'inspec/log'
|
|
3
|
+
|
|
4
|
+
# Add the current directory of the process to the load path
|
|
5
|
+
$LOAD_PATH.unshift('.') unless $LOAD_PATH.include?('.')
|
|
6
|
+
# Add the InSpec source root directory to the load path
|
|
7
|
+
folder = File.expand_path(File.join('..', '..', '..', '..'), __dir__)
|
|
8
|
+
$LOAD_PATH.unshift(folder) unless $LOAD_PATH.include?('folder')
|
|
9
|
+
|
|
10
|
+
module Inspec::Plugin::V2
|
|
11
|
+
class Loader
|
|
12
|
+
attr_reader :registry, :options
|
|
13
|
+
|
|
14
|
+
def initialize(options = {})
|
|
15
|
+
@options = options
|
|
16
|
+
@registry = Inspec::Plugin::V2::Registry.instance
|
|
17
|
+
determine_plugin_conf_file
|
|
18
|
+
read_conf_file
|
|
19
|
+
unpack_conf_file
|
|
20
|
+
detect_bundled_plugins unless options[:omit_bundles]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def load_all
|
|
24
|
+
registry.each do |plugin_name, plugin_details|
|
|
25
|
+
# We want to capture literally any possible exception here, since we are storing them.
|
|
26
|
+
# rubocop: disable Lint/RescueException
|
|
27
|
+
begin
|
|
28
|
+
# We could use require, but under testing, we need to repeatedly reload the same
|
|
29
|
+
# plugin.
|
|
30
|
+
if plugin_details.entry_point.include?('test/unit/mock/plugins')
|
|
31
|
+
load plugin_details.entry_point + '.rb'
|
|
32
|
+
else
|
|
33
|
+
require plugin_details.entry_point
|
|
34
|
+
end
|
|
35
|
+
plugin_details.loaded = true
|
|
36
|
+
annotate_status_after_loading(plugin_name)
|
|
37
|
+
rescue ::Exception => ex
|
|
38
|
+
plugin_details.load_exception = ex
|
|
39
|
+
Inspec::Log.error "Could not load plugin #{plugin_name}"
|
|
40
|
+
end
|
|
41
|
+
# rubocop: enable Lint/RescueException
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# This should possibly be in either lib/inspec/cli.rb or Registry
|
|
46
|
+
def exit_on_load_error
|
|
47
|
+
if registry.any_load_failures?
|
|
48
|
+
Inspec::Log.error 'Errors were encountered while loading plugins...'
|
|
49
|
+
registry.plugin_statuses.select(&:load_exception).each do |plugin_status|
|
|
50
|
+
Inspec::Log.error 'Plugin name: ' + plugin_status.name.to_s
|
|
51
|
+
Inspec::Log.error 'Error: ' + plugin_status.load_exception.message
|
|
52
|
+
if ARGV.include?('--debug')
|
|
53
|
+
Inspec::Log.error 'Exception: ' + plugin_status.load_exception.class.name
|
|
54
|
+
Inspec::Log.error 'Trace: ' + plugin_status.load_exception.backtrace.join("\n")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
Inspec::Log.error('Run again with --debug for a stacktrace.') unless ARGV.include?('--debug')
|
|
58
|
+
exit 2
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def activate(plugin_type, hook_name)
|
|
63
|
+
activator = registry.find_activators(plugin_type: plugin_type, activation_name: hook_name).first
|
|
64
|
+
# We want to capture literally any possible exception here, since we are storing them.
|
|
65
|
+
# rubocop: disable Lint/RescueException
|
|
66
|
+
begin
|
|
67
|
+
impl_class = activator.activation_proc.call
|
|
68
|
+
activator.activated = true
|
|
69
|
+
activator.implementation_class = impl_class
|
|
70
|
+
rescue Exception => ex
|
|
71
|
+
activator.exception = ex
|
|
72
|
+
Inspec::Log.error "Could not activate #{activator.plugin_type} hook named '#{activator.activator_name}' for plugin #{plugin_name}"
|
|
73
|
+
end
|
|
74
|
+
# rubocop: enable Lint/RescueException
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def activate_mentioned_cli_plugins(cli_args = ARGV)
|
|
78
|
+
# Get a list of CLI plugin activation hooks
|
|
79
|
+
registry.find_activators(plugin_type: :cli_command).each do |act|
|
|
80
|
+
next if act.activated
|
|
81
|
+
# If there is anything in the CLI args with the same name, activate it
|
|
82
|
+
# If the word 'help' appears in the first position, load all CLI plugins
|
|
83
|
+
if cli_args.include?(act.activator_name.to_s) || cli_args[0] == 'help'
|
|
84
|
+
activate(:cli_command, act.activator_name)
|
|
85
|
+
act.implementation_class.register_with_thor
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def annotate_status_after_loading(plugin_name)
|
|
93
|
+
status = registry[plugin_name]
|
|
94
|
+
return if status.api_generation == 2 # Gen2 have self-annotating superclasses
|
|
95
|
+
case status.installation_type
|
|
96
|
+
when :bundle
|
|
97
|
+
annotate_bundle_plugin_status_after_load(plugin_name)
|
|
98
|
+
else
|
|
99
|
+
# TODO: are there any other cases? can this whole thing be eliminated?
|
|
100
|
+
raise "I only know how to annotate :bundle plugins when trying to load plugin #{plugin_name}" unless status.installation_type == :bundle
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def annotate_bundle_plugin_status_after_load(plugin_name)
|
|
105
|
+
# HACK: we're relying on the fact that all bundles are gen0 and cli type
|
|
106
|
+
status = registry[plugin_name]
|
|
107
|
+
status.api_generation = 0
|
|
108
|
+
act = Activator.new
|
|
109
|
+
act.activated = true
|
|
110
|
+
act.plugin_type = :cli_command
|
|
111
|
+
act.plugin_name = plugin_name
|
|
112
|
+
act.activator_name = :default
|
|
113
|
+
status.activators = [act]
|
|
114
|
+
|
|
115
|
+
v0_subcommand_name = plugin_name.to_s.gsub('inspec-', '')
|
|
116
|
+
status.plugin_class = Inspec::Plugins::CLI.subcommands[v0_subcommand_name][:klass]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def detect_bundled_plugins
|
|
120
|
+
bundle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'bundles'))
|
|
121
|
+
globs = [
|
|
122
|
+
File.join(bundle_dir, 'inspec-*.rb'),
|
|
123
|
+
File.join(bundle_dir, 'train-*.rb'),
|
|
124
|
+
]
|
|
125
|
+
Dir.glob(globs).each do |loader_file|
|
|
126
|
+
name = File.basename(loader_file, '.rb').gsub(/^(inspec|train)-/, '')
|
|
127
|
+
status = Inspec::Plugin::V2::Status.new
|
|
128
|
+
status.name = name
|
|
129
|
+
status.entry_point = loader_file
|
|
130
|
+
status.installation_type = :bundle
|
|
131
|
+
status.loaded = false
|
|
132
|
+
registry[name] = status
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def determine_plugin_conf_file
|
|
137
|
+
@plugin_conf_file_path = ENV['INSPEC_CONFIG_DIR'] ? ENV['INSPEC_CONFIG_DIR'] : File.join(Dir.home, '.inspec')
|
|
138
|
+
@plugin_conf_file_path = File.join(@plugin_conf_file_path, 'plugins.json')
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def read_conf_file
|
|
142
|
+
if File.exist?(@plugin_conf_file_path)
|
|
143
|
+
@plugin_file_contents = JSON.parse(File.read(@plugin_conf_file_path))
|
|
144
|
+
else
|
|
145
|
+
@plugin_file_contents = {
|
|
146
|
+
'plugins_config_version' => '1.0.0',
|
|
147
|
+
'plugins' => [],
|
|
148
|
+
}
|
|
149
|
+
end
|
|
150
|
+
rescue JSON::ParserError => e
|
|
151
|
+
raise Inspec::Plugin::V2::ConfigError, "Failed to load plugins JSON configuration from #{@plugin_conf_file_path}:\n#{e}"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def unpack_conf_file
|
|
155
|
+
validate_conf_file
|
|
156
|
+
@plugin_file_contents['plugins'].each do |plugin_json|
|
|
157
|
+
status = Inspec::Plugin::V2::Status.new
|
|
158
|
+
status.name = plugin_json['name'].to_sym
|
|
159
|
+
status.loaded = false
|
|
160
|
+
status.installation_type = plugin_json['installation_type'].to_sym || :gem
|
|
161
|
+
case status.installation_type
|
|
162
|
+
when :gem
|
|
163
|
+
status.entry_point = status.name
|
|
164
|
+
status.version = plugin_json['version']
|
|
165
|
+
when :path
|
|
166
|
+
status.entry_point = plugin_json['installation_path']
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
registry[status.name] = status
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def validate_conf_file
|
|
174
|
+
unless @plugin_file_contents['plugins_config_version'] == '1.0.0'
|
|
175
|
+
raise Inspec::Plugin::V2::ConfigError, "Unsupported plugins.json file version #{@plugin_file_contents['plugins_config_version']} at #{@plugin_conf_file_path} - currently support versions: 1.0.0"
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
plugin_entries = @plugin_file_contents['plugins']
|
|
179
|
+
unless plugin_entries.is_a?(Array)
|
|
180
|
+
raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - should have a top-level key named 'plugins', whose value is an array"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
plugin_entries.each do |plugin_entry|
|
|
184
|
+
unless plugin_entry.is_a? Hash
|
|
185
|
+
raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - each 'plugins' entry should be a Hash / JSON object"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
unless plugin_entry.key? 'name'
|
|
189
|
+
raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - each 'plugins' entry must have a 'name' field"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
next unless plugin_entry.key?('installation_type')
|
|
193
|
+
unless %w{gem path}.include? plugin_entry['installation_type']
|
|
194
|
+
raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - each 'installation_type' must be one of 'gem' or 'path'"
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
next unless plugin_entry['installation_type'] == 'path'
|
|
198
|
+
unless plugin_entry.key?('installation_path')
|
|
199
|
+
raise Inspec::Plugin::V2::ConfigError, "Malformed plugins.json file - each 'plugins' entry with a 'path' installation_type must provide an 'installation_path' field"
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|