inspec-core 4.18.100 → 4.18.104
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/lib/inspec/plugin/v2/installer.rb +23 -2
- data/lib/inspec/resources/service.rb +2 -2
- data/lib/inspec/resources/virtualization.rb +86 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +11 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5866bdaba80db3f77d6a3a31af54fcdc6584cb0315093975a90e2a67616b95bd
|
4
|
+
data.tar.gz: a7a84ee7bba5072fc042ea7bd9af8692808e3cc4ae328d182c9af05dd495affd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 438487cd4e20e19f95c767d5627b246f8db486b9686df766ec1cc17883b93aeffad42e86f7bcdc513ecb6b39fa85c2a1f8d4344f1675b8c3768877204abef000
|
7
|
+
data.tar.gz: 32e554b6063e10342aa64d1f5697cc39b1c1b69f6e8b2af19367595b61fe5ef4c6f0c37d121db9195291430a62782bb52bb643c5275e07bda2f2a52054f8b8e5
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "singleton"
|
4
4
|
require "forwardable"
|
5
5
|
require "fileutils"
|
6
|
+
require "uri"
|
6
7
|
|
7
8
|
# Gem extensions for doing unusual things - not loaded by Gem default
|
8
9
|
require "rubygems/package"
|
@@ -56,6 +57,7 @@ module Inspec::Plugin::V2
|
|
56
57
|
# @option opts [String] :gem_file Path to a local gem file to install from
|
57
58
|
# @option opts [String] :path Path to a file to be used as the entry point for a path-based plugin
|
58
59
|
# @option opts [String] :version Version constraint for remote gem installs
|
60
|
+
# @option opts [String] :source Alternate URL to use instead of rubygems.org
|
59
61
|
def install(plugin_name, opts = {})
|
60
62
|
# TODO: - check plugins.json for validity before trying anything that needs to modify it.
|
61
63
|
validate_installation_opts(plugin_name, opts)
|
@@ -127,6 +129,11 @@ module Inspec::Plugin::V2
|
|
127
129
|
validate_search_opts(plugin_query, opts)
|
128
130
|
|
129
131
|
fetcher = Gem::SpecFetcher.fetcher
|
132
|
+
if opts[:source]
|
133
|
+
source_list = Gem::SourceList.from([opts[:source]])
|
134
|
+
fetcher = Gem::SpecFetcher.new(source_list)
|
135
|
+
end
|
136
|
+
|
130
137
|
matched_tuples = []
|
131
138
|
if opts[:exact]
|
132
139
|
matched_tuples = fetcher.detect(opts[:scope]) { |tuple| tuple.name == plugin_query }
|
@@ -284,8 +291,22 @@ module Inspec::Plugin::V2
|
|
284
291
|
|
285
292
|
def install_from_remote_gems(requested_plugin_name, opts)
|
286
293
|
plugin_dependency = Gem::Dependency.new(requested_plugin_name, opts[:version] || "> 0")
|
287
|
-
|
288
|
-
|
294
|
+
|
295
|
+
# BestSet is rubygems.org API + indexing, APISet is for custom sources
|
296
|
+
sources = if opts[:source]
|
297
|
+
Gem::Resolver::APISet.new(URI.join(opts[:source] + "/api/v1/dependencies"))
|
298
|
+
else
|
299
|
+
Gem::Resolver::BestSet.new
|
300
|
+
end
|
301
|
+
|
302
|
+
begin
|
303
|
+
install_gem_to_plugins_dir(plugin_dependency, [sources], opts[:update_mode])
|
304
|
+
rescue Gem::RemoteFetcher::FetchError => gem_ex
|
305
|
+
# TODO: Give a hint if the host was not resolvable or a 404 occured
|
306
|
+
ex = Inspec::Plugin::V2::InstallError.new(gem_ex.message)
|
307
|
+
ex.plugin_name = requested_plugin_name
|
308
|
+
raise ex
|
309
|
+
end
|
289
310
|
end
|
290
311
|
|
291
312
|
def install_gem_to_plugins_dir(new_plugin_dependency, # rubocop: disable Metrics/AbcSize
|
@@ -104,6 +104,8 @@ module Inspec::Resources
|
|
104
104
|
os = inspec.os
|
105
105
|
platform = os[:name]
|
106
106
|
|
107
|
+
return WindowsSrv.new(inspec) if os.windows?
|
108
|
+
|
107
109
|
# Ubuntu
|
108
110
|
# @see: https://wiki.ubuntu.com/SystemdForUpstartUsers
|
109
111
|
# Ubuntu 15.04 : Systemd
|
@@ -154,8 +156,6 @@ module Inspec::Resources
|
|
154
156
|
SysV.new(inspec, service_ctl)
|
155
157
|
when "mac_os_x"
|
156
158
|
LaunchCtl.new(inspec, service_ctl)
|
157
|
-
when "windows"
|
158
|
-
WindowsSrv.new(inspec)
|
159
159
|
when "freebsd"
|
160
160
|
BSDInit.new(inspec, service_ctl)
|
161
161
|
when "arch"
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require "hashie/mash"
|
2
|
+
require "inspec/resources/powershell"
|
2
3
|
|
3
4
|
module Inspec::Resources
|
4
5
|
class Virtualization < Inspec.resource(1)
|
5
6
|
name "virtualization"
|
6
7
|
supports platform: "unix"
|
8
|
+
supports platform: "windows"
|
7
9
|
desc "Use the virtualization InSpec audit resource to test various virtualization platforms."
|
8
10
|
example <<~EXAMPLE
|
9
11
|
describe virtualization do
|
@@ -25,7 +27,15 @@ module Inspec::Resources
|
|
25
27
|
def initialize
|
26
28
|
# TODO: no need for hashie here... in fact, no reason for a hash at all
|
27
29
|
@virtualization_data = Hashie::Mash.new
|
28
|
-
|
30
|
+
|
31
|
+
if inspec.os.linux?
|
32
|
+
collect_data_linux
|
33
|
+
elsif inspec.os.windows?
|
34
|
+
collect_data_windows
|
35
|
+
end
|
36
|
+
|
37
|
+
# Allows checking for non-virtualized systems as well
|
38
|
+
@virtualization_data[:physical] = @virtualization_data.empty?
|
29
39
|
end
|
30
40
|
|
31
41
|
# add helper methods for easy access of properties
|
@@ -36,6 +46,14 @@ module Inspec::Resources
|
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
49
|
+
def virtual_system?
|
50
|
+
@virtualization_data[:role] == "guest"
|
51
|
+
end
|
52
|
+
|
53
|
+
def physical_system?
|
54
|
+
@virtualization_data[:physical]
|
55
|
+
end
|
56
|
+
|
39
57
|
def params
|
40
58
|
# TODO: this is broken. cannot return anything but nil
|
41
59
|
collect_data_linux
|
@@ -236,6 +254,39 @@ module Inspec::Resources
|
|
236
254
|
true
|
237
255
|
end
|
238
256
|
|
257
|
+
# Detect VMware
|
258
|
+
def detect_vmware
|
259
|
+
return false unless inspec.file("/sys/devices/virtual/dmi/id/product_name").exist?
|
260
|
+
|
261
|
+
product_name = inspec.file("/sys/devices/virtual/dmi/id/product_name").content
|
262
|
+
|
263
|
+
if product_name =~ /^VMware/
|
264
|
+
@virtualization_data[:system] = "vmware"
|
265
|
+
@virtualization_data[:role] = "guest"
|
266
|
+
else
|
267
|
+
return false
|
268
|
+
end
|
269
|
+
|
270
|
+
true
|
271
|
+
end
|
272
|
+
|
273
|
+
# Detect Hyper-V
|
274
|
+
# @see https://gallery.technet.microsoft.com/scriptcenter/Get-MachineType-VM-or-ff43f3a9
|
275
|
+
def detect_hyperv
|
276
|
+
return false unless inspec.file("/sys/devices/virtual/dmi/id/product_name").exist?
|
277
|
+
|
278
|
+
product_name = inspec.file("/sys/devices/virtual/dmi/id/product_name").content
|
279
|
+
|
280
|
+
if product_name.rstrip == "Virtual Machine"
|
281
|
+
@virtualization_data[:system] = "hyper-v"
|
282
|
+
@virtualization_data[:role] = "guest"
|
283
|
+
else
|
284
|
+
return false
|
285
|
+
end
|
286
|
+
|
287
|
+
true
|
288
|
+
end
|
289
|
+
|
239
290
|
def collect_data_linux
|
240
291
|
# This avoids doing multiple detections in a single test
|
241
292
|
return unless @virtualization_data.empty?
|
@@ -253,7 +304,40 @@ module Inspec::Resources
|
|
253
304
|
return if detect_openvz
|
254
305
|
return if detect_openstack
|
255
306
|
return if detect_parallels
|
256
|
-
|
307
|
+
return if detect_vmware
|
308
|
+
return if detect_hyperv
|
309
|
+
end
|
310
|
+
|
311
|
+
def windows_computer_system
|
312
|
+
script = "Get-WmiObject -Class Win32_ComputerSystem -ErrorAction Stop | ConvertTo-Json"
|
313
|
+
cmd = inspec.powershell(script)
|
314
|
+
|
315
|
+
JSON.parse(cmd.stdout)
|
316
|
+
rescue JSON::ParserError => _e
|
317
|
+
nil
|
318
|
+
end
|
319
|
+
|
320
|
+
def collect_data_windows
|
321
|
+
# This avoids doing multiple detections in a single test
|
322
|
+
return unless @virtualization_data.empty?
|
323
|
+
|
324
|
+
case windows_computer_system["Model"]
|
325
|
+
when "Virtual Machine"
|
326
|
+
@virtualization_data[:system] = "hyper-v"
|
327
|
+
when /^VMware/
|
328
|
+
@virtualization_data[:system] = "vmware"
|
329
|
+
when "VirtualBox"
|
330
|
+
@virtualization_data[:system] = "virtualbox"
|
331
|
+
end
|
332
|
+
|
333
|
+
case windows_computer_system[:manufacturer]
|
334
|
+
when "Xen"
|
335
|
+
@virtualization_data[:system] = "xen"
|
336
|
+
when "QEMU"
|
337
|
+
@virtualization_data[:system] = "kvm"
|
338
|
+
end
|
339
|
+
|
340
|
+
@virtualization_data[:role] = "guest" if @virtualization_data[:system]
|
257
341
|
end
|
258
342
|
end
|
259
343
|
end
|
data/lib/inspec/version.rb
CHANGED
@@ -60,18 +60,19 @@ module InspecPlugins
|
|
60
60
|
# inspec plugin search
|
61
61
|
#==================================================================#
|
62
62
|
|
63
|
-
desc "search [options] PATTERN", "Searches
|
63
|
+
desc "search [options] PATTERN", "Searches for plugins."
|
64
64
|
long_desc <<~EOLD
|
65
|
-
Searches rubygems.org for #{PRODUCT_NAME} plugins. Exits 0 on a search hit, 1 on user error,
|
65
|
+
Searches rubygems.org or alternate source for #{PRODUCT_NAME} plugins. Exits 0 on a search hit, 1 on user error,
|
66
66
|
2 on a search miss. PATTERN is a simple string; a wildcard will be added as
|
67
67
|
a suffix, unless -e is used.
|
68
68
|
EOLD
|
69
69
|
option :all, desc: "List all available versions, not just the latest one.", type: :boolean, aliases: [:a]
|
70
70
|
option :exact, desc: "Assume PATTERN is exact; do not add a wildcard to the end", type: :boolean, aliases: [:e]
|
71
71
|
option :'include-test-fixture', type: :boolean, desc: "Internal use", hide: true
|
72
|
+
option :source, type: :string, desc: "URL of repository, defaults to https://rubygems.org", aliases: [:s]
|
72
73
|
# Justification for disabling ABC: currently at 33.51/33
|
73
74
|
def search(search_term) # rubocop: disable Metrics/AbcSize
|
74
|
-
search_results = installer.search(search_term, exact: options[:exact])
|
75
|
+
search_results = installer.search(search_term, exact: options[:exact], source: options[:source])
|
75
76
|
# The search results have already been filtered by the reject list. But the
|
76
77
|
# RejectList doesn't filter {inspec, train}-test-fixture because we need those
|
77
78
|
# for testing. We want to hide those from users, so unless we know we're in
|
@@ -102,9 +103,9 @@ module InspecPlugins
|
|
102
103
|
#==================================================================#
|
103
104
|
# inspec plugin install
|
104
105
|
#==================================================================#
|
105
|
-
desc "install [
|
106
|
+
desc "install [options] PLUGIN", "Installs a plugin from rubygems.org, a gemfile, or a path to local source."
|
106
107
|
long_desc <<~EOLD
|
107
|
-
PLUGIN may be the name of a gem on rubygems.org that begins with inspec
|
108
|
+
PLUGIN may be the name of a gem on rubygems.org (or an alternate source) that begins with `inspec-` or `train-`.
|
108
109
|
PLUGIN may also be the path to a local gemfile, which will then be installed like
|
109
110
|
any other gem. Finally, if PLUGIN is a path ending in .rb, it is taken to be a
|
110
111
|
local file that will act as athe entry point for a plugin (this mode is provided
|
@@ -112,6 +113,7 @@ module InspecPlugins
|
|
112
113
|
already installed, and 1 if any other error occurs.
|
113
114
|
EOLD
|
114
115
|
option :version, desc: "When installing from rubygems.org, specifies a specific version to install.", aliases: [:v]
|
116
|
+
option :source, type: :string, desc: "URL of repository, defaults to https://rubygems.org", aliases: [:s]
|
115
117
|
def install(plugin_id_arg)
|
116
118
|
if plugin_id_arg =~ /\.gem$/ # Does it end in .gem?
|
117
119
|
install_from_gemfile(plugin_id_arg)
|
@@ -407,7 +409,7 @@ module InspecPlugins
|
|
407
409
|
|
408
410
|
# Rationale for RuboCop variance: This is a one-line method with heavy UX-focused error handling.
|
409
411
|
def install_attempt_install(plugin_name) # rubocop: disable Metrics/AbcSize
|
410
|
-
installer.install(plugin_name, version: options[:version])
|
412
|
+
installer.install(plugin_name, version: options[:version], source: options[:source])
|
411
413
|
rescue Inspec::Plugin::V2::PluginExcludedError => ex
|
412
414
|
ui.red("Plugin on Exclusion List - #{plugin_name} is listed as an " \
|
413
415
|
"incompatible gem - refusing to install.\n")
|
@@ -422,12 +424,13 @@ module InspecPlugins
|
|
422
424
|
raise if Inspec::Log.level == :debug
|
423
425
|
|
424
426
|
results = installer.search(plugin_name, exact: true)
|
427
|
+
source_host = URI(options[:source] || "https://rubygems.org/").host
|
425
428
|
if results.empty?
|
426
429
|
ui.red("No such plugin gem #{plugin_name} could be found on " \
|
427
|
-
"
|
430
|
+
"#{source_host} - installation failed.\n")
|
428
431
|
elsif options[:version] && !results[plugin_name].include?(options[:version])
|
429
432
|
ui.red("No such version - #{plugin_name} exists, but no such " \
|
430
|
-
"version #{options[:version]} found on
|
433
|
+
"version #{options[:version]} found on #{source_host} - " \
|
431
434
|
"installation failed.\n")
|
432
435
|
else
|
433
436
|
ui.red("Unknown error occured - installation failed.\n")
|
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.18.
|
4
|
+
version: 4.18.104
|
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: 2020-
|
11
|
+
date: 2020-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-telemetry
|