inspec 0.35.0 → 1.0.0.beta2
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 +83 -2
- data/Gemfile +6 -0
- data/Rakefile +3 -55
- data/docs/README.md +20 -0
- data/docs/cli.rst +6 -0
- data/docs/dsl_inspec.md +245 -0
- data/docs/dsl_resource.md +93 -0
- data/docs/inspec_and_friends.md +102 -0
- data/docs/matchers.md +136 -0
- data/docs/plugin_kitchen_inspec.html.md +55 -0
- data/docs/profiles.md +271 -0
- data/docs/resources.rst +1 -1
- data/docs/shell.md +150 -0
- 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/fetchers/git.rb +4 -0
- data/lib/fetchers/local.rb +16 -1
- data/lib/fetchers/mock.rb +4 -0
- data/lib/fetchers/url.rb +40 -12
- data/lib/inspec/base_cli.rb +4 -0
- data/lib/inspec/cli.rb +6 -8
- data/lib/inspec/control_eval_context.rb +8 -0
- data/lib/inspec/dependencies/{vendor_index.rb → cache.rb} +5 -4
- data/lib/inspec/dependencies/dependency_set.rb +8 -14
- data/lib/inspec/dependencies/requirement.rb +10 -20
- data/lib/inspec/dependencies/resolver.rb +2 -2
- data/lib/inspec/dsl.rb +9 -0
- data/lib/inspec/fetcher.rb +1 -1
- data/lib/inspec/objects/test.rb +8 -2
- data/lib/inspec/plugins/fetcher.rb +11 -12
- data/lib/inspec/plugins/resource.rb +3 -0
- data/lib/inspec/profile.rb +60 -14
- data/lib/inspec/profile_context.rb +28 -7
- data/lib/inspec/resource.rb +17 -2
- data/lib/inspec/rspec_json_formatter.rb +80 -35
- data/lib/inspec/runner.rb +42 -18
- 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/oneget.rb +1 -0
- data/lib/resources/os.rb +1 -1
- data/lib/resources/package.rb +3 -1
- data/lib/resources/pip.rb +1 -1
- data/lib/resources/ssl.rb +9 -11
- metadata +15 -15
- 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/shell.rst +0 -130
- data/docs/template.rst +0 -51
data/lib/inspec/base_cli.rb
CHANGED
@@ -58,6 +58,10 @@ module Inspec
|
|
58
58
|
desc: 'Use colors in output.'
|
59
59
|
option :attrs, type: :array,
|
60
60
|
desc: 'Load attributes file (experimental)'
|
61
|
+
option :cache, type: :string,
|
62
|
+
desc: 'Use the given path for caching dependencies. (default: ~/.inspec/cache)'
|
63
|
+
option :create_lockfile, type: :boolean, default: true,
|
64
|
+
desc: 'Write out a lockfile based on this execution (unless one already exists)'
|
61
65
|
end
|
62
66
|
|
63
67
|
private
|
data/lib/inspec/cli.rb
CHANGED
@@ -102,8 +102,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
102
102
|
desc 'vendor', 'Download all dependencies and generate a lockfile'
|
103
103
|
def vendor(path = nil)
|
104
104
|
configure_logger(opts)
|
105
|
-
profile = Inspec::Profile.for_target('./', opts)
|
106
|
-
lockfile = profile.generate_lockfile
|
105
|
+
profile = Inspec::Profile.for_target('./', opts.merge(cache: Inspec::Cache.new(path)))
|
106
|
+
lockfile = profile.generate_lockfile
|
107
107
|
File.write('inspec.lock', lockfile.to_yaml)
|
108
108
|
end
|
109
109
|
|
@@ -213,13 +213,11 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
213
213
|
|
214
214
|
def run_command(opts)
|
215
215
|
runner = Inspec::Runner.new(opts)
|
216
|
-
|
217
|
-
|
216
|
+
res = runner.eval_with_virtual_profile(opts[:command])
|
217
|
+
runner.load
|
218
218
|
|
219
|
-
return :ruby_eval, res if
|
220
|
-
|
221
|
-
runner.register_rules(ctx)
|
222
|
-
return :rspec_run, runner.run # rubocop:disable Style/RedundantReturn
|
219
|
+
return :ruby_eval, res if runner.all_rules.empty?
|
220
|
+
return :rspec_run, runner.run_tests # rubocop:disable Style/RedundantReturn
|
223
221
|
end
|
224
222
|
end
|
225
223
|
|
@@ -92,6 +92,14 @@ module Inspec
|
|
92
92
|
res
|
93
93
|
end
|
94
94
|
|
95
|
+
define_method :add_resource do |name, new_res|
|
96
|
+
resources_dsl.module_exec do
|
97
|
+
define_method name.to_sym do |*args|
|
98
|
+
new_res.new(@backend, name.to_s, *args)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
95
103
|
define_method :add_resources do |context|
|
96
104
|
self.class.class_eval do
|
97
105
|
include context.to_resources_dsl
|
@@ -4,7 +4,7 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
module Inspec
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# Inspec::Cache manages an on-disk cache of inspec profiles. The
|
8
8
|
# cache can contain:
|
9
9
|
#
|
10
10
|
# - .tar.gz profile archives
|
@@ -16,7 +16,7 @@ module Inspec
|
|
16
16
|
# sources.
|
17
17
|
#
|
18
18
|
#
|
19
|
-
class
|
19
|
+
class Cache
|
20
20
|
attr_reader :path
|
21
21
|
def initialize(path = nil)
|
22
22
|
@path = path || File.join(Dir.home, '.inspec', 'cache')
|
@@ -43,19 +43,20 @@ module Inspec
|
|
43
43
|
|
44
44
|
#
|
45
45
|
# For a given name and source_url, return true if the
|
46
|
-
# profile exists in the
|
46
|
+
# profile exists in the Cache.
|
47
47
|
#
|
48
48
|
# @param [String] name
|
49
49
|
# @param [String] source_url
|
50
50
|
# @return [Boolean]
|
51
51
|
#
|
52
52
|
def exists?(key)
|
53
|
+
return false if key.nil? || key.empty?
|
53
54
|
path = base_path_for(key)
|
54
55
|
File.directory?(path) || File.exist?("#{path}.tar.gz") || File.exist?("#{path}.zip")
|
55
56
|
end
|
56
57
|
|
57
58
|
#
|
58
|
-
# Return the path to given profile in the
|
59
|
+
# Return the path to given profile in the cache.
|
59
60
|
#
|
60
61
|
# The `source_url` parameter should be a URI-like string that
|
61
62
|
# fully specifies the source of the exact version we want to pull
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'inspec/dependencies/vendor_index'
|
3
2
|
require 'inspec/dependencies/requirement'
|
4
3
|
require 'inspec/dependencies/resolver'
|
5
4
|
|
@@ -7,9 +6,6 @@ module Inspec
|
|
7
6
|
#
|
8
7
|
# A DependencySet manages a list of dependencies for a profile.
|
9
8
|
#
|
10
|
-
# Currently this class is a thin wrapper interface to coordinate the
|
11
|
-
# VendorIndex and the Resolver.
|
12
|
-
#
|
13
9
|
class DependencySet
|
14
10
|
#
|
15
11
|
# Return a dependency set given a lockfile.
|
@@ -18,22 +14,21 @@ module Inspec
|
|
18
14
|
# @param cwd [String] Current working directory for relative path includes
|
19
15
|
# @param vendor_path [String] Path to the vendor directory
|
20
16
|
#
|
21
|
-
def self.from_lockfile(lockfile, cwd,
|
22
|
-
vendor_index = VendorIndex.new(vendor_path)
|
17
|
+
def self.from_lockfile(lockfile, cwd, cache, backend)
|
23
18
|
dep_tree = lockfile.deps.map do |dep|
|
24
|
-
Inspec::Requirement.from_lock_entry(dep, cwd,
|
19
|
+
Inspec::Requirement.from_lock_entry(dep, cwd, cache, backend)
|
25
20
|
end
|
26
21
|
|
27
22
|
dep_list = flatten_dep_tree(dep_tree)
|
28
|
-
new(cwd,
|
23
|
+
new(cwd, cache, dep_list, backend)
|
29
24
|
end
|
30
25
|
|
31
|
-
def self.from_array(dependencies, cwd,
|
26
|
+
def self.from_array(dependencies, cwd, cache, backend)
|
32
27
|
dep_list = {}
|
33
28
|
dependencies.each do |d|
|
34
29
|
dep_list[d.name] = d
|
35
30
|
end
|
36
|
-
new(cwd,
|
31
|
+
new(cwd, cache, dep_list, backend)
|
37
32
|
end
|
38
33
|
|
39
34
|
# This is experimental code to test the working of the
|
@@ -58,9 +53,9 @@ module Inspec
|
|
58
53
|
# @param cwd [String] current working directory for relative path includes
|
59
54
|
# @param vendor_path [String] path which contains vendored dependencies
|
60
55
|
# @return [dependencies] this
|
61
|
-
def initialize(cwd,
|
56
|
+
def initialize(cwd, cache, dep_list, backend)
|
62
57
|
@cwd = cwd
|
63
|
-
@
|
58
|
+
@cache = cache
|
64
59
|
@dep_list = dep_list
|
65
60
|
@backend = backend
|
66
61
|
end
|
@@ -91,8 +86,7 @@ module Inspec
|
|
91
86
|
#
|
92
87
|
def vendor(dependencies)
|
93
88
|
return nil if dependencies.nil? || dependencies.empty?
|
94
|
-
@
|
95
|
-
@dep_list = Resolver.resolve(dependencies, @vendor_index, @cwd, @backend)
|
89
|
+
@dep_list = Resolver.resolve(dependencies, @cache, @cwd, @backend)
|
96
90
|
end
|
97
91
|
end
|
98
92
|
end
|
@@ -9,31 +9,31 @@ module Inspec
|
|
9
9
|
# appropriate we delegate to Inspec::Profile directly.
|
10
10
|
#
|
11
11
|
class Requirement
|
12
|
-
def self.from_metadata(dep,
|
12
|
+
def self.from_metadata(dep, cache, opts)
|
13
13
|
fail 'Cannot load empty dependency.' if dep.nil? || dep.empty?
|
14
|
-
new(dep[:name], dep[:version],
|
14
|
+
new(dep[:name], dep[:version], cache, opts[:cwd], opts.merge(dep))
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.from_lock_entry(entry, cwd,
|
17
|
+
def self.from_lock_entry(entry, cwd, cache, backend)
|
18
18
|
req = new(entry[:name],
|
19
19
|
entry[:version_constraints],
|
20
|
-
|
20
|
+
cache,
|
21
21
|
cwd,
|
22
22
|
entry[:resolved_source].merge(backend: backend))
|
23
23
|
|
24
24
|
locked_deps = []
|
25
25
|
Array(entry[:dependencies]).each do |dep_entry|
|
26
|
-
locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd,
|
26
|
+
locked_deps << Inspec::Requirement.from_lock_entry(dep_entry, cwd, cache, backend)
|
27
27
|
end
|
28
28
|
req.lock_deps(locked_deps)
|
29
29
|
req
|
30
30
|
end
|
31
31
|
|
32
32
|
attr_reader :cwd, :opts, :required_version
|
33
|
-
def initialize(name, version_constraints,
|
33
|
+
def initialize(name, version_constraints, cache, cwd, opts)
|
34
34
|
@name = name
|
35
35
|
@required_version = Gem::Requirement.new(Array(version_constraints))
|
36
|
-
@
|
36
|
+
@cache = cache
|
37
37
|
@backend = opts[:backend]
|
38
38
|
@opts = opts
|
39
39
|
@cwd = cwd
|
@@ -74,7 +74,6 @@ module Inspec
|
|
74
74
|
h['dependencies'] = dependencies.map(&:to_hash)
|
75
75
|
end
|
76
76
|
|
77
|
-
h['content_hash'] = content_hash if content_hash
|
78
77
|
h
|
79
78
|
end
|
80
79
|
|
@@ -82,15 +81,6 @@ module Inspec
|
|
82
81
|
@dependencies = dep_array
|
83
82
|
end
|
84
83
|
|
85
|
-
def content_hash
|
86
|
-
@content_hash ||= begin
|
87
|
-
archive_path = @vendor_index.archive_entry_for(fetcher.cache_key) || fetcher.archive_path
|
88
|
-
if archive_path && File.file?(archive_path)
|
89
|
-
Digest::SHA256.hexdigest File.read(archive_path)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
84
|
def fetcher
|
95
85
|
@fetcher ||= Inspec::Fetcher.resolve(opts)
|
96
86
|
fail "No fetcher for #{name} (options: #{opts})" if @fetcher.nil?
|
@@ -99,7 +89,7 @@ module Inspec
|
|
99
89
|
|
100
90
|
def dependencies
|
101
91
|
@dependencies ||= profile.metadata.dependencies.map do |r|
|
102
|
-
Inspec::Requirement.from_metadata(r, @
|
92
|
+
Inspec::Requirement.from_metadata(r, @cache, cwd: @cwd, backend: @backend)
|
103
93
|
end
|
104
94
|
end
|
105
95
|
|
@@ -109,10 +99,10 @@ module Inspec
|
|
109
99
|
|
110
100
|
def profile
|
111
101
|
opts = @opts.dup
|
112
|
-
opts[:cache] = @
|
102
|
+
opts[:cache] = @cache
|
113
103
|
opts[:backend] = @backend
|
114
104
|
if !@dependencies.nil?
|
115
|
-
opts[:dependencies] = Inspec::DependencySet.from_array(@dependencies, @cwd, @
|
105
|
+
opts[:dependencies] = Inspec::DependencySet.from_array(@dependencies, @cwd, @cache, @backend)
|
116
106
|
end
|
117
107
|
@profile ||= Inspec::Profile.for_target(opts, opts)
|
118
108
|
end
|
@@ -23,9 +23,9 @@ module Inspec
|
|
23
23
|
# implementation of the fetcher being used.
|
24
24
|
#
|
25
25
|
class Resolver
|
26
|
-
def self.resolve(dependencies,
|
26
|
+
def self.resolve(dependencies, cache, working_dir, backend)
|
27
27
|
reqs = dependencies.map do |dep|
|
28
|
-
req = Inspec::Requirement.from_metadata(dep,
|
28
|
+
req = Inspec::Requirement.from_metadata(dep, cache, cwd: working_dir, backend: backend)
|
29
29
|
req || fail("Cannot initialize dependency: #{req}")
|
30
30
|
end
|
31
31
|
new.resolve(reqs)
|
data/lib/inspec/dsl.rb
CHANGED
@@ -18,6 +18,15 @@ module Inspec::DSL
|
|
18
18
|
alias require_rules require_controls
|
19
19
|
alias include_rules include_controls
|
20
20
|
|
21
|
+
def require_resource(options = {})
|
22
|
+
fail 'You must specify a specific resource name when calling require_resource()' if options[:resource].nil?
|
23
|
+
|
24
|
+
from_profile = options[:profile] || profile_name
|
25
|
+
target_name = options[:as] || options[:resource]
|
26
|
+
res = resource_class(from_profile, options[:resource])
|
27
|
+
add_resource(target_name, res)
|
28
|
+
end
|
29
|
+
|
21
30
|
def self.load_spec_files_for_profile(bind_context, opts, &block)
|
22
31
|
dependencies = opts[:dependencies]
|
23
32
|
profile_id = opts[:profile_id]
|
data/lib/inspec/fetcher.rb
CHANGED
@@ -16,7 +16,7 @@ module Inspec
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache].freeze
|
19
|
+
NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache, :sha256].freeze
|
20
20
|
def fetcher_specified?(target)
|
21
21
|
# Only set a default for Hash-based (i.e. from
|
22
22
|
# inspec.yml/inspec.lock) targets
|
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,10 @@ module Inspec
|
|
24
24
|
Inspec::Fetcher
|
25
25
|
end
|
26
26
|
|
27
|
+
def writable?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
27
31
|
#
|
28
32
|
# The path to the archive on disk. This can be passed to a
|
29
33
|
# FileProvider to get access to the files in the fetched
|
@@ -56,6 +60,13 @@ module Inspec
|
|
56
60
|
fail "Fetcher #{self} does not implement `resolved_source()`. This is required for terminal fetchers."
|
57
61
|
end
|
58
62
|
|
63
|
+
#
|
64
|
+
# The unique key based on the content of the remote archive.
|
65
|
+
#
|
66
|
+
def cache_key
|
67
|
+
fail "Fetcher #{self} does not implement `cache_key()`. This is required for terminal fetchers."
|
68
|
+
end
|
69
|
+
|
59
70
|
#
|
60
71
|
# relative_target is provided to keep compatibility with 3rd
|
61
72
|
# party plugins.
|
@@ -69,18 +80,6 @@ module Inspec
|
|
69
80
|
file_provider = Inspec::FileProvider.for_path(archive_path)
|
70
81
|
file_provider.relative_provider
|
71
82
|
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
83
|
end
|
85
84
|
end
|
86
85
|
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
@@ -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
|
|
@@ -21,19 +21,44 @@ module Inspec
|
|
21
21
|
class Profile # rubocop:disable Metrics/ClassLength
|
22
22
|
extend Forwardable
|
23
23
|
|
24
|
+
#
|
25
|
+
# TODO: This function is getting pretty gross.
|
26
|
+
#
|
24
27
|
def self.resolve_target(target, cache = nil)
|
25
|
-
cache ||=
|
28
|
+
cache ||= Cache.new
|
26
29
|
fetcher = Inspec::Fetcher.resolve(target)
|
30
|
+
|
27
31
|
if fetcher.nil?
|
28
32
|
fail("Could not fetch inspec profile in #{target.inspect}.")
|
29
33
|
end
|
30
34
|
|
31
|
-
if
|
35
|
+
cache_key = if target.is_a?(Hash)
|
36
|
+
target[:sha256] || target[:ref] || fetcher.cache_key
|
37
|
+
else
|
38
|
+
fetcher.cache_key
|
39
|
+
end
|
40
|
+
|
41
|
+
if cache.exists?(cache_key)
|
32
42
|
Inspec::Log.debug "Using cached dependency for #{target}"
|
33
|
-
cache.prefered_entry_for(
|
43
|
+
[cache.prefered_entry_for(cache_key), false]
|
34
44
|
else
|
35
45
|
fetcher.fetch(cache.base_path_for(fetcher.cache_key))
|
36
|
-
|
46
|
+
if target.respond_to?(:key?) && target.key?(:sha256)
|
47
|
+
if fetcher.resolved_source[:sha256] != target[:sha256]
|
48
|
+
fail <<EOF
|
49
|
+
The remote source #{fetcher} no longer has the requested content:
|
50
|
+
|
51
|
+
Request Content Hash: #{target[:sha256]}
|
52
|
+
Actual Content Hash: #{fetcher.resolved_source[:sha256]}
|
53
|
+
|
54
|
+
For URL, supermarket, compliance, and other sources that do not
|
55
|
+
provide versioned artifacts, this likely means that the remote source
|
56
|
+
has changed since your lockfile was generated.
|
57
|
+
EOF
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
[fetcher.archive_path, fetcher.writable?]
|
37
62
|
end
|
38
63
|
end
|
39
64
|
|
@@ -48,7 +73,8 @@ module Inspec
|
|
48
73
|
end
|
49
74
|
|
50
75
|
def self.for_target(target, opts = {})
|
51
|
-
|
76
|
+
path, writable = resolve_target(target, opts[:cache])
|
77
|
+
for_path(path, opts.merge(target: target, writable: writable))
|
52
78
|
end
|
53
79
|
|
54
80
|
attr_reader :source_reader, :backend, :runner_context
|
@@ -62,10 +88,13 @@ module Inspec
|
|
62
88
|
@logger = options[:logger] || Logger.new(nil)
|
63
89
|
@locked_dependencies = options[:dependencies]
|
64
90
|
@controls = options[:controls] || []
|
91
|
+
@writable = options[:writable] || false
|
65
92
|
@profile_id = options[:id]
|
93
|
+
@cache = options[:cache] || Cache.new
|
66
94
|
@backend = options[:backend] || Inspec::Backend.create(options)
|
67
95
|
@source_reader = source_reader
|
68
96
|
@tests_collected = false
|
97
|
+
@libraries_loaded = false
|
69
98
|
Metadata.finalize(@source_reader.metadata, @profile_id)
|
70
99
|
@runner_context = options[:profile_context] || Inspec::ProfileContext.for_profile(self,
|
71
100
|
@backend,
|
@@ -80,6 +109,10 @@ module Inspec
|
|
80
109
|
metadata.params[:version]
|
81
110
|
end
|
82
111
|
|
112
|
+
def writable? # rubocop:disable Style/TrivialAccessors
|
113
|
+
@writable
|
114
|
+
end
|
115
|
+
|
83
116
|
#
|
84
117
|
# Is this profile is supported on the current platform of the
|
85
118
|
# backend machine and the current inspec version.
|
@@ -125,6 +158,8 @@ module Inspec
|
|
125
158
|
end
|
126
159
|
|
127
160
|
def load_libraries
|
161
|
+
return @runner_context if @libraries_loaded
|
162
|
+
|
128
163
|
locked_dependencies.each do |d|
|
129
164
|
c = d.load_libraries
|
130
165
|
@runner_context.add_resources(c)
|
@@ -135,6 +170,7 @@ module Inspec
|
|
135
170
|
end
|
136
171
|
|
137
172
|
@runner_context.load_libraries(libs)
|
173
|
+
@libraries_loaded = true
|
138
174
|
@runner_context
|
139
175
|
end
|
140
176
|
|
@@ -142,19 +178,29 @@ module Inspec
|
|
142
178
|
"Inspec::Profile<#{name}>"
|
143
179
|
end
|
144
180
|
|
145
|
-
|
146
|
-
|
181
|
+
# return info using uncached params
|
182
|
+
def info!
|
183
|
+
info(load_params.dup)
|
184
|
+
end
|
185
|
+
|
186
|
+
def info(res = params.dup)
|
147
187
|
# add information about the controls
|
148
|
-
controls = res[:controls].map do |id, rule|
|
188
|
+
res[:controls] = res[:controls].map do |id, rule|
|
149
189
|
next if id.to_s.empty?
|
150
190
|
data = rule.dup
|
151
191
|
data.delete(:checks)
|
152
192
|
data[:impact] ||= 0.5
|
153
193
|
data[:impact] = 1.0 if data[:impact] > 1.0
|
154
194
|
data[:impact] = 0.0 if data[:impact] < 0.0
|
155
|
-
[id
|
195
|
+
data[:id] = id
|
196
|
+
data
|
197
|
+
end.compact
|
198
|
+
|
199
|
+
# resolve hash structure in groups
|
200
|
+
res[:groups] = res[:groups].map do |id, group|
|
201
|
+
group[:id] = id
|
202
|
+
group
|
156
203
|
end
|
157
|
-
res[:controls] = Hash[controls.compact]
|
158
204
|
|
159
205
|
# add information about the required attributes
|
160
206
|
res[:attributes] = res[:attributes].map(&:to_hash) unless res[:attributes].nil? || res[:attributes].empty?
|
@@ -329,14 +375,14 @@ module Inspec
|
|
329
375
|
# @param vendor_path [String] Path to the on-disk vendor dir
|
330
376
|
# @return [Inspec::Lockfile]
|
331
377
|
#
|
332
|
-
def generate_lockfile
|
333
|
-
res = Inspec::DependencySet.new(cwd,
|
378
|
+
def generate_lockfile
|
379
|
+
res = Inspec::DependencySet.new(cwd, @cache, nil, @backend)
|
334
380
|
res.vendor(metadata.dependencies)
|
335
381
|
Inspec::Lockfile.from_dependency_set(res)
|
336
382
|
end
|
337
383
|
|
338
384
|
def load_dependencies
|
339
|
-
Inspec::DependencySet.from_lockfile(lockfile, cwd,
|
385
|
+
Inspec::DependencySet.from_lockfile(lockfile, cwd, @cache, @backend)
|
340
386
|
end
|
341
387
|
|
342
388
|
private
|