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