inspec 4.16.0 → 4.17.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|