inspec 4.12.0 → 4.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/etc/plugin_filters.json +0 -4
- data/lib/fetchers/git.rb +2 -0
- data/lib/inspec/base_cli.rb +2 -0
- data/lib/inspec/cli.rb +2 -2
- data/lib/inspec/config.rb +49 -2
- data/lib/inspec/input_registry.rb +30 -0
- data/lib/inspec/metadata.rb +4 -0
- data/lib/inspec/plugin/v1/plugin_types/resource.rb +5 -11
- data/lib/inspec/plugin/v2/filter.rb +33 -0
- data/lib/inspec/plugin/v2/installer.rb +10 -7
- data/lib/inspec/plugin/v2/loader.rb +64 -20
- data/lib/inspec/profile.rb +12 -2
- data/lib/inspec/resources.rb +1 -0
- data/lib/inspec/resources/postfix_conf.rb +31 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +88 -53
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +125 -97
- data/lib/plugins/inspec-plugin-manager-cli/test/unit/cli_args_test.rb +8 -6
- data/lib/source_readers/inspec.rb +14 -12
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 877fb588106fac603caf212f8224901fbad9d694097718b85382c40140989477
|
4
|
+
data.tar.gz: afc82cd0c4e59ddf7466c68f8a67a79288548f44fddb5b49b27726f8dbe2f05e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 197367b25a88684493e27d1db0b070c2790d9373476f98b09fb11a5d213d50e4c971d26c9be8c4969833cbb87f09fa28c88be448303646bd26ca85374182af44
|
7
|
+
data.tar.gz: ac3787f1a29e222221edbeefa46c620fc59d2a6e712e2c1de8d3594de448473acd0700ba7880c1d2e82bd7b02804f161ad42421423940f36b8ffa8b43b0b90d1
|
data/etc/plugin_filters.json
CHANGED
@@ -25,10 +25,6 @@
|
|
25
25
|
"plugin_name": "inspec-release",
|
26
26
|
"rationale": "This gem is currently only a placeholder, waiting to be built."
|
27
27
|
},
|
28
|
-
{
|
29
|
-
"plugin_name": "inspec-vault",
|
30
|
-
"rationale": "This gem is currently only a placeholder, waiting to be built."
|
31
|
-
},
|
32
28
|
{
|
33
29
|
"plugin_name": "train-vault",
|
34
30
|
"rationale": "This gem is currently only a placeholder, waiting to be built."
|
data/lib/fetchers/git.rb
CHANGED
@@ -52,6 +52,7 @@ module Fetchers
|
|
52
52
|
# processing, but then again, if you passed a relative path
|
53
53
|
# to an on-disk repo, you probably expect it to exist.
|
54
54
|
return url_or_file_path unless File.exist?(url_or_file_path)
|
55
|
+
|
55
56
|
# It's important to expand this path, because it may be specified
|
56
57
|
# locally in the metadata files, and when we clone, we will be
|
57
58
|
# in a temp dir.
|
@@ -97,6 +98,7 @@ module Fetchers
|
|
97
98
|
|
98
99
|
def cache_key
|
99
100
|
return resolved_ref unless @relative_path
|
101
|
+
|
100
102
|
OpenSSL::Digest::SHA256.hexdigest(resolved_ref + @relative_path)
|
101
103
|
end
|
102
104
|
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -133,6 +133,8 @@ module Inspec
|
|
133
133
|
option :reporter, type: :array,
|
134
134
|
banner: "one two:/output/file/path",
|
135
135
|
desc: "Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml"
|
136
|
+
option :input, type: :array, banner: "name1=value1 name2=value2",
|
137
|
+
desc: "Specify one or more inputs directly on the command line, as --input NAME=VALUE"
|
136
138
|
option :input_file, type: :array,
|
137
139
|
desc: "Load one or more input files, a YAML file with values for the profile to use"
|
138
140
|
option :attrs, type: :array,
|
data/lib/inspec/cli.rb
CHANGED
@@ -124,8 +124,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
124
124
|
else
|
125
125
|
%w{location profile controls timestamp valid}.each do |item|
|
126
126
|
prepared_string = format("%-12s %s",
|
127
|
-
|
128
|
-
|
127
|
+
"#{item.to_s.capitalize} :",
|
128
|
+
result[:summary][item.to_sym])
|
129
129
|
ui.plain_line(prepared_string)
|
130
130
|
end
|
131
131
|
puts
|
data/lib/inspec/config.rb
CHANGED
@@ -7,9 +7,12 @@ require "forwardable"
|
|
7
7
|
require "thor"
|
8
8
|
require "base64"
|
9
9
|
require "inspec/base_cli"
|
10
|
+
require "inspec/plugin/v2/filter"
|
10
11
|
|
11
12
|
module Inspec
|
12
13
|
class Config
|
14
|
+
include Inspec::Plugin::V2::FilterPredicates
|
15
|
+
|
13
16
|
# These are options that apply to any transport
|
14
17
|
GENERIC_CREDENTIALS = %w{
|
15
18
|
backend
|
@@ -23,6 +26,11 @@ module Inspec
|
|
23
26
|
shell_command
|
24
27
|
}.freeze
|
25
28
|
|
29
|
+
KNOWN_VERSIONS = [
|
30
|
+
"1.1",
|
31
|
+
"1.2",
|
32
|
+
].freeze
|
33
|
+
|
26
34
|
extend Forwardable
|
27
35
|
|
28
36
|
# Many parts of InSpec expect to treat the Config as a Hash
|
@@ -48,6 +56,7 @@ module Inspec
|
|
48
56
|
def initialize(cli_opts = {}, cfg_io = nil, command_name = nil)
|
49
57
|
@command_name = command_name || (ARGV.empty? ? nil : ARGV[0].to_sym)
|
50
58
|
@defaults = Defaults.for_command(@command_name)
|
59
|
+
@plugin_cfg = {}
|
51
60
|
|
52
61
|
@cli_opts = cli_opts.dup
|
53
62
|
cfg_io = resolve_cfg_io(@cli_opts, cfg_io)
|
@@ -119,6 +128,13 @@ module Inspec
|
|
119
128
|
end
|
120
129
|
end
|
121
130
|
|
131
|
+
#-----------------------------------------------------------------------#
|
132
|
+
# Fetching Plugin Data
|
133
|
+
#-----------------------------------------------------------------------#
|
134
|
+
def fetch_plugin_config(plugin_name)
|
135
|
+
Thor::CoreExt::HashWithIndifferentAccess.new(@plugin_cfg[plugin_name] || {})
|
136
|
+
end
|
137
|
+
|
122
138
|
private
|
123
139
|
|
124
140
|
def _utc_merge_transport_options(credentials, transport_name)
|
@@ -285,16 +301,24 @@ module Inspec
|
|
285
301
|
# Assume legacy format, which is unconstrained
|
286
302
|
return unless version
|
287
303
|
|
288
|
-
unless version
|
289
|
-
raise Inspec::ConfigError::Invalid, "Unsupported config file version '#{version}' - currently supported versions:
|
304
|
+
unless KNOWN_VERSIONS.include?(version)
|
305
|
+
raise Inspec::ConfigError::Invalid, "Unsupported config file version '#{version}' - currently supported versions: #{KNOWN_VERSIONS.join(",")}"
|
290
306
|
end
|
291
307
|
|
308
|
+
# Use Gem::Version for comparision operators
|
309
|
+
cfg_version = Gem::Version.new(version)
|
310
|
+
version_1_2 = Gem::Version.new("1.2")
|
311
|
+
|
312
|
+
# TODO: proper schema version loading and validation
|
292
313
|
valid_fields = %w{version cli_options credentials compliance reporter}.sort
|
314
|
+
valid_fields << "plugins" if cfg_version >= version_1_2
|
293
315
|
@cfg_file_contents.keys.each do |seen_field|
|
294
316
|
unless valid_fields.include?(seen_field)
|
295
317
|
raise Inspec::ConfigError::Invalid, "Unrecognized top-level configuration field #{seen_field}. Recognized fields: #{valid_fields.join(", ")}"
|
296
318
|
end
|
297
319
|
end
|
320
|
+
|
321
|
+
validate_plugins! if cfg_version >= version_1_2
|
298
322
|
end
|
299
323
|
|
300
324
|
def validate_reporters!(reporters)
|
@@ -334,6 +358,29 @@ module Inspec
|
|
334
358
|
raise ArgumentError, "The option --reporter can only have a single report outputting to stdout." if stdout_reporters > 1
|
335
359
|
end
|
336
360
|
|
361
|
+
def validate_plugins!
|
362
|
+
return unless @cfg_file_contents.key? "plugins"
|
363
|
+
|
364
|
+
data = @cfg_file_contents["plugins"]
|
365
|
+
unless data.is_a?(Hash)
|
366
|
+
raise Inspec::ConfigError::Invalid, "The 'plugin' field in your config file must be a hash (key-value list), not an array."
|
367
|
+
end
|
368
|
+
|
369
|
+
data.each do |plugin_name, plugin_settings|
|
370
|
+
# Enforce that every key is a valid inspec or train plugin name
|
371
|
+
unless valid_plugin_name?(plugin_name)
|
372
|
+
raise Inspec::ConfigError::Invalid, "Plugin settings should ne named after the the InSpec or Train plugin. Valid names must begin with inspec- or train-, not '#{plugin_name}' "
|
373
|
+
end
|
374
|
+
|
375
|
+
# Enforce that every entry is hash-valued
|
376
|
+
unless plugin_settings.is_a?(Hash)
|
377
|
+
raise Inspec::ConfigError::Invalid, "The plugin settings for '#{plugin_name}' in your config file should be a Hash (key-value list)."
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
@plugin_cfg = data
|
382
|
+
end
|
383
|
+
|
337
384
|
#-----------------------------------------------------------------------#
|
338
385
|
# Merging Options
|
339
386
|
#-----------------------------------------------------------------------#
|
@@ -64,6 +64,9 @@ module Inspec
|
|
64
64
|
#-------------------------------------------------------------#
|
65
65
|
|
66
66
|
def find_or_register_input(input_name, profile_name, options = {})
|
67
|
+
input_name = input_name.to_s
|
68
|
+
profile_name = profile_name.to_s
|
69
|
+
|
67
70
|
if profile_alias?(profile_name) && !profile_aliases[profile_name].nil?
|
68
71
|
alias_name = profile_name
|
69
72
|
profile_name = profile_aliases[profile_name]
|
@@ -132,10 +135,37 @@ module Inspec
|
|
132
135
|
bind_inputs_from_metadata(profile_name, sources[:profile_metadata])
|
133
136
|
bind_inputs_from_input_files(profile_name, sources[:cli_input_files])
|
134
137
|
bind_inputs_from_runner_api(profile_name, sources[:runner_api])
|
138
|
+
bind_inputs_from_cli_args(profile_name, sources[:cli_input_arg])
|
135
139
|
end
|
136
140
|
|
137
141
|
private
|
138
142
|
|
143
|
+
def bind_inputs_from_cli_args(profile_name, input_list)
|
144
|
+
# TODO: move this into a core plugin
|
145
|
+
|
146
|
+
return if input_list.nil?
|
147
|
+
return if input_list.empty?
|
148
|
+
|
149
|
+
# These arrive as an array of "name=value" strings
|
150
|
+
# If the user used a comma, we'll see unfortunately see it as "name=value," pairs
|
151
|
+
input_list.each do |pair|
|
152
|
+
unless pair.include?("=")
|
153
|
+
if pair.end_with?(".yaml")
|
154
|
+
raise ArgumentError, "ERROR: --input is used for individual input values, as --input name=value. Use --input-file to load a YAML file."
|
155
|
+
else
|
156
|
+
raise ArgumentError, "ERROR: An '=' is required when using --input. Usage: --input input_name1=input_value1 input2=value2"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
input_name, input_value = pair.split("=")
|
160
|
+
evt = Inspec::Input::Event.new(
|
161
|
+
value: input_value.chomp(","), # Trim trailing comma if any
|
162
|
+
provider: :cli,
|
163
|
+
priority: 50
|
164
|
+
)
|
165
|
+
find_or_register_input(input_name, profile_name, event: evt)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
139
169
|
def bind_inputs_from_runner_api(profile_name, input_hash)
|
140
170
|
# TODO: move this into a core plugin
|
141
171
|
|
data/lib/inspec/metadata.rb
CHANGED
@@ -88,6 +88,10 @@ module Inspec
|
|
88
88
|
errors.push("Version needs to be in SemVer format")
|
89
89
|
end
|
90
90
|
|
91
|
+
unless supports_runtime?
|
92
|
+
warnings.push("The current inspec version #{Inspec::VERSION} cannot satisfy profile inspec_version constraint #{params[:inspec_version]}")
|
93
|
+
end
|
94
|
+
|
91
95
|
%w{title summary maintainer copyright license}.each do |field|
|
92
96
|
next unless params[field.to_sym].nil?
|
93
97
|
|
@@ -81,17 +81,13 @@ module Inspec
|
|
81
81
|
@resource_skipped = false
|
82
82
|
@resource_failed = false
|
83
83
|
@supports = Inspec::Resource.supports[name]
|
84
|
+
@resource_exception_message = nil
|
84
85
|
|
85
86
|
# attach the backend to this instance
|
86
87
|
@__backend_runner__ = backend
|
87
88
|
@__resource_name__ = name
|
88
89
|
|
89
|
-
#
|
90
|
-
supported = true
|
91
|
-
supported = check_supports unless @supports.nil?
|
92
|
-
test_backend = defined?(Train::Transports::Mock::Connection) && backend.backend.class == Train::Transports::Mock::Connection
|
93
|
-
# do not return if we are supported, or for tests
|
94
|
-
return unless supported || test_backend
|
90
|
+
check_supports unless @supports.nil? # this has side effects
|
95
91
|
|
96
92
|
# call the resource initializer
|
97
93
|
begin
|
@@ -100,12 +96,10 @@ module Inspec
|
|
100
96
|
skip_resource(e.message)
|
101
97
|
rescue Inspec::Exceptions::ResourceFailed => e
|
102
98
|
fail_resource(e.message)
|
99
|
+
rescue NotImplementedError => e
|
100
|
+
fail_resource(e.message) unless @resource_failed
|
103
101
|
rescue NoMethodError => e
|
104
|
-
|
105
|
-
# for inspec check to work we need to skip these train errors
|
106
|
-
raise unless test_backend && e.receiver.class == Train::Transports::Mock::Connection
|
107
|
-
|
108
|
-
skip_resource(e.message)
|
102
|
+
skip_resource(e.message) unless @resource_failed
|
109
103
|
end
|
110
104
|
end
|
111
105
|
|
@@ -2,6 +2,8 @@ require "singleton"
|
|
2
2
|
require "json"
|
3
3
|
require "inspec/globals"
|
4
4
|
|
5
|
+
module Inspec::Plugin; end
|
6
|
+
|
5
7
|
module Inspec::Plugin::V2
|
6
8
|
Exclusion = Struct.new(:plugin_name, :rationale)
|
7
9
|
|
@@ -60,4 +62,35 @@ module Inspec::Plugin::V2
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
65
|
+
|
66
|
+
# To be a valid plugin name, the plugin must beign with either
|
67
|
+
# inspec- or train-, AND ALSO not be on the exclusion list.
|
68
|
+
# We maintain this exclusion list to avoid confusing users.
|
69
|
+
# For example, we want to have a real gem named inspec-test-fixture,
|
70
|
+
# but we don't want the users to see that.
|
71
|
+
module FilterPredicates
|
72
|
+
def train_plugin_name?(name)
|
73
|
+
valid_plugin_name?(name, :train)
|
74
|
+
end
|
75
|
+
|
76
|
+
def inspec_plugin_name?(name)
|
77
|
+
valid_plugin_name?(name, :inspec)
|
78
|
+
end
|
79
|
+
|
80
|
+
def valid_plugin_name?(name, kind = :either)
|
81
|
+
# Must have a permitted prefix.
|
82
|
+
return false unless case kind
|
83
|
+
when :inspec
|
84
|
+
name.to_s.start_with?("inspec-")
|
85
|
+
when :train
|
86
|
+
name.to_s.start_with?("train-")
|
87
|
+
when :either
|
88
|
+
name.to_s.match(/^(inspec|train)-/)
|
89
|
+
else false
|
90
|
+
end # rubocop: disable Layout/EndAlignment
|
91
|
+
|
92
|
+
# And must not be on the exclusion list.
|
93
|
+
! Inspec::Plugin::V2::PluginFilter.exclude?(name)
|
94
|
+
end
|
95
|
+
end
|
63
96
|
end
|
@@ -60,14 +60,15 @@ module Inspec::Plugin::V2
|
|
60
60
|
# TODO: - check plugins.json for validity before trying anything that needs to modify it.
|
61
61
|
validate_installation_opts(plugin_name, opts)
|
62
62
|
|
63
|
-
# TODO: change all of these to return installed spec/gem/thingy
|
64
63
|
# TODO: return installed thingy
|
65
64
|
if opts[:path]
|
66
65
|
install_from_path(plugin_name, opts)
|
67
66
|
elsif opts[:gem_file]
|
68
|
-
install_from_gem_file(plugin_name, opts)
|
67
|
+
gem_version = install_from_gem_file(plugin_name, opts)
|
68
|
+
opts[:version] = gem_version.to_s
|
69
69
|
else
|
70
|
-
install_from_remote_gems(plugin_name, opts)
|
70
|
+
gem_version = install_from_remote_gems(plugin_name, opts)
|
71
|
+
opts[:version] = gem_version.to_s
|
71
72
|
end
|
72
73
|
|
73
74
|
update_plugin_config_file(plugin_name, opts.merge({ action: :install }))
|
@@ -88,9 +89,9 @@ module Inspec::Plugin::V2
|
|
88
89
|
|
89
90
|
# TODO: Handle installing from a local file
|
90
91
|
# TODO: Perform dependency checks to make sure the new solution is valid
|
91
|
-
install_from_remote_gems(plugin_name, opts)
|
92
|
+
gem_version = install_from_remote_gems(plugin_name, opts)
|
92
93
|
|
93
|
-
update_plugin_config_file(plugin_name, opts.merge({ action: :update }))
|
94
|
+
update_plugin_config_file(plugin_name, opts.merge({ action: :update, version: gem_version.to_s }))
|
94
95
|
end
|
95
96
|
|
96
97
|
# Uninstalls (removes) a plugin. Refers to plugin.json to determine if it
|
@@ -335,13 +336,15 @@ module Inspec::Plugin::V2
|
|
335
336
|
# not obliged to during packaging.)
|
336
337
|
# So, after each install, run a scan for all gem(specs) we manage, and copy in their gemspec file
|
337
338
|
# into the exploded gem source area if absent.
|
338
|
-
|
339
339
|
loader.list_managed_gems.each do |spec|
|
340
340
|
path_inside_source = File.join(spec.gem_dir, "#{spec.name}.gemspec")
|
341
341
|
unless File.exist?(path_inside_source)
|
342
342
|
File.write(path_inside_source, spec.to_ruby)
|
343
343
|
end
|
344
344
|
end
|
345
|
+
|
346
|
+
# Locate the GemVersion for the new dependency and return it
|
347
|
+
solution.detect { |g| g.name == new_plugin_dependency.name }.version
|
345
348
|
end
|
346
349
|
|
347
350
|
#===================================================================#
|
@@ -365,7 +368,7 @@ module Inspec::Plugin::V2
|
|
365
368
|
# excluding any that are path-or-core-based, excluding the gem to be removed
|
366
369
|
plugin_deps_we_still_must_satisfy = registry.plugin_statuses
|
367
370
|
plugin_deps_we_still_must_satisfy = plugin_deps_we_still_must_satisfy.select do |status|
|
368
|
-
status.installation_type == :
|
371
|
+
status.installation_type == :user_gem && status.name != plugin_name_to_be_removed.to_sym
|
369
372
|
end
|
370
373
|
plugin_deps_we_still_must_satisfy = plugin_deps_we_still_must_satisfy.map do |status|
|
371
374
|
constraint = status.version || "> 0"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "inspec/log"
|
2
2
|
require "inspec/plugin/v2/config_file"
|
3
|
+
require "inspec/plugin/v2/filter"
|
3
4
|
|
4
5
|
# Add the current directory of the process to the load path
|
5
6
|
$LOAD_PATH.unshift(".") unless $LOAD_PATH.include?(".")
|
@@ -11,9 +12,16 @@ module Inspec::Plugin::V2
|
|
11
12
|
class Loader
|
12
13
|
attr_reader :conf_file, :registry, :options
|
13
14
|
|
15
|
+
# For {inspec|train}_plugin_name?
|
16
|
+
include Inspec::Plugin::V2::FilterPredicates
|
17
|
+
extend Inspec::Plugin::V2::FilterPredicates
|
18
|
+
|
14
19
|
def initialize(options = {})
|
15
20
|
@options = options
|
16
21
|
@registry = Inspec::Plugin::V2::Registry.instance
|
22
|
+
|
23
|
+
# User plugins are those installed by the user via `inspec plugin install`
|
24
|
+
# and are installed under ~/.inspec/gems
|
17
25
|
unless options[:omit_user_plugins]
|
18
26
|
@conf_file = Inspec::Plugin::V2::ConfigFile.new
|
19
27
|
read_conf_file_into_registry
|
@@ -27,9 +35,8 @@ module Inspec::Plugin::V2
|
|
27
35
|
# and may be safely loaded
|
28
36
|
detect_core_plugins unless options[:omit_core_plugins]
|
29
37
|
|
30
|
-
#
|
31
|
-
|
32
|
-
accommodate_train_plugins
|
38
|
+
# Identify plugins that inspec is co-installed with
|
39
|
+
detect_system_plugins unless options[:omit_sys_plugins]
|
33
40
|
end
|
34
41
|
|
35
42
|
def load_all
|
@@ -46,7 +53,7 @@ module Inspec::Plugin::V2
|
|
46
53
|
begin
|
47
54
|
# We could use require, but under testing, we need to repeatedly reload the same
|
48
55
|
# plugin. However, gems only work with require (rubygems dooes not overload `load`)
|
49
|
-
if plugin_details.installation_type == :
|
56
|
+
if plugin_details.installation_type == :user_gem
|
50
57
|
activate_managed_gems_for_plugin(plugin_name)
|
51
58
|
require plugin_details.entry_point
|
52
59
|
else
|
@@ -130,10 +137,11 @@ module Inspec::Plugin::V2
|
|
130
137
|
end
|
131
138
|
|
132
139
|
# Lists all plugin gems found in the plugin_gem_path.
|
133
|
-
# This is simply all gems that begin with train- or inspec
|
140
|
+
# This is simply all gems that begin with train- or inspec-
|
141
|
+
# and are not on the exclusion list.
|
134
142
|
# @return [Array[Gem::Specification]] Specs of all gems found.
|
135
143
|
def self.list_installed_plugin_gems
|
136
|
-
list_managed_gems.select { |spec| spec.name
|
144
|
+
list_managed_gems.select { |spec| valid_plugin_name?(spec.name) }
|
137
145
|
end
|
138
146
|
|
139
147
|
def list_installed_plugin_gems
|
@@ -234,34 +242,70 @@ module Inspec::Plugin::V2
|
|
234
242
|
end
|
235
243
|
end
|
236
244
|
|
237
|
-
def accommodate_train_plugins
|
238
|
-
registry.plugin_names.map(&:to_s).grep(/^train-/).each do |train_plugin_name|
|
239
|
-
status = registry[train_plugin_name.to_sym]
|
240
|
-
status.api_generation = :'train-1'
|
241
|
-
|
242
|
-
if status.installation_type == :gem
|
243
|
-
# Activate the gem. This allows train to 'require' the gem later.
|
244
|
-
activate_managed_gems_for_plugin(train_plugin_name)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
245
|
def read_conf_file_into_registry
|
250
246
|
conf_file.each do |plugin_entry|
|
251
247
|
status = Inspec::Plugin::V2::Status.new
|
252
248
|
status.name = plugin_entry[:name]
|
253
249
|
status.loaded = false
|
254
|
-
status.installation_type = (plugin_entry[:installation_type] || :
|
250
|
+
status.installation_type = (plugin_entry[:installation_type] || :user_gem)
|
255
251
|
case status.installation_type
|
256
|
-
when :
|
252
|
+
when :user_gem
|
257
253
|
status.entry_point = status.name.to_s
|
258
254
|
status.version = plugin_entry[:version]
|
259
255
|
when :path
|
260
256
|
status.entry_point = plugin_entry[:installation_path]
|
261
257
|
end
|
262
258
|
|
259
|
+
# Train plugins are not true InSpec plugins; we need to decorate them a
|
260
|
+
# bit more to integrate them.
|
261
|
+
fixup_train_plugin_status(status) if train_plugin_name?(plugin_entry[:name])
|
262
|
+
|
263
263
|
registry[status.name] = status
|
264
264
|
end
|
265
265
|
end
|
266
|
+
|
267
|
+
def fixup_train_plugin_status(status)
|
268
|
+
status.api_generation = :'train-1'
|
269
|
+
if status.installation_type == :user_gem
|
270
|
+
# Activate the gem. This allows train to 'require' the gem later.
|
271
|
+
activate_managed_gems_for_plugin(status.entry_point)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def detect_system_plugins
|
276
|
+
# Find the gemspec for inspec
|
277
|
+
inspec_gemspec = Gem::Specification.find_by_name("inspec", "=#{Inspec::VERSION}")
|
278
|
+
|
279
|
+
# Make a RequestSet that represents the dependencies of inspec
|
280
|
+
inspec_deps_request_set = Gem::RequestSet.new(*inspec_gemspec.dependencies)
|
281
|
+
inspec_deps_request_set.remote = false
|
282
|
+
|
283
|
+
# Resolve the request against the installed gem universe
|
284
|
+
gem_resolver = Gem::Resolver::CurrentSet.new
|
285
|
+
runtime_solution = inspec_deps_request_set.resolve(gem_resolver)
|
286
|
+
|
287
|
+
inspec_gemspec.dependencies.each do |inspec_dep|
|
288
|
+
next unless inspec_plugin_name?(inspec_dep.name) || train_plugin_name?(inspec_dep.name)
|
289
|
+
|
290
|
+
plugin_spec = runtime_solution.detect { |s| s.name == inspec_dep.name }.spec
|
291
|
+
|
292
|
+
status = Inspec::Plugin::V2::Status.new
|
293
|
+
status.name = inspec_dep.name
|
294
|
+
status.entry_point = inspec_dep.name # gem-based, just 'require' the name
|
295
|
+
status.version = plugin_spec.version.to_s
|
296
|
+
status.loaded = false
|
297
|
+
status.installation_type = :system_gem
|
298
|
+
|
299
|
+
if train_plugin_name?(status[:name])
|
300
|
+
# Train plugins are not true InSpec plugins; we need to decorate them a
|
301
|
+
# bit more to integrate them.
|
302
|
+
fixup_train_plugin_status(status)
|
303
|
+
else
|
304
|
+
status.api_generation = 2
|
305
|
+
end
|
306
|
+
|
307
|
+
registry[status.name.to_sym] = status
|
308
|
+
end
|
309
|
+
end
|
266
310
|
end
|
267
311
|
end
|