inspec 0.34.1 → 1.0.0
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/CHANGELOG.md +323 -6
- data/Gemfile +10 -0
- data/README.md +1 -1
- data/Rakefile +4 -55
- data/docs/.gitignore +2 -0
- data/docs/README.md +40 -0
- data/docs/cli.md +342 -0
- data/docs/dsl_inspec.md +245 -0
- data/docs/dsl_resource.md +93 -0
- data/docs/inspec_and_friends.md +105 -0
- data/docs/matchers.md +136 -0
- data/docs/plugin_kitchen_inspec.html.md +55 -0
- data/docs/profiles.md +285 -0
- data/docs/resources/apache_conf.md.erb +75 -0
- data/docs/resources/apt.md.erb +84 -0
- data/docs/resources/audit_policy.md.erb +61 -0
- data/docs/resources/auditd_conf.md.erb +79 -0
- data/docs/resources/auditd_rules.md.erb +132 -0
- data/docs/resources/bash.md.erb +84 -0
- data/docs/resources/bond.md.erb +97 -0
- data/docs/resources/bridge.md.erb +67 -0
- data/docs/resources/bsd_service.md.erb +76 -0
- data/docs/resources/command.md.erb +151 -0
- data/docs/resources/csv.md.erb +62 -0
- data/docs/resources/directory.md.erb +43 -0
- data/docs/resources/etc_group.md.erb +116 -0
- data/docs/resources/etc_passwd.md.erb +155 -0
- data/docs/resources/etc_shadow.md.erb +149 -0
- data/docs/resources/file.md.erb +460 -0
- data/docs/resources/gem.md.erb +73 -0
- data/docs/resources/group.md.erb +74 -0
- data/docs/resources/grub_conf.md.erb +115 -0
- data/docs/resources/host.md.erb +85 -0
- data/docs/resources/iis_site.md.erb +142 -0
- data/docs/resources/inetd_conf.md.erb +99 -0
- data/docs/resources/ini.md.erb +69 -0
- data/docs/resources/interface.md.erb +66 -0
- data/docs/resources/iptables.md.erb +70 -0
- data/docs/resources/json.md.erb +76 -0
- data/docs/resources/kernel_module.md.erb +60 -0
- data/docs/resources/kernel_parameter.md.erb +72 -0
- data/docs/resources/launchd_service.md.erb +76 -0
- data/docs/resources/limits_conf.md.erb +80 -0
- data/docs/resources/login_def.md.erb +77 -0
- data/docs/resources/mount.md.erb +83 -0
- data/docs/resources/mysql_conf.md.erb +102 -0
- data/docs/resources/mysql_session.md.erb +63 -0
- data/docs/resources/npm.md.erb +75 -0
- data/docs/resources/ntp_conf.md.erb +76 -0
- data/docs/resources/oneget.md.erb +67 -0
- data/docs/resources/os.md.erb +154 -0
- data/docs/resources/os_env.md.erb +98 -0
- data/docs/resources/package.md.erb +115 -0
- data/docs/resources/parse_config.md.erb +122 -0
- data/docs/resources/parse_config_file.md.erb +143 -0
- data/docs/resources/pip.md.erb +74 -0
- data/docs/resources/port.md.erb +150 -0
- data/docs/resources/postgres_conf.md.erb +90 -0
- data/docs/resources/postgres_session.md.erb +75 -0
- data/docs/resources/powershell.md.erb +116 -0
- data/docs/resources/process.md.erb +73 -0
- data/docs/resources/registry_key.md.erb +149 -0
- data/docs/resources/runit_service.md.erb +76 -0
- data/docs/resources/security_policy.md.erb +61 -0
- data/docs/resources/service.md.erb +135 -0
- data/docs/resources/ssh_config.md.erb +94 -0
- data/docs/resources/sshd_config.md.erb +97 -0
- data/docs/resources/ssl.md.erb +133 -0
- data/docs/resources/sys_info.md.erb +55 -0
- data/docs/resources/systemd_service.md.erb +76 -0
- data/docs/resources/sysv_service.md.erb +76 -0
- data/docs/resources/upstart_service.md.erb +76 -0
- data/docs/resources/user.md.erb +154 -0
- data/docs/resources/users.md.erb +140 -0
- data/docs/resources/vbscript.md.erb +69 -0
- data/docs/resources/windows_feature.md.erb +61 -0
- data/docs/resources/wmi.md.erb +95 -0
- data/docs/resources/xinetd_conf.md.erb +170 -0
- data/docs/resources/yaml.md.erb +69 -0
- data/docs/resources/yum.md.erb +103 -0
- data/docs/ruby_usage.md +154 -0
- data/docs/shared/matcher_be.md.erb +1 -0
- data/docs/shared/matcher_cmp.md.erb +45 -0
- data/docs/shared/matcher_eq.md.erb +3 -0
- data/docs/shared/matcher_include.md.erb +1 -0
- data/docs/shared/matcher_match.md.erb +1 -0
- data/docs/shell.md +150 -0
- data/examples/meta-profile/inspec.yml +2 -4
- data/inspec.gemspec +1 -1
- data/lib/bundles/inspec-compliance/api.rb +28 -18
- data/lib/bundles/inspec-compliance/cli.rb +19 -27
- data/lib/bundles/inspec-compliance/target.rb +15 -2
- data/lib/fetchers/git.rb +4 -0
- data/lib/fetchers/local.rb +16 -1
- data/lib/fetchers/mock.rb +4 -0
- data/lib/fetchers/url.rb +46 -20
- data/lib/inspec/base_cli.rb +14 -0
- data/lib/inspec/cached_fetcher.rb +67 -0
- data/lib/inspec/cli.rb +22 -8
- data/lib/inspec/control_eval_context.rb +12 -2
- data/lib/inspec/dependencies/{vendor_index.rb → cache.rb} +5 -4
- data/lib/inspec/dependencies/dependency_set.rb +8 -14
- data/lib/inspec/dependencies/lockfile.rb +5 -13
- data/lib/inspec/dependencies/requirement.rb +31 -41
- data/lib/inspec/dependencies/resolver.rb +3 -3
- data/lib/inspec/dsl.rb +16 -4
- data/lib/inspec/errors.rb +1 -0
- data/lib/inspec/fetcher.rb +25 -1
- data/lib/inspec/objects/each_loop.rb +5 -2
- data/lib/inspec/objects/test.rb +8 -2
- data/lib/inspec/plugins/fetcher.rb +13 -12
- data/lib/inspec/plugins/resource.rb +3 -0
- data/lib/inspec/profile.rb +62 -26
- data/lib/inspec/profile_context.rb +44 -8
- data/lib/inspec/resource.rb +18 -3
- data/lib/inspec/rspec_json_formatter.rb +91 -40
- data/lib/inspec/rule.rb +45 -2
- data/lib/inspec/runner.rb +51 -39
- data/lib/inspec/shell.rb +5 -16
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apache_conf.rb +1 -1
- data/lib/resources/gem.rb +1 -0
- data/lib/resources/groups.rb +190 -0
- data/lib/resources/oneget.rb +1 -0
- data/lib/resources/os.rb +1 -1
- data/lib/resources/package.rb +3 -1
- data/lib/resources/parse_config.rb +18 -1
- data/lib/resources/pip.rb +1 -1
- data/lib/resources/security_policy.rb +54 -0
- data/lib/resources/ssl.rb +9 -11
- data/lib/resources/sys_info.rb +1 -1
- data/lib/resources/users.rb +81 -64
- metadata +91 -17
- data/docs/cli.rst +0 -442
- data/docs/dsl_inspec.rst +0 -259
- data/docs/dsl_resource.rst +0 -90
- data/docs/inspec_and_friends.rst +0 -85
- data/docs/matchers.rst +0 -137
- data/docs/profiles.rst +0 -169
- data/docs/readme.rst +0 -105
- data/docs/resources.rst +0 -4836
- data/docs/ruby_usage.rst +0 -145
- data/docs/shell.rst +0 -130
- data/docs/template.rst +0 -51
- data/lib/resources/group.rb +0 -137
data/lib/inspec/fetcher.rb
CHANGED
|
@@ -6,7 +6,31 @@ require 'inspec/plugins'
|
|
|
6
6
|
require 'utils/plugin_registry'
|
|
7
7
|
|
|
8
8
|
module Inspec
|
|
9
|
-
|
|
9
|
+
class FetcherRegistry < PluginRegistry
|
|
10
|
+
def resolve(target)
|
|
11
|
+
if fetcher_specified?(target)
|
|
12
|
+
super(target)
|
|
13
|
+
else
|
|
14
|
+
Inspec::Log.debug("Assuming default supermarket source for #{target}")
|
|
15
|
+
super(with_default_fetcher(target))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache, :sha256].freeze
|
|
20
|
+
def fetcher_specified?(target)
|
|
21
|
+
# Only set a default for Hash-based (i.e. from
|
|
22
|
+
# inspec.yml/inspec.lock) targets
|
|
23
|
+
|
|
24
|
+
return true if !target.respond_to?(:keys)
|
|
25
|
+
!(target.keys - NON_FETCHER_KEYS).empty?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def with_default_fetcher(target)
|
|
29
|
+
target.merge({ supermarket: target[:name] })
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Fetcher = FetcherRegistry.new
|
|
10
34
|
|
|
11
35
|
def self.fetcher(version)
|
|
12
36
|
if version != 1
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module Inspec
|
|
4
4
|
class EachLoop < List
|
|
5
|
-
attr_reader :tests
|
|
5
|
+
attr_reader :tests, :variables
|
|
6
6
|
def initialize
|
|
7
7
|
super
|
|
8
8
|
@tests = []
|
|
9
|
+
@variables = []
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def add_test(t = nil)
|
|
@@ -24,9 +25,11 @@ module Inspec
|
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def to_ruby
|
|
28
|
+
vars = variables.map(&:to_ruby).join("\n")
|
|
29
|
+
vars += "\n" unless vars.empty?
|
|
27
30
|
obj = super
|
|
28
31
|
all_tests = @tests.map(&:to_ruby).join("\n").gsub("\n", "\n ")
|
|
29
|
-
format("%s.each do |entry|\n %s\nend", obj, all_tests)
|
|
32
|
+
format("%s%s.each do |entry|\n %s\nend", vars, obj, all_tests)
|
|
30
33
|
end
|
|
31
34
|
end
|
|
32
35
|
end
|
data/lib/inspec/objects/test.rb
CHANGED
|
@@ -66,8 +66,14 @@ module Inspec
|
|
|
66
66
|
res, xtra = describe_chain
|
|
67
67
|
itsy = xtra.nil? ? 'it' : 'its(' + xtra.to_s.inspect + ')'
|
|
68
68
|
naughty = @negated ? '_not' : ''
|
|
69
|
-
xpect = defined?(@expectation) ? expectation.inspect
|
|
70
|
-
|
|
69
|
+
xpect = defined?(@expectation) ? expectation.inspect : ''
|
|
70
|
+
if matcher == 'match'
|
|
71
|
+
# without this, xpect values like / \/zones\// will not be parsed properly
|
|
72
|
+
xpect = "(#{xpect})"
|
|
73
|
+
elsif xpect != ''
|
|
74
|
+
xpect = ' ' + xpect
|
|
75
|
+
end
|
|
76
|
+
format("%sdescribe %s do\n %s { should%s %s%s }\nend",
|
|
71
77
|
vars, res, itsy, naughty, matcher, xpect)
|
|
72
78
|
end
|
|
73
79
|
|
|
@@ -24,6 +24,12 @@ module Inspec
|
|
|
24
24
|
Inspec::Fetcher
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
attr_accessor :target
|
|
28
|
+
|
|
29
|
+
def writable?
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
|
|
27
33
|
#
|
|
28
34
|
# The path to the archive on disk. This can be passed to a
|
|
29
35
|
# FileProvider to get access to the files in the fetched
|
|
@@ -56,6 +62,13 @@ module Inspec
|
|
|
56
62
|
fail "Fetcher #{self} does not implement `resolved_source()`. This is required for terminal fetchers."
|
|
57
63
|
end
|
|
58
64
|
|
|
65
|
+
#
|
|
66
|
+
# The unique key based on the content of the remote archive.
|
|
67
|
+
#
|
|
68
|
+
def cache_key
|
|
69
|
+
fail "Fetcher #{self} does not implement `cache_key()`. This is required for terminal fetchers."
|
|
70
|
+
end
|
|
71
|
+
|
|
59
72
|
#
|
|
60
73
|
# relative_target is provided to keep compatibility with 3rd
|
|
61
74
|
# party plugins.
|
|
@@ -69,18 +82,6 @@ module Inspec
|
|
|
69
82
|
file_provider = Inspec::FileProvider.for_path(archive_path)
|
|
70
83
|
file_provider.relative_provider
|
|
71
84
|
end
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
# A string based on the components of the resolved source,
|
|
75
|
-
# suitable for constructing per-source file names.
|
|
76
|
-
#
|
|
77
|
-
def cache_key
|
|
78
|
-
key = ''
|
|
79
|
-
resolved_source.each do |k, v|
|
|
80
|
-
key << "#{k}:#{v}"
|
|
81
|
-
end
|
|
82
|
-
Digest::SHA256.hexdigest key
|
|
83
|
-
end
|
|
84
85
|
end
|
|
85
86
|
end
|
|
86
87
|
end
|
|
@@ -72,6 +72,9 @@ module Inspec
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# rubocop:enable Lint/NestedMethodDefinition
|
|
75
|
+
if __resource_registry.key?(name)
|
|
76
|
+
Inspec::Log.warn("Overwriting resource #{name}. To reference a specific version of #{name} use the resource() method")
|
|
77
|
+
end
|
|
75
78
|
__resource_registry[name] = cl
|
|
76
79
|
end
|
|
77
80
|
end
|
data/lib/inspec/profile.rb
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
require 'forwardable'
|
|
7
7
|
require 'inspec/polyfill'
|
|
8
|
-
require 'inspec/
|
|
8
|
+
require 'inspec/cached_fetcher'
|
|
9
9
|
require 'inspec/file_provider'
|
|
10
10
|
require 'inspec/source_reader'
|
|
11
11
|
require 'inspec/metadata'
|
|
@@ -13,7 +13,7 @@ require 'inspec/backend'
|
|
|
13
13
|
require 'inspec/rule'
|
|
14
14
|
require 'inspec/log'
|
|
15
15
|
require 'inspec/profile_context'
|
|
16
|
-
require 'inspec/dependencies/
|
|
16
|
+
require 'inspec/dependencies/cache'
|
|
17
17
|
require 'inspec/dependencies/lockfile'
|
|
18
18
|
require 'inspec/dependencies/dependency_set'
|
|
19
19
|
|
|
@@ -22,19 +22,7 @@ module Inspec
|
|
|
22
22
|
extend Forwardable
|
|
23
23
|
|
|
24
24
|
def self.resolve_target(target, cache = nil)
|
|
25
|
-
cache
|
|
26
|
-
fetcher = Inspec::Fetcher.resolve(target)
|
|
27
|
-
if fetcher.nil?
|
|
28
|
-
fail("Could not fetch inspec profile in #{target.inspect}.")
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
if cache.exists?(fetcher.cache_key)
|
|
32
|
-
Inspec::Log.debug "Using cached dependency for #{target}"
|
|
33
|
-
cache.prefered_entry_for(fetcher.cache_key)
|
|
34
|
-
else
|
|
35
|
-
fetcher.fetch(cache.base_path_for(fetcher.cache_key))
|
|
36
|
-
fetcher.archive_path
|
|
37
|
-
end
|
|
25
|
+
Inspec::CachedFetcher.new(target, cache || Cache.new)
|
|
38
26
|
end
|
|
39
27
|
|
|
40
28
|
def self.for_path(path, opts)
|
|
@@ -47,12 +35,17 @@ module Inspec
|
|
|
47
35
|
new(reader, opts)
|
|
48
36
|
end
|
|
49
37
|
|
|
38
|
+
def self.for_fetcher(fetcher, opts)
|
|
39
|
+
path, writable = fetcher.fetch
|
|
40
|
+
for_path(path, opts.merge(target: fetcher.target, writable: writable))
|
|
41
|
+
end
|
|
42
|
+
|
|
50
43
|
def self.for_target(target, opts = {})
|
|
51
|
-
|
|
44
|
+
fetcher = resolve_target(target, opts[:cache])
|
|
45
|
+
for_fetcher(fetcher, opts)
|
|
52
46
|
end
|
|
53
47
|
|
|
54
|
-
attr_reader :source_reader
|
|
55
|
-
attr_accessor :runner_context
|
|
48
|
+
attr_reader :source_reader, :backend, :runner_context
|
|
56
49
|
def_delegator :@source_reader, :tests
|
|
57
50
|
def_delegator :@source_reader, :libraries
|
|
58
51
|
def_delegator :@source_reader, :metadata
|
|
@@ -63,10 +56,13 @@ module Inspec
|
|
|
63
56
|
@logger = options[:logger] || Logger.new(nil)
|
|
64
57
|
@locked_dependencies = options[:dependencies]
|
|
65
58
|
@controls = options[:controls] || []
|
|
59
|
+
@writable = options[:writable] || false
|
|
66
60
|
@profile_id = options[:id]
|
|
61
|
+
@cache = options[:cache] || Cache.new
|
|
67
62
|
@backend = options[:backend] || Inspec::Backend.create(options)
|
|
68
63
|
@source_reader = source_reader
|
|
69
64
|
@tests_collected = false
|
|
65
|
+
@libraries_loaded = false
|
|
70
66
|
Metadata.finalize(@source_reader.metadata, @profile_id)
|
|
71
67
|
@runner_context = options[:profile_context] || Inspec::ProfileContext.for_profile(self,
|
|
72
68
|
@backend,
|
|
@@ -77,6 +73,32 @@ module Inspec
|
|
|
77
73
|
metadata.params[:name]
|
|
78
74
|
end
|
|
79
75
|
|
|
76
|
+
def version
|
|
77
|
+
metadata.params[:version]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def writable? # rubocop:disable Style/TrivialAccessors
|
|
81
|
+
@writable
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Is this profile is supported on the current platform of the
|
|
86
|
+
# backend machine and the current inspec version.
|
|
87
|
+
#
|
|
88
|
+
# @returns [TrueClass, FalseClass]
|
|
89
|
+
#
|
|
90
|
+
def supported?
|
|
91
|
+
supports_os? && supports_runtime?
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def supports_os?
|
|
95
|
+
metadata.supports_transport?(@backend)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def supports_runtime?
|
|
99
|
+
metadata.supports_runtime?
|
|
100
|
+
end
|
|
101
|
+
|
|
80
102
|
def params
|
|
81
103
|
@params ||= load_params
|
|
82
104
|
end
|
|
@@ -104,6 +126,8 @@ module Inspec
|
|
|
104
126
|
end
|
|
105
127
|
|
|
106
128
|
def load_libraries
|
|
129
|
+
return @runner_context if @libraries_loaded
|
|
130
|
+
|
|
107
131
|
locked_dependencies.each do |d|
|
|
108
132
|
c = d.load_libraries
|
|
109
133
|
@runner_context.add_resources(c)
|
|
@@ -114,6 +138,7 @@ module Inspec
|
|
|
114
138
|
end
|
|
115
139
|
|
|
116
140
|
@runner_context.load_libraries(libs)
|
|
141
|
+
@libraries_loaded = true
|
|
117
142
|
@runner_context
|
|
118
143
|
end
|
|
119
144
|
|
|
@@ -121,19 +146,29 @@ module Inspec
|
|
|
121
146
|
"Inspec::Profile<#{name}>"
|
|
122
147
|
end
|
|
123
148
|
|
|
124
|
-
|
|
125
|
-
|
|
149
|
+
# return info using uncached params
|
|
150
|
+
def info!
|
|
151
|
+
info(load_params.dup)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def info(res = params.dup)
|
|
126
155
|
# add information about the controls
|
|
127
|
-
controls = res[:controls].map do |id, rule|
|
|
156
|
+
res[:controls] = res[:controls].map do |id, rule|
|
|
128
157
|
next if id.to_s.empty?
|
|
129
158
|
data = rule.dup
|
|
130
159
|
data.delete(:checks)
|
|
131
160
|
data[:impact] ||= 0.5
|
|
132
161
|
data[:impact] = 1.0 if data[:impact] > 1.0
|
|
133
162
|
data[:impact] = 0.0 if data[:impact] < 0.0
|
|
134
|
-
[id
|
|
163
|
+
data[:id] = id
|
|
164
|
+
data
|
|
165
|
+
end.compact
|
|
166
|
+
|
|
167
|
+
# resolve hash structure in groups
|
|
168
|
+
res[:groups] = res[:groups].map do |id, group|
|
|
169
|
+
group[:id] = id
|
|
170
|
+
group
|
|
135
171
|
end
|
|
136
|
-
res[:controls] = Hash[controls.compact]
|
|
137
172
|
|
|
138
173
|
# add information about the required attributes
|
|
139
174
|
res[:attributes] = res[:attributes].map(&:to_hash) unless res[:attributes].nil? || res[:attributes].empty?
|
|
@@ -308,14 +343,14 @@ module Inspec
|
|
|
308
343
|
# @param vendor_path [String] Path to the on-disk vendor dir
|
|
309
344
|
# @return [Inspec::Lockfile]
|
|
310
345
|
#
|
|
311
|
-
def generate_lockfile
|
|
312
|
-
res = Inspec::DependencySet.new(cwd,
|
|
346
|
+
def generate_lockfile
|
|
347
|
+
res = Inspec::DependencySet.new(cwd, @cache, nil, @backend)
|
|
313
348
|
res.vendor(metadata.dependencies)
|
|
314
349
|
Inspec::Lockfile.from_dependency_set(res)
|
|
315
350
|
end
|
|
316
351
|
|
|
317
352
|
def load_dependencies
|
|
318
|
-
Inspec::DependencySet.from_lockfile(lockfile, cwd,
|
|
353
|
+
Inspec::DependencySet.from_lockfile(lockfile, cwd, @cache, @backend)
|
|
319
354
|
end
|
|
320
355
|
|
|
321
356
|
private
|
|
@@ -353,6 +388,7 @@ module Inspec
|
|
|
353
388
|
params[:groups] = groups = {}
|
|
354
389
|
prefix = @source_reader.target.prefix || ''
|
|
355
390
|
tests.each do |rule|
|
|
391
|
+
next if rule.nil?
|
|
356
392
|
f = load_rule_filepath(prefix, rule)
|
|
357
393
|
load_rule(rule, f, controls, groups)
|
|
358
394
|
end
|
|
@@ -17,7 +17,8 @@ module Inspec
|
|
|
17
17
|
'attributes' => attributes })
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
attr_reader :attributes, :
|
|
20
|
+
attr_reader :attributes, :profile_id, :resource_registry, :backend
|
|
21
|
+
attr_accessor :rules
|
|
21
22
|
def initialize(profile_id, backend, conf)
|
|
22
23
|
if backend.nil?
|
|
23
24
|
fail 'ProfileContext is initiated with a backend == nil. ' \
|
|
@@ -27,7 +28,8 @@ module Inspec
|
|
|
27
28
|
@backend = backend
|
|
28
29
|
@conf = conf.dup
|
|
29
30
|
@rules = {}
|
|
30
|
-
@
|
|
31
|
+
@control_subcontexts = []
|
|
32
|
+
@lib_subcontexts = []
|
|
31
33
|
@require_loader = ::Inspec::RequireLoader.new
|
|
32
34
|
@attributes = []
|
|
33
35
|
# A local resource registry that only contains resources defined
|
|
@@ -45,7 +47,7 @@ module Inspec
|
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
def to_resources_dsl
|
|
48
|
-
Inspec::Resource.create_dsl(
|
|
50
|
+
Inspec::Resource.create_dsl(self)
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
def control_eval_context
|
|
@@ -59,20 +61,47 @@ module Inspec
|
|
|
59
61
|
@control_eval_context = nil
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
def
|
|
64
|
+
def profile_supports_os?
|
|
65
|
+
return true if @conf['profile'].nil?
|
|
66
|
+
|
|
67
|
+
@conf['profile'].supports_os?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def remove_rule(id)
|
|
71
|
+
@rules[id] = nil if @rules.key?(id)
|
|
72
|
+
@control_subcontexts.each do |c|
|
|
73
|
+
c.remove_rule(id)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def all_controls
|
|
63
78
|
ret = @rules.values
|
|
64
|
-
ret += @
|
|
79
|
+
ret += @control_subcontexts.map(&:all_rules).flatten
|
|
65
80
|
ret
|
|
66
81
|
end
|
|
82
|
+
alias all_rules all_controls
|
|
83
|
+
|
|
84
|
+
def subcontext_by_name(name)
|
|
85
|
+
found = @lib_subcontexts.find { |c| c.profile_id == name }
|
|
86
|
+
if !found
|
|
87
|
+
@lib_subcontexts.each do |c|
|
|
88
|
+
found = c.subcontext_by_name(name)
|
|
89
|
+
break if found
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
found
|
|
94
|
+
end
|
|
67
95
|
|
|
68
96
|
def add_resources(context)
|
|
69
97
|
@resource_registry.merge!(context.resource_registry)
|
|
70
98
|
control_eval_context.add_resources(context)
|
|
99
|
+
@lib_subcontexts << context
|
|
71
100
|
reload_dsl
|
|
72
101
|
end
|
|
73
102
|
|
|
74
103
|
def add_subcontext(context)
|
|
75
|
-
@
|
|
104
|
+
@control_subcontexts << context
|
|
76
105
|
end
|
|
77
106
|
|
|
78
107
|
def load_libraries(libs)
|
|
@@ -122,10 +151,17 @@ module Inspec
|
|
|
122
151
|
@rules.delete(full_id(@profile_id, id))
|
|
123
152
|
end
|
|
124
153
|
|
|
154
|
+
attr_reader :current_load
|
|
155
|
+
|
|
125
156
|
def register_rule(r)
|
|
126
157
|
# get the full ID
|
|
127
|
-
|
|
128
|
-
|
|
158
|
+
file = if @current_load.nil?
|
|
159
|
+
'unknown'
|
|
160
|
+
else
|
|
161
|
+
@current_load[:file] || 'unknown'
|
|
162
|
+
end
|
|
163
|
+
r.instance_variable_set(:@__file, file)
|
|
164
|
+
r.instance_variable_set(:@__group_title, current_load[:title])
|
|
129
165
|
|
|
130
166
|
# add the rule to the registry
|
|
131
167
|
fid = full_id(Inspec::Rule.profile_id(r), Inspec::Rule.rule_id(r))
|
data/lib/inspec/resource.rb
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
require 'inspec/plugins'
|
|
7
7
|
|
|
8
8
|
module Inspec
|
|
9
|
+
class ProfileNotFound < StandardError; end
|
|
10
|
+
|
|
9
11
|
class Resource
|
|
10
12
|
def self.default_registry
|
|
11
13
|
@default_registry ||= {}
|
|
@@ -25,9 +27,22 @@ module Inspec
|
|
|
25
27
|
#
|
|
26
28
|
# @param backend [BackendRunner] exposing the target to resources
|
|
27
29
|
# @return [ResourcesDSL]
|
|
28
|
-
def self.create_dsl(
|
|
29
|
-
|
|
30
|
+
def self.create_dsl(profile_context)
|
|
31
|
+
backend = profile_context.backend
|
|
32
|
+
my_registry = profile_context.resource_registry
|
|
33
|
+
|
|
30
34
|
Module.new do
|
|
35
|
+
define_method :resource_class do |profile_name, resource_name|
|
|
36
|
+
inner_context = if profile_name == profile_context.profile_id
|
|
37
|
+
profile_context
|
|
38
|
+
else
|
|
39
|
+
profile_context.subcontext_by_name(profile_name)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
fail ProfileNotFound, "Cannot find profile named: #{profile_name}" if inner_context.nil?
|
|
43
|
+
inner_context.resource_registry[resource_name]
|
|
44
|
+
end
|
|
45
|
+
|
|
31
46
|
my_registry.each do |id, r|
|
|
32
47
|
define_method id.to_sym do |*args|
|
|
33
48
|
r.new(backend, id.to_s, *args)
|
|
@@ -68,7 +83,7 @@ require 'resources/directory'
|
|
|
68
83
|
require 'resources/etc_group'
|
|
69
84
|
require 'resources/file'
|
|
70
85
|
require 'resources/gem'
|
|
71
|
-
require 'resources/
|
|
86
|
+
require 'resources/groups'
|
|
72
87
|
require 'resources/grub_conf'
|
|
73
88
|
require 'resources/host'
|
|
74
89
|
require 'resources/iis_site'
|