inspec 4.16.0 → 4.17.7
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.rb +0 -1
- data/lib/inspec/backend.rb +7 -0
- data/lib/inspec/base_cli.rb +2 -0
- data/lib/inspec/cli.rb +3 -10
- data/lib/inspec/config.rb +3 -4
- data/lib/inspec/control_eval_context.rb +5 -3
- data/lib/inspec/dsl.rb +24 -1
- data/lib/inspec/errors.rb +0 -26
- data/lib/inspec/file_provider.rb +33 -43
- data/lib/inspec/formatters/base.rb +1 -0
- data/lib/inspec/impact.rb +2 -0
- data/lib/inspec/input.rb +410 -0
- data/lib/inspec/input_registry.rb +10 -1
- data/lib/inspec/objects.rb +3 -1
- data/lib/inspec/objects/input.rb +5 -387
- data/lib/inspec/objects/tag.rb +1 -1
- data/lib/inspec/plugin/v1/plugin_types/resource.rb +16 -5
- data/lib/inspec/plugin/v2/activator.rb +4 -8
- data/lib/inspec/plugin/v2/loader.rb +19 -3
- data/lib/inspec/profile.rb +1 -1
- data/lib/inspec/profile_context.rb +1 -1
- data/lib/inspec/reporters/json.rb +70 -88
- data/lib/inspec/resource.rb +1 -0
- data/lib/inspec/resources.rb +9 -2
- data/lib/inspec/resources/aide_conf.rb +4 -0
- data/lib/inspec/resources/apt.rb +19 -19
- data/lib/inspec/resources/etc_fstab.rb +4 -0
- data/lib/inspec/resources/etc_hosts.rb +4 -0
- data/lib/inspec/resources/firewalld.rb +4 -0
- data/lib/inspec/resources/json.rb +10 -3
- data/lib/inspec/resources/mssql_session.rb +1 -1
- data/lib/inspec/resources/platform.rb +18 -13
- data/lib/inspec/resources/postfix_conf.rb +6 -2
- data/lib/inspec/resources/security_identifier.rb +4 -0
- data/lib/inspec/resources/sys_info.rb +65 -4
- data/lib/inspec/resources/user.rb +1 -0
- data/lib/inspec/rule.rb +68 -6
- data/lib/inspec/runner.rb +6 -1
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/shell.rb +8 -1
- data/lib/inspec/utils/pkey_reader.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +2 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/help_test.rb +23 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/helper.rb +62 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/install_test.rb +368 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/list_test.rb +101 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/search_test.rb +129 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/uninstall_test.rb +63 -0
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/update_test.rb +84 -0
- metadata +11 -3
- data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +0 -845
@@ -31,8 +31,10 @@ module Inspec
|
|
31
31
|
def supports(criteria = nil)
|
32
32
|
return if criteria.nil?
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
key = @name.to_sym
|
35
|
+
|
36
|
+
Inspec::Resource.supports[key] ||= []
|
37
|
+
Inspec::Resource.supports[key].push(criteria)
|
36
38
|
end
|
37
39
|
|
38
40
|
def example(example = nil)
|
@@ -80,14 +82,22 @@ module Inspec
|
|
80
82
|
def initialize(backend, name, *args)
|
81
83
|
@resource_skipped = false
|
82
84
|
@resource_failed = false
|
83
|
-
@supports = Inspec::Resource.supports[name]
|
85
|
+
@supports = Inspec::Resource.supports[name.to_sym]
|
84
86
|
@resource_exception_message = nil
|
85
87
|
|
86
88
|
# attach the backend to this instance
|
87
89
|
@__backend_runner__ = backend
|
88
90
|
@__resource_name__ = name
|
89
91
|
|
90
|
-
|
92
|
+
# check resource supports
|
93
|
+
supported = @supports ? check_supports : true # check_supports has side effects!
|
94
|
+
test_backend = defined?(Train::Transports::Mock::Connection) && backend.backend.class == Train::Transports::Mock::Connection
|
95
|
+
# raise unless we are supported or in test
|
96
|
+
unless supported || test_backend
|
97
|
+
msg = "Unsupported resource/backend combination: %s / %s. Exiting." %
|
98
|
+
[name, backend.platform.name]
|
99
|
+
raise ArgumentError, msg
|
100
|
+
end
|
91
101
|
|
92
102
|
# call the resource initializer
|
93
103
|
begin
|
@@ -116,6 +126,7 @@ module Inspec
|
|
116
126
|
end
|
117
127
|
|
118
128
|
def check_supports
|
129
|
+
require "inspec/resources/platform"
|
119
130
|
status = inspec.platform.supported?(@supports)
|
120
131
|
fail_msg = "Resource `#{@__resource_name__}` is not supported on platform #{inspec.platform.name}/#{inspec.platform.release}."
|
121
132
|
fail_resource(fail_msg) unless status
|
@@ -157,7 +168,7 @@ module Inspec
|
|
157
168
|
end
|
158
169
|
|
159
170
|
module Plugins
|
160
|
-
class Resource
|
171
|
+
class Resource # TODO: possibly push up to inspec/resource.rb
|
161
172
|
extend Inspec::ResourceDSL
|
162
173
|
include Inspec::ResourceBehaviors
|
163
174
|
end
|
@@ -3,21 +3,17 @@ module Inspec::Plugin::V2
|
|
3
3
|
:plugin_name,
|
4
4
|
:plugin_type,
|
5
5
|
:activator_name,
|
6
|
-
:activated
|
6
|
+
:activated,
|
7
7
|
:exception,
|
8
8
|
:activation_proc,
|
9
9
|
:implementation_class
|
10
10
|
) do
|
11
11
|
def initialize(*)
|
12
12
|
super
|
13
|
-
self[:
|
13
|
+
self[:activated] = false
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
return self[:activated?] if new_value.nil?
|
18
|
-
|
19
|
-
self[:activated?] = new_value
|
20
|
-
end
|
16
|
+
alias activated? activated
|
21
17
|
|
22
18
|
# Load a plugin, but if an error is encountered, store it and continue
|
23
19
|
def activate
|
@@ -26,7 +22,7 @@ module Inspec::Plugin::V2
|
|
26
22
|
# rubocop: disable Lint/RescueException
|
27
23
|
begin
|
28
24
|
impl_class = self[:activation_proc].call
|
29
|
-
self
|
25
|
+
self.activated = true
|
30
26
|
self[:implementation_class] = impl_class
|
31
27
|
rescue Exception => ex
|
32
28
|
self[:exception] = ex
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "inspec/log"
|
2
|
+
require "inspec/version"
|
2
3
|
require "inspec/plugin/v2/config_file"
|
3
4
|
require "inspec/plugin/v2/filter"
|
4
5
|
|
@@ -123,7 +124,9 @@ module Inspec::Plugin::V2
|
|
123
124
|
require "rbconfig"
|
124
125
|
ruby_abi_version = RbConfig::CONFIG["ruby_version"]
|
125
126
|
# TODO: why are we installing under the api directory for plugins?
|
126
|
-
|
127
|
+
base_dir = Inspec.config_dir
|
128
|
+
base_dir = File.realpath base_dir if File.exist? base_dir
|
129
|
+
File.join(base_dir, "gems", ruby_abi_version)
|
127
130
|
end
|
128
131
|
|
129
132
|
# Lists all gems found in the plugin_gem_path.
|
@@ -201,7 +204,7 @@ module Inspec::Plugin::V2
|
|
201
204
|
status = registry[plugin_name]
|
202
205
|
status.api_generation = 0
|
203
206
|
act = Activator.new
|
204
|
-
act.activated
|
207
|
+
act.activated = true
|
205
208
|
act.plugin_type = :cli_command
|
206
209
|
act.plugin_name = plugin_name
|
207
210
|
act.activator_name = :default
|
@@ -272,9 +275,22 @@ module Inspec::Plugin::V2
|
|
272
275
|
end
|
273
276
|
end
|
274
277
|
|
278
|
+
def find_inspec_gemspec(name, ver)
|
279
|
+
Gem::Specification.find_by_name(name, ver)
|
280
|
+
rescue Gem::MissingSpecError
|
281
|
+
nil
|
282
|
+
end
|
283
|
+
|
275
284
|
def detect_system_plugins
|
276
285
|
# Find the gemspec for inspec
|
277
|
-
inspec_gemspec =
|
286
|
+
inspec_gemspec =
|
287
|
+
find_inspec_gemspec("inspec", "=#{Inspec::VERSION}") ||
|
288
|
+
find_inspec_gemspec("inspec-core", "=#{Inspec::VERSION}")
|
289
|
+
|
290
|
+
unless inspec_gemspec
|
291
|
+
Inspec::Log.warn "inspec gem not found, skipping detecting of system plugins"
|
292
|
+
return
|
293
|
+
end
|
278
294
|
|
279
295
|
# Make a RequestSet that represents the dependencies of inspec
|
280
296
|
inspec_deps_request_set = Gem::RequestSet.new(*inspec_gemspec.dependencies)
|
data/lib/inspec/profile.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "json"
|
2
2
|
|
3
3
|
module Inspec::Reporters
|
4
|
+
# rubocop:disable Layout/AlignHash, Style/BlockDelimiters
|
4
5
|
class Json < Base
|
5
6
|
def render
|
6
7
|
output(report.to_json, false)
|
@@ -20,112 +21,93 @@ module Inspec::Reporters
|
|
20
21
|
private
|
21
22
|
|
22
23
|
def platform
|
23
|
-
|
24
|
-
name:
|
25
|
-
release:
|
26
|
-
|
27
|
-
|
28
|
-
platform
|
24
|
+
{
|
25
|
+
name: run_data[:platform][:name],
|
26
|
+
release: run_data[:platform][:release],
|
27
|
+
target_id: @config["target_id"],
|
28
|
+
}.reject { |_k, v| v.nil? }
|
29
29
|
end
|
30
30
|
|
31
31
|
def profile_results(control)
|
32
|
-
results
|
33
|
-
|
32
|
+
(control[:results] || []).map { |r|
|
33
|
+
{
|
34
|
+
status: r[:status],
|
35
|
+
code_desc: r[:code_desc],
|
36
|
+
run_time: r[:run_time],
|
37
|
+
start_time: r[:start_time],
|
38
|
+
resource: r[:resource],
|
39
|
+
skip_message: r[:skip_message],
|
40
|
+
message: r[:message],
|
41
|
+
exception: r[:exception],
|
42
|
+
backtrace: r[:backtrace],
|
43
|
+
waiver_data: r[:waiver_data],
|
44
|
+
}.reject { |_k, v| v.nil? }
|
45
|
+
}
|
46
|
+
end
|
34
47
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
48
|
+
def profiles
|
49
|
+
run_data[:profiles].map { |p|
|
50
|
+
{
|
51
|
+
name: p[:name],
|
52
|
+
version: p[:version],
|
53
|
+
sha256: p[:sha256],
|
54
|
+
title: p[:title],
|
55
|
+
maintainer: p[:maintainer],
|
56
|
+
summary: p[:summary],
|
57
|
+
license: p[:license],
|
58
|
+
copyright: p[:copyright],
|
59
|
+
copyright_email: p[:copyright_email],
|
60
|
+
supports: p[:supports],
|
61
|
+
# TODO: rename exposed field to inputs, see #3802:
|
62
|
+
attributes: (p[:inputs] || p[:attributes]),
|
63
|
+
parent_profile: p[:parent_profile],
|
64
|
+
depends: p[:depends],
|
65
|
+
groups: profile_groups(p),
|
66
|
+
controls: profile_controls(p),
|
67
|
+
status: p[:status],
|
68
|
+
skip_message: p[:skip_message],
|
69
|
+
waiver_data: p[:waiver_data],
|
70
|
+
}.reject { |_k, v| v.nil? }
|
71
|
+
}
|
72
|
+
end
|
47
73
|
|
48
|
-
|
49
|
-
|
50
|
-
|
74
|
+
def profile_groups(profile)
|
75
|
+
(profile[:groups] || []).map { |g|
|
76
|
+
{
|
77
|
+
id: g[:id],
|
78
|
+
controls: g[:controls],
|
79
|
+
title: g[:title],
|
80
|
+
}.reject { |_k, v| v.nil? }
|
81
|
+
}
|
51
82
|
end
|
52
83
|
|
53
84
|
def profile_controls(profile)
|
54
|
-
controls
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
id: c[:id],
|
60
|
-
title: c[:title],
|
61
|
-
desc: c.dig(:descriptions, :default),
|
85
|
+
(profile[:controls] || []).map { |c|
|
86
|
+
{
|
87
|
+
id: c[:id],
|
88
|
+
title: c[:title],
|
89
|
+
desc: c.dig(:descriptions, :default),
|
62
90
|
descriptions: convert_descriptions(c[:descriptions]),
|
63
91
|
impact: c[:impact],
|
64
|
-
refs:
|
65
|
-
tags:
|
66
|
-
code:
|
92
|
+
refs: c[:refs],
|
93
|
+
tags: c[:tags],
|
94
|
+
code: c[:code],
|
67
95
|
source_location: {
|
68
96
|
line: c[:source_location][:line],
|
69
|
-
ref:
|
97
|
+
ref: c[:source_location][:ref],
|
70
98
|
},
|
71
99
|
results: profile_results(c),
|
72
100
|
}
|
73
|
-
|
74
|
-
end
|
75
|
-
controls
|
76
|
-
end
|
77
|
-
|
78
|
-
def profile_groups(profile)
|
79
|
-
groups = []
|
80
|
-
return groups if profile[:groups].nil?
|
81
|
-
|
82
|
-
profile[:groups].each do |g|
|
83
|
-
group = {
|
84
|
-
id: g[:id],
|
85
|
-
controls: g[:controls],
|
86
|
-
}
|
87
|
-
group[:title] = g[:title] if g[:title]
|
88
|
-
|
89
|
-
groups << group
|
90
|
-
end
|
91
|
-
groups
|
92
|
-
end
|
93
|
-
|
94
|
-
def profiles
|
95
|
-
profiles = []
|
96
|
-
run_data[:profiles].each do |p|
|
97
|
-
profile = {
|
98
|
-
name: p[:name],
|
99
|
-
version: p[:version],
|
100
|
-
sha256: p[:sha256],
|
101
|
-
title: p[:title],
|
102
|
-
maintainer: p[:maintainer],
|
103
|
-
summary: p[:summary],
|
104
|
-
license: p[:license],
|
105
|
-
copyright: p[:copyright],
|
106
|
-
copyright_email: p[:copyright_email],
|
107
|
-
supports: p[:supports],
|
108
|
-
attributes: (p[:inputs] ? p[:inputs] : p[:attributes]), # TODO: rename exposed field to inputs, see #3802
|
109
|
-
parent_profile: p[:parent_profile],
|
110
|
-
depends: p[:depends],
|
111
|
-
groups: profile_groups(p),
|
112
|
-
controls: profile_controls(p),
|
113
|
-
status: p[:status],
|
114
|
-
skip_message: p[:skip_message],
|
115
|
-
}
|
116
|
-
profiles << profile.reject { |_k, v| v.nil? }
|
117
|
-
end
|
118
|
-
profiles
|
101
|
+
}
|
119
102
|
end
|
120
103
|
|
121
104
|
def convert_descriptions(data)
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
results
|
105
|
+
(data || []).map { |label, text|
|
106
|
+
{
|
107
|
+
label: label.to_s,
|
108
|
+
data: text,
|
109
|
+
}
|
110
|
+
}
|
129
111
|
end
|
130
112
|
end
|
131
113
|
end
|
data/lib/inspec/resource.rb
CHANGED
data/lib/inspec/resources.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
+
##
|
2
|
+
# Now that resources are lazily loaded, this file is ONLY here for one
|
3
|
+
# reason at this point, to load all the resources in order to populate
|
4
|
+
# the registry for `inspec shell`'s `help commands`. There has to be a
|
5
|
+
# cheaper way to do this, but this will do for now.
|
6
|
+
#
|
7
|
+
# NOTE: I intentionally didn't convert this to a loop over a simple
|
8
|
+
# glob so this remains a sort of manifest for our resources.
|
9
|
+
|
1
10
|
require "inspec/resource"
|
2
11
|
|
3
12
|
# Detect if we are running the stripped-down inspec-core
|
4
13
|
# This relies on AWS being stripped from the inspec-core gem
|
5
14
|
inspec_core_only = ENV["NO_AWS"] || !File.exist?(File.join(File.dirname(__FILE__), "..", "resource_support", "aws.rb"))
|
6
15
|
|
7
|
-
require "rspec/matchers"
|
8
|
-
|
9
16
|
# Do not attempt to load cloud resources if we are in inspec-core mode
|
10
17
|
unless inspec_core_only
|
11
18
|
require "resource_support/aws"
|
data/lib/inspec/resources/apt.rb
CHANGED
@@ -71,9 +71,9 @@ module Inspec::Resources
|
|
71
71
|
read_debs.select { |repo| repo[:url] == @deb_url && repo[:type] == "deb" }
|
72
72
|
end
|
73
73
|
|
74
|
+
# TODO: remove this. just see if it is valid w/ URI.parse
|
74
75
|
HTTP_URL_RE = /\A#{URI::DEFAULT_PARSER.make_regexp(%w{http https})}\z/.freeze
|
75
76
|
|
76
|
-
# read
|
77
77
|
def read_debs
|
78
78
|
return @repo_cache if defined?(@repo_cache)
|
79
79
|
|
@@ -81,32 +81,32 @@ module Inspec::Resources
|
|
81
81
|
cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
|
82
82
|
|
83
83
|
# @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
|
84
|
-
@repo_cache = cmd.stdout.
|
85
|
-
active = true
|
86
|
-
|
84
|
+
@repo_cache = cmd.stdout.lines.map do |raw_line|
|
87
85
|
# detect if the repo is commented out
|
88
86
|
line = raw_line.gsub(/^(#\s*)*/, "")
|
89
|
-
active =
|
87
|
+
active = raw_line == line
|
88
|
+
|
89
|
+
# formats:
|
90
|
+
# deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
|
91
|
+
# deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
words = line.split
|
94
|
+
words.delete 1 if words[1] && words[1].start_with?("[")
|
95
|
+
type, url, distro, *components = words
|
94
96
|
|
95
|
-
|
96
|
-
next
|
97
|
+
next if components.empty?
|
98
|
+
next unless URI::HTTP === URI.parse(url)
|
99
|
+
next unless %w{deb deb-src}.include? type
|
97
100
|
|
98
101
|
# map data
|
99
|
-
|
100
|
-
type:
|
101
|
-
url:
|
102
|
-
distro:
|
103
|
-
components:
|
102
|
+
{
|
103
|
+
type: type,
|
104
|
+
url: url,
|
105
|
+
distro: distro,
|
106
|
+
components: components,
|
104
107
|
active: active,
|
105
108
|
}
|
106
|
-
|
107
|
-
|
108
|
-
lines.push(repo)
|
109
|
-
end
|
109
|
+
end.compact
|
110
110
|
end
|
111
111
|
|
112
112
|
# resolves ppa urls
|