inspec-core 4.56.19 → 5.12.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/etc/deprecations.json +12 -16
- data/inspec-core.gemspec +1 -1
- data/lib/inspec/base_cli.rb +14 -2
- data/lib/inspec/cli.rb +15 -0
- data/lib/inspec/dependency_installer.rb +74 -0
- data/lib/inspec/dependency_loader.rb +97 -0
- data/lib/inspec/dsl.rb +11 -2
- data/lib/inspec/errors.rb +7 -0
- data/lib/inspec/formatters/base.rb +23 -0
- data/lib/inspec/metadata.rb +36 -0
- data/lib/inspec/plugin/v2/installer.rb +9 -2
- data/lib/inspec/plugin/v2/loader.rb +13 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +44 -1
- data/lib/inspec/plugin/v2/status.rb +2 -1
- data/lib/inspec/profile.rb +63 -0
- data/lib/inspec/reporters/automate.rb +1 -1
- data/lib/inspec/reporters/cli.rb +1 -1
- data/lib/inspec/reporters/json.rb +31 -11
- data/lib/inspec/resource.rb +6 -0
- data/lib/inspec/resources/apt.rb +12 -6
- data/lib/inspec/resources/cgroup.rb +101 -0
- data/lib/inspec/resources/cron.rb +49 -0
- data/lib/inspec/resources/docker_container.rb +21 -0
- data/lib/inspec/resources/docker_image.rb +53 -0
- data/lib/inspec/resources/ipfilter.rb +59 -0
- data/lib/inspec/resources/ipnat.rb +58 -0
- data/lib/inspec/resources/lxc.rb +57 -0
- data/lib/inspec/resources/mail_alias.rb +46 -0
- data/lib/inspec/resources/routing_table.rb +137 -0
- data/lib/inspec/resources/service.rb +14 -1
- data/lib/inspec/resources/user.rb +12 -0
- data/lib/inspec/resources/users.rb +79 -14
- data/lib/inspec/resources/virtualization.rb +9 -3
- data/lib/inspec/resources.rb +3 -16
- data/lib/inspec/runner.rb +18 -1
- data/lib/inspec/runner_rspec.rb +15 -0
- data/lib/inspec/schema/exec_json.rb +59 -58
- data/lib/inspec/schema/exec_json_min.rb +16 -16
- data/lib/inspec/schema/primitives.rb +68 -51
- data/lib/inspec/schema/profile_json.rb +27 -27
- data/lib/inspec/schema.rb +1 -0
- data/lib/inspec/ui.rb +10 -0
- data/lib/inspec/utils/deprecated_cloud_resources_list.rb +54 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec.rb +3 -0
- data/lib/plugins/inspec-artifact/inspec-artifact.gemspec +9 -0
- data/lib/plugins/inspec-compliance/inspec-compliance.gemspec +9 -0
- data/lib/plugins/inspec-habitat/inspec-habitat.gemspec +9 -0
- data/lib/plugins/inspec-init/inspec-init.gemspec +9 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +9 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +126 -0
- data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +9 -8
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.erb +16 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/streaming_reporter.erb +31 -0
- data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
- data/lib/plugins/inspec-init/templates/resources/basic/docs/resource-doc.erb +77 -0
- data/lib/plugins/inspec-init/templates/resources/basic/libraries/inspec-resource-template.erb +94 -0
- data/lib/plugins/inspec-init/templates/resources/plural/docs/resource-doc.erb +62 -0
- data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb +73 -0
- data/lib/plugins/inspec-plugin-manager-cli/inspec-plugin-manager-cli.gemspec +10 -0
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +15 -11
- data/lib/plugins/inspec-reporter-html2/inspec-reporter-html2.gemspec +9 -0
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +2 -0
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +3 -0
- data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +1 -0
- data/lib/plugins/inspec-reporter-html2/templates/result.html.erb +1 -0
- data/lib/plugins/inspec-reporter-json-min/inspec-reporter-json-min.gemspec +9 -0
- data/lib/plugins/inspec-reporter-junit/inspec-reporter-junit.gemspec +9 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/README.md +5 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/inspec-streaming-reporter-progress-bar.gemspec +9 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/plugin.rb +13 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +123 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/version.rb +8 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar.rb +15 -0
- metadata +33 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7242aa89bb64084dbeb75587b128af25c4967be0bc06ec8e9d8f386e821d36a
|
4
|
+
data.tar.gz: 876166ebb7e7ae59bb39fe1b9fd4523f45cdb6c22702f08e0074dad4662bf5bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 155d7f957519b8358c1e8d92373f50b8839cb7f31ca3f32af953a556a2753f768b69b9a78dc7fa2b228ed30e2a26a5b33a393dbe472c501fcc1bda0b54a353f8
|
7
|
+
data.tar.gz: af8ec2a17788ba7add5c58c07c0e842b31e8a7a92f6afd38ca0e794c2d297dde6464e8dd9cf8d8a07374042a2437ec41685226be098004a4396160432d68a14f
|
data/etc/deprecations.json
CHANGED
@@ -17,9 +17,14 @@
|
|
17
17
|
"prefix": "Inputs should be specified by using the 'inputs' key in profile metadata, not 'attributes'."
|
18
18
|
},
|
19
19
|
"aws_resources_in_resource_pack": {
|
20
|
-
"comment": "
|
21
|
-
"action": "
|
22
|
-
"prefix": "AWS resources
|
20
|
+
"comment": "Deprecated in InSpec 5",
|
21
|
+
"action": "exit",
|
22
|
+
"prefix": "AWS resources in core InSpec are deprecated and have been removed in InSpec 5. They are now part of a resource pack. Please update your profiles to depend on git@github.com:inspec/inspec-aws.git ."
|
23
|
+
},
|
24
|
+
"azure_resources_in_resource_pack": {
|
25
|
+
"comment": "Deprecated in InSpec 5",
|
26
|
+
"action": "exit",
|
27
|
+
"prefix": "Azure resources in core InSpec are deprecated and have been removed in InSpec 5. They are now part of a resource pack. Please update your profiles to depend on git@github.com:inspec/inspec-azure.git ."
|
23
28
|
},
|
24
29
|
"cli_option_json_config": {
|
25
30
|
"action": "ignore",
|
@@ -55,10 +60,6 @@
|
|
55
60
|
"action": "fail_control",
|
56
61
|
"suffix": "This property was removed in InSpec 4.0."
|
57
62
|
},
|
58
|
-
"properties_aws_iam_user": {
|
59
|
-
"action": "fail_control",
|
60
|
-
"suffix": "This property was removed in InSpec 4.0."
|
61
|
-
},
|
62
63
|
"properties_shadow": {
|
63
64
|
"action": "fail_control",
|
64
65
|
"suffix": "This property was removed in InSpec 4.0."
|
@@ -72,10 +73,6 @@
|
|
72
73
|
"action": "exit",
|
73
74
|
"suffix": "This resource was removed in InSpec 4.0."
|
74
75
|
},
|
75
|
-
"resource_azure_generic_resource": {
|
76
|
-
"action": "warn",
|
77
|
-
"prefix": "The azure_generic_resource is deprecated. Please use a specific resource. See: 'https://github.com/inspec/inspec/issues/3131'"
|
78
|
-
},
|
79
76
|
"resource_iis_website": {
|
80
77
|
"action": "exit",
|
81
78
|
"suffix": "This resource was removed in InSpec 4.0.",
|
@@ -86,11 +83,6 @@
|
|
86
83
|
"suffix": "This resource was removed in InSpec 4.0.",
|
87
84
|
"comment": "Needed for ServerSpec compatibility"
|
88
85
|
},
|
89
|
-
"resource_ppa": {
|
90
|
-
"action": "exit",
|
91
|
-
"suffix": "This resource was removed in InSpec 4.0.",
|
92
|
-
"comment": "Needed for ServerSpec compatibility"
|
93
|
-
},
|
94
86
|
"resource_script": {
|
95
87
|
"action": "exit",
|
96
88
|
"suffix": "This resource will be removed in InSpec 4.0"
|
@@ -125,6 +117,10 @@
|
|
125
117
|
"action": "warn",
|
126
118
|
"prefix": "The --hook option is being replaced by the --activator option.",
|
127
119
|
"suffix": "This options will be removed in InSpec 4.0."
|
120
|
+
},
|
121
|
+
"cli_option_target_id":{
|
122
|
+
"action": "warn",
|
123
|
+
"prefix": "The --target-id option is deprecated in InSpec 5. Its value will be ignored."
|
128
124
|
}
|
129
125
|
}
|
130
126
|
}
|
data/inspec-core.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.license = "Apache-2.0"
|
14
14
|
spec.require_paths = ["lib"]
|
15
15
|
|
16
|
-
spec.required_ruby_version = ">= 2.
|
16
|
+
spec.required_ruby_version = ">= 2.7"
|
17
17
|
|
18
18
|
# the gemfile and gemspec are necessary for appbundler so don't remove it
|
19
19
|
spec.files =
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -99,8 +99,18 @@ module Inspec
|
|
99
99
|
desc: "Specify a particular shell to use."
|
100
100
|
option :ssl, type: :boolean,
|
101
101
|
desc: "Use SSL for transport layer encryption (WinRM)."
|
102
|
+
option :ssl_peer_fingerprint, type: :string,
|
103
|
+
desc: "Specify peer fingerprint for SSL authentication, used in lieu of certificates"
|
102
104
|
option :self_signed, type: :boolean,
|
103
105
|
desc: "Allow remote scans with self-signed certificates (WinRM)."
|
106
|
+
option :ca_trust_file, type: :string,
|
107
|
+
desc: "Specify CA trust file for SSL authentication"
|
108
|
+
option :client_cert, type: :string,
|
109
|
+
desc: "Specify client certificate for SSL authentication"
|
110
|
+
option :client_key, type: :string,
|
111
|
+
desc: "Specify client key required with client cert for SSL authentication"
|
112
|
+
option :client_key_pass, type: :string, lazy_default: -1,
|
113
|
+
desc: "Specify client cert password, if required for SSL authentication"
|
104
114
|
option :winrm_transport, type: :string, default: "negotiate",
|
105
115
|
desc: "Specify which transport to use, defaults to negotiate (WinRM)."
|
106
116
|
option :winrm_disable_sspi, type: :boolean,
|
@@ -121,7 +131,7 @@ module Inspec
|
|
121
131
|
option :insecure, type: :boolean, default: false,
|
122
132
|
desc: "Disable SSL verification on select targets"
|
123
133
|
option :target_id, type: :string,
|
124
|
-
desc: "Provide a ID which will be included on reports"
|
134
|
+
desc: "Provide a ID which will be included on reports - deprecated"
|
125
135
|
option :winrm_shell_type, type: :string, default: "powershell",
|
126
136
|
desc: "Specify a shell type for winrm (eg. 'elevated' or 'powershell')"
|
127
137
|
option :docker_url, type: :string,
|
@@ -135,6 +145,8 @@ module Inspec
|
|
135
145
|
desc: "Folder which contains referenced profiles."
|
136
146
|
option :vendor_cache, type: :string,
|
137
147
|
desc: "Use the given path for caching dependencies. (default: ~/.inspec/cache)"
|
148
|
+
option :auto_install_gems, type: :boolean, default: false,
|
149
|
+
desc: "Auto installs gem dependencies of the profile or resource pack."
|
138
150
|
end
|
139
151
|
|
140
152
|
def self.supermarket_options
|
@@ -152,7 +164,7 @@ module Inspec
|
|
152
164
|
desc: "A list of tags names that are part of controls to filter and run controls, or a list of /regexes/ to match against tags names of controls. Ignore all other tests."
|
153
165
|
option :reporter, type: :array,
|
154
166
|
banner: "one two:/output/file/path",
|
155
|
-
desc: "Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml"
|
167
|
+
desc: "Enable one or more output reporters: cli, documentation, html, progress, progress-bar, json, json-min, json-rspec, junit, yaml"
|
156
168
|
option :reporter_message_truncation, type: :string,
|
157
169
|
desc: "Number of characters to truncate failure messages and code_desc in report data to (default: no truncation)"
|
158
170
|
option :reporter_backtrace_inclusion, type: :boolean,
|
data/lib/inspec/cli.rb
CHANGED
@@ -201,6 +201,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
201
201
|
vendor_deps(path, vendor_options)
|
202
202
|
|
203
203
|
profile = Inspec::Profile.for_target(path, o)
|
204
|
+
gem_deps = profile.metadata.gem_dependencies + \
|
205
|
+
profile.locked_dependencies.list.map { |_k, v| v.profile.metadata.gem_dependencies }.flatten
|
206
|
+
unless gem_deps.empty?
|
207
|
+
o[:logger].warn "Archiving a profile that contains gem dependencies, but InSpec cannot package gems with the profile! Please archive your ~/.inspec/gems directory separately."
|
208
|
+
end
|
209
|
+
|
204
210
|
result = profile.check
|
205
211
|
|
206
212
|
if result && !o[:ignore_errors] == false
|
@@ -296,6 +302,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
296
302
|
def exec(*targets)
|
297
303
|
o = config
|
298
304
|
diagnose(o)
|
305
|
+
deprecate_target_id(config)
|
299
306
|
configure_logger(o)
|
300
307
|
|
301
308
|
runner = Inspec::Runner.new(o)
|
@@ -314,6 +321,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
314
321
|
option :format, type: :string
|
315
322
|
def detect
|
316
323
|
o = config
|
324
|
+
deprecate_target_id(config)
|
317
325
|
o[:command] = "platform.params"
|
318
326
|
|
319
327
|
configure_logger(o)
|
@@ -354,6 +362,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
354
362
|
desc: "Specify one or more inputs directly on the command line to the shell, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
|
355
363
|
def shell_func
|
356
364
|
o = config
|
365
|
+
deprecate_target_id(config)
|
357
366
|
diagnose(o)
|
358
367
|
o[:debug_shell] = true
|
359
368
|
|
@@ -441,6 +450,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
441
450
|
|
442
451
|
private
|
443
452
|
|
453
|
+
def deprecate_target_id(config)
|
454
|
+
unless config[:target_id].nil?
|
455
|
+
Inspec.deprecate "cli_option_target_id"
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
444
459
|
def run_command(opts)
|
445
460
|
runner = Inspec::Runner.new(Inspec::Config.new(opts))
|
446
461
|
res = runner.eval_with_virtual_profile(opts[:command])
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# This class will install the gem depedencies for profiles etc.
|
2
|
+
# The basic things which is required to install dependencies is the gem path where gem needs to be installed
|
3
|
+
# and the list of gems needs to be installed.
|
4
|
+
require "rubygems/remote_fetcher"
|
5
|
+
require "forwardable" unless defined?(Forwardable)
|
6
|
+
|
7
|
+
module Inspec
|
8
|
+
class DependencyInstaller
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
attr_reader :gem_path, :requested_gems, :dependency_loader
|
12
|
+
|
13
|
+
def_delegator :dependency_loader, :inspec_gem_path
|
14
|
+
|
15
|
+
def initialize(gem_path = nil, requested_gems = [])
|
16
|
+
@dependency_loader = Inspec::DependencyLoader.new
|
17
|
+
@gem_path = gem_path || inspec_gem_path
|
18
|
+
@requested_gems = requested_gems
|
19
|
+
end
|
20
|
+
|
21
|
+
def install
|
22
|
+
requested_gems.each do |requested_gem|
|
23
|
+
version = requested_gem[:version].nil? ? "> 0" : requested_gem[:version]
|
24
|
+
install_from_remote_gems(requested_gem[:name], { version: version })
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def install_from_remote_gems(requested_gem_name, opts)
|
31
|
+
version = opts[:version].split(",")
|
32
|
+
begin
|
33
|
+
gem_dependency = Gem::Dependency.new(requested_gem_name, version || "> 0")
|
34
|
+
|
35
|
+
# BestSet is rubygems.org API + indexing, APISet is for custom sources
|
36
|
+
sources = if opts[:source]
|
37
|
+
Gem::Resolver::APISet.new(URI.join(opts[:source] + "/api/v1/dependencies"))
|
38
|
+
else
|
39
|
+
Gem::Resolver::BestSet.new
|
40
|
+
end
|
41
|
+
|
42
|
+
install_gem_to_gems_dir(gem_dependency, [sources], opts[:update_mode])
|
43
|
+
rescue Gem::RemoteFetcher::FetchError => gem_ex
|
44
|
+
ex = Inspec::GemDependencyInstallError.new(gem_ex.message)
|
45
|
+
ex.gem_name = requested_gem_name
|
46
|
+
raise ex
|
47
|
+
rescue Gem::Requirement::BadRequirementError => gem_ex
|
48
|
+
ex = Inspec::GemDependencyInstallError.new(gem_ex.message)
|
49
|
+
ex.gem_name = requested_gem_name
|
50
|
+
raise "Unparseable gem dependency '#{version}' for '#{ex.gem_name}'"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def install_gem_to_gems_dir(gem_dependency, extra_request_sets = [], update_mode = false)
|
55
|
+
# Solve the dependency (that is, find a way to install the new gem and anything it needs)
|
56
|
+
request_set = Gem::RequestSet.new(gem_dependency)
|
57
|
+
|
58
|
+
begin
|
59
|
+
solution = request_set.resolve
|
60
|
+
rescue Gem::UnsatisfiableDependencyError => gem_ex
|
61
|
+
ex = Inspec::GemDependencyInstallError.new(gem_ex.message)
|
62
|
+
ex.gem_name = gem_dependency.name
|
63
|
+
raise ex
|
64
|
+
end
|
65
|
+
|
66
|
+
# OK, perform the installation.
|
67
|
+
# Ignore deps here, because any needed deps should already be baked into gem_dependency
|
68
|
+
request_set.install_into(gem_path, true, ignore_dependencies: true, document: [])
|
69
|
+
|
70
|
+
# Locate the GemVersion for the new dependency and return it
|
71
|
+
solution.detect { |g| g.name == gem_dependency.name }.version
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# This class will load the gem depedencies for profiles etc.
|
2
|
+
# The basic things which is required to load gem dependencies is the path from which gems needs to be loaded
|
3
|
+
# and the list of gems needs to be loaded.
|
4
|
+
|
5
|
+
module Inspec
|
6
|
+
class DependencyLoader
|
7
|
+
attr_accessor :gem_path, :gem_list
|
8
|
+
|
9
|
+
# initializes the dependency_loader
|
10
|
+
def initialize(gem_path = nil, gem_list = [])
|
11
|
+
@gem_path = gem_path || inspec_gem_path
|
12
|
+
@gem_list = gem_list
|
13
|
+
end
|
14
|
+
|
15
|
+
def load
|
16
|
+
Gem.path << gem_path
|
17
|
+
Gem.refresh
|
18
|
+
|
19
|
+
gem_list.each do |gem_data|
|
20
|
+
version = gem_data[:version].nil? ? "> 0" : gem_data[:version]
|
21
|
+
activate_gem_dependency(gem_data[:name], version)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def inspec_gem_path
|
26
|
+
self.class.inspec_gem_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.inspec_gem_path
|
30
|
+
require "rbconfig" unless defined?(RbConfig)
|
31
|
+
ruby_abi_version = RbConfig::CONFIG["ruby_version"]
|
32
|
+
# TODO: why are we installing under the api directory for plugins?
|
33
|
+
base_dir = Inspec.config_dir
|
34
|
+
base_dir = File.realpath base_dir if File.exist? base_dir
|
35
|
+
File.join(base_dir, "gems", ruby_abi_version)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Lists all gems found in the inspec_gem_path.
|
39
|
+
# @return [Array[Gem::Specification]] Specs of all gems found.
|
40
|
+
def list_managed_gems
|
41
|
+
Dir.glob(File.join(gem_path, "specifications", "*.gemspec")).map { |p| Gem::Specification.load(p) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def list_installed_gems
|
45
|
+
list_managed_gems
|
46
|
+
end
|
47
|
+
|
48
|
+
def gem_installed?(name)
|
49
|
+
list_installed_gems.any? { |spec| spec.name == name }
|
50
|
+
end
|
51
|
+
|
52
|
+
def gem_version_installed?(name, version)
|
53
|
+
list_installed_gems.any? { |s| s.name == name && Gem::Requirement.new(version.split(",")) =~ s.version }
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def activate_gem_dependency(name, version_constraint = "> 0")
|
59
|
+
version_constraint = version_constraint.split(",")
|
60
|
+
gem_deps = [Gem::Dependency.new(name.to_s, version_constraint)]
|
61
|
+
managed_gem_set = Gem::Resolver::VendorSet.new
|
62
|
+
|
63
|
+
# Note: There is an issue in resolving gem dependency.
|
64
|
+
# This block resolves that issue partially.
|
65
|
+
# But this will still fail for the gems which don't have the .gemspec file.
|
66
|
+
# TODO: Find the solution to resolve gem dependencies that work for the unpackaged gems which don't have the .gemspec file.
|
67
|
+
list_managed_gems.each do |spec|
|
68
|
+
unless Dir["#{spec.gem_dir}/*.gemspec"].empty?
|
69
|
+
managed_gem_set.add_vendor_gem(spec.name, spec.gem_dir)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# TODO: Next two lines merge our managed gems with the other gems available
|
74
|
+
# in our "local universe" - which may be the system, or it could be in a Bundler microcosm,
|
75
|
+
# or rbenv, etc. Do we want to merge that, though?
|
76
|
+
distrib_gem_set = Gem::Resolver::CurrentSet.new
|
77
|
+
installed_gem_set = Gem::Resolver.compose_sets(managed_gem_set, distrib_gem_set)
|
78
|
+
|
79
|
+
# So, given what we need, and what we have available, what activations are needed?
|
80
|
+
resolver = Gem::Resolver.new(gem_deps, installed_gem_set)
|
81
|
+
|
82
|
+
begin
|
83
|
+
solution = resolver.resolve
|
84
|
+
rescue Gem::UnsatisfiableDependencyError => gem_ex
|
85
|
+
# If you broke your install, or downgraded to a plugin with a bad gemspec, you could get here.
|
86
|
+
ex = Inspec::GemDependencyLoadError.new(gem_ex.message)
|
87
|
+
raise ex
|
88
|
+
end
|
89
|
+
solution.each do |activation_request|
|
90
|
+
next if activation_request.full_spec.activated?
|
91
|
+
|
92
|
+
activation_request.full_spec.activate
|
93
|
+
# TODO: If we are under Bundler, inform it that we loaded a gem
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/inspec/dsl.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# copyright: 2015, Dominik Richter
|
2
2
|
require "inspec/log"
|
3
3
|
require "inspec/plugin/v2"
|
4
|
+
require "inspec/utils/deprecated_cloud_resources_list"
|
4
5
|
|
5
6
|
module Inspec::DSL
|
6
7
|
attr_accessor :backend
|
@@ -38,8 +39,16 @@ module Inspec::DSL
|
|
38
39
|
|
39
40
|
begin
|
40
41
|
require "inspec/resources/#{id}"
|
41
|
-
rescue LoadError
|
42
|
-
|
42
|
+
rescue LoadError => e
|
43
|
+
include DeprecatedCloudResourcesList
|
44
|
+
cloud_resource = id.start_with?("aws_") ? "aws" : "azure"
|
45
|
+
|
46
|
+
# Deprecated AWS and Azure resources in InSpec 5.
|
47
|
+
if CLOUD_RESOURCES_DEPRECATED.include? id
|
48
|
+
Inspec.deprecate(:"#{cloud_resource}_resources_in_resource_pack", "Resource '#{id}'")
|
49
|
+
else
|
50
|
+
raise LoadError, "#{e.message}"
|
51
|
+
end
|
43
52
|
end
|
44
53
|
|
45
54
|
klass = Inspec::Resource.registry[id.to_s]
|
data/lib/inspec/errors.rb
CHANGED
@@ -15,4 +15,11 @@ module Inspec
|
|
15
15
|
class ConfigError::Invalid < ConfigError; end
|
16
16
|
|
17
17
|
class UserInteractionRequired < Error; end
|
18
|
+
|
19
|
+
class GemDependencyLoadError < Error; end
|
20
|
+
|
21
|
+
class GemDependencyInstallError < Error
|
22
|
+
attr_accessor :gem_name
|
23
|
+
attr_accessor :version
|
24
|
+
end
|
18
25
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "rspec/core"
|
2
2
|
require "rspec/core/formatters/base_formatter"
|
3
|
+
require "set" unless defined?(Set)
|
3
4
|
|
4
5
|
module Inspec::Formatters
|
5
6
|
class Base < RSpec::Core::Formatters::BaseFormatter
|
@@ -14,6 +15,8 @@ module Inspec::Formatters
|
|
14
15
|
@profiles = []
|
15
16
|
@profiles_info = nil
|
16
17
|
@backend = nil
|
18
|
+
@all_controls_count = nil
|
19
|
+
@control_checks_count_map = {}
|
17
20
|
end
|
18
21
|
|
19
22
|
# RSpec Override: #dump_summary
|
@@ -80,6 +83,26 @@ module Inspec::Formatters
|
|
80
83
|
@profiles.push(profile)
|
81
84
|
end
|
82
85
|
|
86
|
+
# These control count related methods are called via runner rspec library of inspec
|
87
|
+
# And these are used within streaming plugins to determine end of control
|
88
|
+
######### Start of control count related methods
|
89
|
+
def set_controls_count(controls_count)
|
90
|
+
@all_controls_count = controls_count
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_control_checks_count_map(mapping)
|
94
|
+
@control_checks_count_map = mapping
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_controls_count
|
98
|
+
@all_controls_count
|
99
|
+
end
|
100
|
+
|
101
|
+
def get_control_checks_count_map
|
102
|
+
@control_checks_count_map
|
103
|
+
end
|
104
|
+
######### end of control count related methods
|
105
|
+
|
83
106
|
# Return all the collected output to the caller
|
84
107
|
def results
|
85
108
|
run_data
|
data/lib/inspec/metadata.rb
CHANGED
@@ -41,6 +41,7 @@ module Inspec
|
|
41
41
|
description
|
42
42
|
version
|
43
43
|
inspec_version
|
44
|
+
entitlement_id
|
44
45
|
}.each do |name|
|
45
46
|
define_method name.to_sym do |arg|
|
46
47
|
params[name.to_sym] = arg
|
@@ -51,6 +52,10 @@ module Inspec
|
|
51
52
|
params[:depends] || []
|
52
53
|
end
|
53
54
|
|
55
|
+
def gem_dependencies
|
56
|
+
params[:gem_dependencies] || []
|
57
|
+
end
|
58
|
+
|
54
59
|
def supports(sth, version = nil)
|
55
60
|
# Ignore supports with metadata.rb. This file is legacy and the way it
|
56
61
|
# it handles `supports` deprecated. A deprecation warning will be printed
|
@@ -94,6 +99,10 @@ module Inspec
|
|
94
99
|
errors.push("Version needs to be in SemVer format")
|
95
100
|
end
|
96
101
|
|
102
|
+
if params[:entitlement_id] && params[:entitlement_id].strip.empty?
|
103
|
+
errors.push("Entitlement ID should not be blank.")
|
104
|
+
end
|
105
|
+
|
97
106
|
unless supports_runtime?
|
98
107
|
warnings.push("The current inspec version #{Inspec::VERSION} cannot satisfy profile inspec_version constraint #{params[:inspec_version]}")
|
99
108
|
end
|
@@ -109,6 +118,33 @@ module Inspec
|
|
109
118
|
warnings.push("License '#{params[:license]}' needs to be in SPDX format or marked as 'Proprietary'. See https://spdx.org/licenses/.")
|
110
119
|
end
|
111
120
|
|
121
|
+
# If gem_dependencies is set, it must be an array of hashes with keys name and optional version
|
122
|
+
unless params[:gem_dependencies].nil?
|
123
|
+
list = params[:gem_dependencies]
|
124
|
+
if list.is_a?(Array) && list.all? { |e| e.is_a? Hash }
|
125
|
+
list.each do |entry|
|
126
|
+
errors.push("gem_dependencies entries must all have a 'name' field") unless entry.key?(:name)
|
127
|
+
if entry[:version]
|
128
|
+
orig = entry[:version]
|
129
|
+
begin
|
130
|
+
# Split on commas as we may have a complex dep
|
131
|
+
orig.split(",").map { |c| Gem::Requirement.parse(c) }
|
132
|
+
rescue Gem::Requirement::BadRequirementError
|
133
|
+
errors.push "Unparseable gem dependency '#{orig}' for #{entry[:name]}"
|
134
|
+
rescue Inspec::GemDependencyInstallError => e
|
135
|
+
errors.push e.message
|
136
|
+
end
|
137
|
+
end
|
138
|
+
extra = (entry.keys - %i{name version})
|
139
|
+
unless extra.empty?
|
140
|
+
warnings.push "Unknown gem_dependencies key(s) #{extra.join(",")} seen for entry '#{entry[:name]}'"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
else
|
144
|
+
errors.push("gem_dependencies must be a List of Hashes")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
112
148
|
[errors, warnings]
|
113
149
|
end
|
114
150
|
|
@@ -149,12 +149,19 @@ module Inspec::Plugin::V2
|
|
149
149
|
|
150
150
|
gem_info = {}
|
151
151
|
matched_tuples.each do |tuple|
|
152
|
-
gem_info[tuple.first.name] ||=
|
153
|
-
gem_info[tuple.first.name]
|
152
|
+
gem_info[tuple.first.name] ||= {}
|
153
|
+
gem_info[tuple.first.name]["versions"] ||= []
|
154
|
+
gem_info[tuple.first.name]["versions"] << tuple.first.version.to_s
|
155
|
+
gem_info[tuple.first.name]["description"] ||= fetch_plugin_specs(fetcher, tuple.first.name)&.summary
|
154
156
|
end
|
155
157
|
gem_info
|
156
158
|
end
|
157
159
|
|
160
|
+
def fetch_plugin_specs(fetcher, gem_name)
|
161
|
+
plugin_dependency = Gem::Dependency.new(gem_name)
|
162
|
+
fetcher.spec_for_dependency(plugin_dependency).flatten.first
|
163
|
+
end
|
164
|
+
|
158
165
|
# Testing API. Performs a hard reset on the installer and registry, and reloads the loader.
|
159
166
|
# Not for public use.
|
160
167
|
# TODO: bad timing coupling in tests
|
@@ -259,10 +259,15 @@ module Inspec::Plugin::V2
|
|
259
259
|
status.entry_point = File.join(plugin_dir, "lib", status.name.to_s + ".rb")
|
260
260
|
status.installation_type = :core
|
261
261
|
status.loaded = false
|
262
|
+
status.description = fetch_gemspec(File.join(plugin_dir, status.name.to_s + ".gemspec"))&.summary
|
262
263
|
registry[status.name.to_sym] = status
|
263
264
|
end
|
264
265
|
end
|
265
266
|
|
267
|
+
def fetch_gemspec(spec_file)
|
268
|
+
Gem::Specification.load(spec_file)
|
269
|
+
end
|
270
|
+
|
266
271
|
def read_conf_file_into_registry
|
267
272
|
conf_file.each do |plugin_entry|
|
268
273
|
status = Inspec::Plugin::V2::Status.new
|
@@ -273,6 +278,7 @@ module Inspec::Plugin::V2
|
|
273
278
|
when :user_gem
|
274
279
|
status.entry_point = status.name.to_s
|
275
280
|
status.version = plugin_entry[:version]
|
281
|
+
status.description = fetch_plugin_specs(status.name.to_s)&.summary
|
276
282
|
when :path
|
277
283
|
status.entry_point = plugin_entry[:installation_path]
|
278
284
|
end
|
@@ -281,6 +287,12 @@ module Inspec::Plugin::V2
|
|
281
287
|
end
|
282
288
|
end
|
283
289
|
|
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
|
+
|
284
296
|
def fixup_train_plugin_status(status)
|
285
297
|
status.api_generation = :'train-1'
|
286
298
|
if status.installation_type == :user_gem
|
@@ -327,6 +339,7 @@ module Inspec::Plugin::V2
|
|
327
339
|
status.version = plugin_spec.version.to_s
|
328
340
|
status.loaded = false
|
329
341
|
status.installation_type = :system_gem
|
342
|
+
status.description = plugin_spec.summary
|
330
343
|
|
331
344
|
if train_plugin_name?(status[:name])
|
332
345
|
# Train plugins are not true InSpec plugins; we need to decorate them a
|
@@ -1,10 +1,53 @@
|
|
1
1
|
module Inspec::Plugin::V2::PluginType
|
2
|
-
class StreamingReporter < Inspec::Plugin::V2::PluginBase
|
2
|
+
class StreamingReporter < Inspec::Plugin::V2::PluginBase
|
3
3
|
register_plugin_type(:streaming_reporter)
|
4
4
|
|
5
5
|
#====================================================================#
|
6
6
|
# StreamingReporter plugin type API
|
7
7
|
#====================================================================#
|
8
8
|
# Implementation classes must implement these methods.
|
9
|
+
|
10
|
+
def initialize_streaming_reporter
|
11
|
+
@running_controls_list = []
|
12
|
+
@control_checks_count_map = {}
|
13
|
+
@controls_count = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# method to identify when the control started running
|
19
|
+
# this will be useful in executing operations on control's level start
|
20
|
+
def control_started?(control_id)
|
21
|
+
if @running_controls_list.include? control_id
|
22
|
+
false
|
23
|
+
else
|
24
|
+
@running_controls_list.push(control_id)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# method to identify when the control ended running
|
30
|
+
# this will be useful in executing operations on control's level end
|
31
|
+
def control_ended?(control_id)
|
32
|
+
set_control_checks_count_map_value
|
33
|
+
unless @control_checks_count_map[control_id].nil?
|
34
|
+
@control_checks_count_map[control_id] -= 1
|
35
|
+
@control_checks_count_map[control_id] == 0
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# method to identify total no. of controls
|
42
|
+
def controls_count
|
43
|
+
@controls_count ||= RSpec.configuration.formatters.grep(Inspec::Formatters::Base).first.get_controls_count
|
44
|
+
end
|
45
|
+
|
46
|
+
# this method is used in the logic of determining end of control
|
47
|
+
def set_control_checks_count_map_value
|
48
|
+
if @control_checks_count_map.empty?
|
49
|
+
@control_checks_count_map = RSpec.configuration.formatters.grep(Inspec::Formatters::Base).first.get_control_checks_count_map
|
50
|
+
end
|
51
|
+
end
|
9
52
|
end
|
10
53
|
end
|
@@ -14,7 +14,8 @@ module Inspec::Plugin::V2
|
|
14
14
|
:loaded, # true, false False could mean not attempted or failed
|
15
15
|
:load_exception, # Exception class if it failed to load
|
16
16
|
:name, # String name
|
17
|
-
:version
|
17
|
+
:version, # three-digit version. Core / bundled plugins use InSpec version here.
|
18
|
+
:description # Description of plugin.
|
18
19
|
) do
|
19
20
|
def initialize(*)
|
20
21
|
super
|