inspec-core 4.18.51 → 4.18.85
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +61 -0
- data/README.md +3 -3
- data/inspec-core.gemspec +51 -0
- data/lib/bundles/inspec-supermarket/cli.rb +1 -0
- data/lib/inspec/backend.rb +49 -47
- data/lib/inspec/base_cli.rb +2 -2
- data/lib/inspec/cached_fetcher.rb +4 -0
- data/lib/inspec/cli.rb +5 -0
- data/lib/inspec/config.rb +1 -1
- data/lib/inspec/control_eval_context.rb +131 -199
- data/lib/inspec/dependencies/requirement.rb +1 -1
- data/lib/inspec/dependencies/resolver.rb +46 -0
- data/lib/inspec/dsl_shared.rb +25 -3
- data/lib/inspec/fetcher.rb +0 -3
- data/lib/inspec/fetcher/git.rb +4 -0
- data/lib/inspec/fetcher/url.rb +1 -2
- data/lib/inspec/file_provider.rb +4 -2
- data/lib/inspec/library_eval_context.rb +37 -37
- data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +27 -0
- data/lib/inspec/plugin/v1/plugins.rb +0 -1
- data/lib/inspec/profile.rb +8 -6
- data/lib/inspec/profile_context.rb +74 -9
- data/lib/inspec/profile_vendor.rb +48 -3
- data/lib/inspec/resource.rb +192 -41
- data/lib/inspec/resources/aide_conf.rb +1 -1
- data/lib/inspec/resources/apache_conf.rb +15 -31
- data/lib/inspec/resources/command.rb +1 -1
- data/lib/inspec/resources/crontab.rb +56 -56
- data/lib/inspec/resources/etc_fstab.rb +1 -1
- data/lib/inspec/resources/etc_group.rb +1 -1
- data/lib/inspec/resources/etc_hosts.rb +2 -3
- data/lib/inspec/resources/etc_hosts_allow_deny.rb +1 -1
- data/lib/inspec/resources/file.rb +2 -2
- data/lib/inspec/resources/filesystem.rb +4 -4
- data/lib/inspec/resources/groups.rb +16 -2
- data/lib/inspec/resources/iis_app.rb +1 -1
- data/lib/inspec/resources/ini.rb +1 -2
- data/lib/inspec/resources/mount.rb +2 -2
- data/lib/inspec/resources/oracledb_session.rb +1 -1
- data/lib/inspec/resources/package.rb +22 -0
- data/lib/inspec/resources/passwd.rb +1 -1
- data/lib/inspec/resources/platform.rb +36 -36
- data/lib/inspec/resources/port.rb +1 -1
- data/lib/inspec/resources/postfix_conf.rb +1 -1
- data/lib/inspec/resources/service.rb +23 -15
- data/lib/inspec/resources/users.rb +3 -3
- data/lib/inspec/resources/virtualization.rb +15 -11
- data/lib/inspec/resources/x509_certificate.rb +18 -4
- data/lib/inspec/resources/xinetd_conf.rb +1 -1
- data/lib/inspec/resources/xml.rb +1 -2
- data/lib/inspec/rspec_extensions.rb +12 -0
- data/lib/inspec/rule.rb +63 -22
- data/lib/inspec/utils/filter.rb +2 -0
- data/lib/inspec/utils/parser.rb +244 -240
- data/lib/inspec/utils/simpleconfig.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +11 -10
- data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +3 -0
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb +2 -2
- data/lib/plugins/inspec-init/templates/profiles/aws/README.md +192 -0
- data/lib/plugins/inspec-init/templates/profiles/aws/attributes.yml +2 -0
- data/lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb +39 -0
- data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +22 -0
- data/lib/plugins/inspec-init/templates/profiles/azure/README.md +56 -0
- data/lib/plugins/inspec-init/templates/profiles/azure/controls/example.rb +14 -0
- data/lib/plugins/inspec-init/templates/profiles/azure/inspec.yml +14 -0
- data/lib/plugins/inspec-init/templates/profiles/gcp/README.md +66 -0
- data/lib/plugins/inspec-init/templates/profiles/gcp/attributes.yml +2 -0
- data/lib/plugins/inspec-init/templates/profiles/gcp/controls/example.rb +27 -0
- data/lib/plugins/inspec-init/templates/profiles/gcp/inspec.yml +19 -0
- data/lib/source_readers/inspec.rb +1 -1
- metadata +87 -74
- data/lib/inspec/plugin/v1/plugin_types/resource.rb +0 -176
- data/lib/plugins/inspec-init/templates/profiles/os/libraries/.gitkeep +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 367bf0fb9467148e5434036ec14c7ec9b9b9e560504758e0c72493bacc73270a
|
4
|
+
data.tar.gz: 352392686e13db1a8827f9d7aa29f3961c070fd0b66d7f8cdb7ab88513429f59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e237b06411e204f1a811c7cf5707ebed9082084f24e541fc94faea6e2e956ab671c2cdf1ab3ac2388e721129d151d06171791448501a71c760b426c2919567c
|
7
|
+
data.tar.gz: 11bdb33d12ef3890934c17bb5855001de5d0bce259f484e80b15ed3fed2b69639d509baab1a7f4690778c882ea1a11a6b50244a881cb883853eb6bfa77ec0866
|
data/Gemfile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "inspec", path: "."
|
4
|
+
|
5
|
+
# This dependency is NOT used for normal gem deployment
|
6
|
+
# - instead, inspec-bin gemspec-depends on inspec
|
7
|
+
#
|
8
|
+
# However, AppBundler requires a top-level Gemfile.lock with inspec-bin
|
9
|
+
# in it in order to package the executable. Hence the odd backwards dependency.
|
10
|
+
gem "inspec-bin", path: "./inspec-bin"
|
11
|
+
|
12
|
+
gem "ffi", ">= 1.9.14"
|
13
|
+
|
14
|
+
group :omnibus do
|
15
|
+
gem "rb-readline"
|
16
|
+
gem "appbundler"
|
17
|
+
gem "ed25519" # ed25519 ssh key support done here as its a native gem we can't put in the gemspec
|
18
|
+
gem "bcrypt_pbkdf" # ed25519 ssh key support done here as its a native gem we can't put in the gemspec
|
19
|
+
end
|
20
|
+
|
21
|
+
group :test do
|
22
|
+
gem "chefstyle", "~> 0.13.0"
|
23
|
+
gem "minitest", "~> 5.5"
|
24
|
+
gem "minitest-sprint", "~> 1.0"
|
25
|
+
gem "rake", ">= 10"
|
26
|
+
gem "simplecov", "~> 0.10"
|
27
|
+
gem "concurrent-ruby", "~> 1.0"
|
28
|
+
gem "mocha", "~> 1.1"
|
29
|
+
gem "ruby-progressbar", "~> 1.8"
|
30
|
+
gem "webmock", "~> 3.0"
|
31
|
+
gem "m"
|
32
|
+
gem "pry", "~> 0.10"
|
33
|
+
gem "pry-byebug"
|
34
|
+
end
|
35
|
+
|
36
|
+
group :integration do
|
37
|
+
gem "berkshelf"
|
38
|
+
gem "chef", "< 15"
|
39
|
+
gem "test-kitchen"
|
40
|
+
gem "kitchen-vagrant"
|
41
|
+
gem "kitchen-inspec"
|
42
|
+
gem "kitchen-ec2"
|
43
|
+
gem "kitchen-dokken"
|
44
|
+
gem "git"
|
45
|
+
end
|
46
|
+
|
47
|
+
# gems for Maintainers.md generation
|
48
|
+
group :maintenance do
|
49
|
+
gem "tomlrb"
|
50
|
+
|
51
|
+
# To sync maintainers with github
|
52
|
+
gem "octokit"
|
53
|
+
gem "netrc"
|
54
|
+
end
|
55
|
+
|
56
|
+
group :deploy do
|
57
|
+
gem "inquirer"
|
58
|
+
end
|
59
|
+
|
60
|
+
# add these additional dependencies into Gemfile.local
|
61
|
+
eval_gemfile(__FILE__ + ".local") if File.exist?(__FILE__ + ".local")
|
data/README.md
CHANGED
@@ -312,7 +312,7 @@ Remote Targets
|
|
312
312
|
| Oracle Enterprise Linux | 5, 6, 7 | i386, x86_64 |
|
313
313
|
| Red Hat Enterprise Linux | 5, 6, 7 | i386, x86_64 |
|
314
314
|
| Solaris | 10, 11 | sparc, x86 |
|
315
|
-
| Windows\* |
|
315
|
+
| Windows\* | 8, 8.1, 10, 2012, 2012R2, 2016 | x86, x86_64 |
|
316
316
|
| Ubuntu Linux | | x86, x86_64 |
|
317
317
|
| SUSE Linux Enterprise Server | 11, 12 | x86_64 |
|
318
318
|
| Scientific Linux | 5.x, 6.x and 7.x | i386, x86_64 |
|
@@ -332,7 +332,7 @@ In addition, runtime support is provided for:
|
|
332
332
|
| Debian | 8, 9 | x86_64 |
|
333
333
|
| RHEL | 6, 7 | x86_64 |
|
334
334
|
| Ubuntu | 12.04+ | x86_64 |
|
335
|
-
| Windows |
|
335
|
+
| Windows | 8+ | x86_64 |
|
336
336
|
| Windows | 2012+ | x86_64 |
|
337
337
|
|
338
338
|
## Documentation
|
@@ -449,7 +449,7 @@ Please see [TESTING_AGAINST_AWS.md](./test/integration/aws/TESTING_AGAINST_AWS.m
|
|
449
449
|
|
450
450
|
Use the rake task `bundle exec rake test:azure` to test the Azure resources against an Azure account.
|
451
451
|
|
452
|
-
Please see [TESTING_AGAINST_AZURE.md](./test/integration/
|
452
|
+
Please see [TESTING_AGAINST_AZURE.md](./test/integration/azure/TESTING_AGAINST_AZURE.md) for details on how to setup the needed Azure accounts to perform testing.
|
453
453
|
|
454
454
|
## License
|
455
455
|
|
data/inspec-core.gemspec
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "inspec/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "inspec-core"
|
7
|
+
spec.version = Inspec::VERSION
|
8
|
+
spec.authors = ["Chef InSpec Team"]
|
9
|
+
spec.email = ["inspec@chef.io"]
|
10
|
+
spec.summary = "Infrastructure and compliance testing. Core library."
|
11
|
+
spec.description = "InSpec provides a framework for creating end-to-end infrastructure tests. You can use it for integration or even compliance testing. Create fully portable test profiles and use them in your workflow to ensure stability and security. Integrate InSpec in your change lifecycle for local testing, CI/CD, and deployment verification. This has local support only. See the `inspec` gem for full support."
|
12
|
+
spec.homepage = "https://github.com/inspec/inspec"
|
13
|
+
spec.license = "Apache-2.0"
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
|
16
|
+
spec.required_ruby_version = "~> 2.4"
|
17
|
+
|
18
|
+
# the gemfile and gemspec are necessary for appbundler so don't remove it
|
19
|
+
spec.files =
|
20
|
+
Dir.glob("{{lib,etc}/**/*,README.md,LICENSE,Gemfile,inspec-core.gemspec}")
|
21
|
+
.grep_v(%r{(?<!inspec-init/templates/profiles/)(aws|azure|gcp)})
|
22
|
+
.grep_v(%r{lib/plugins/.*/test/})
|
23
|
+
.reject { |f| File.directory?(f) }
|
24
|
+
|
25
|
+
# Implementation dependencies
|
26
|
+
spec.add_dependency "chef-telemetry", "~> 1.0"
|
27
|
+
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
|
28
|
+
spec.add_dependency "thor", ">= 0.20", "< 2.0"
|
29
|
+
spec.add_dependency "json-schema", "~> 2.8"
|
30
|
+
spec.add_dependency "method_source", "~> 0.8"
|
31
|
+
spec.add_dependency "rubyzip", "~> 1.2", ">= 1.2.2"
|
32
|
+
spec.add_dependency "rspec", "~> 3.9"
|
33
|
+
spec.add_dependency "rspec-its", "~> 1.2"
|
34
|
+
spec.add_dependency "pry", "~> 0"
|
35
|
+
spec.add_dependency "hashie", "~> 3.4"
|
36
|
+
spec.add_dependency "mixlib-log", "~> 3.0"
|
37
|
+
spec.add_dependency "sslshake", "~> 1.2"
|
38
|
+
spec.add_dependency "parallel", "~> 1.9"
|
39
|
+
spec.add_dependency "faraday", ">= 0.9.0"
|
40
|
+
spec.add_dependency "tty-table", "~> 0.10"
|
41
|
+
spec.add_dependency "tty-prompt", "~> 0.17"
|
42
|
+
spec.add_dependency "tomlrb", "~> 1.2"
|
43
|
+
spec.add_dependency "addressable", "~> 2.4"
|
44
|
+
spec.add_dependency "parslet", "~> 1.5"
|
45
|
+
spec.add_dependency "semverse", "~> 3.0"
|
46
|
+
spec.add_dependency "htmlentities", "~> 4.3" # TODO: remove when #4853 fixed
|
47
|
+
spec.add_dependency "multipart-post", "~> 2.0"
|
48
|
+
spec.add_dependency "term-ansicolor", "~> 1.7"
|
49
|
+
|
50
|
+
spec.add_dependency "train-core", "~> 3.0"
|
51
|
+
end
|
data/lib/inspec/backend.rb
CHANGED
@@ -7,34 +7,19 @@ require "inspec/resource"
|
|
7
7
|
require "inspec/dsl" # for method_missing_resource
|
8
8
|
|
9
9
|
module Inspec
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
class Backend
|
11
|
+
attr_accessor :backend
|
12
|
+
attr_accessor :profile
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def version
|
18
|
-
Inspec::VERSION
|
19
|
-
end
|
20
|
-
|
21
|
-
# Determine whether the connection/transport is a local connection
|
22
|
-
# Useful for resources to modify behavior as necessary, such as using
|
23
|
-
# the Ruby stdlib for a better experience.
|
24
|
-
def local_transport?
|
25
|
-
return false unless defined?(Train::Transports::Local)
|
26
|
-
|
27
|
-
backend.is_a?(Train::Transports::Local::Connection)
|
28
|
-
end
|
14
|
+
# Creates a bunch of predefined resource methods based on the
|
15
|
+
# current registry at the time. See #method_missing for what else
|
16
|
+
# can happen.
|
29
17
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# Ruby internal for pretty-printing a summary for this class
|
36
|
-
def inspect
|
37
|
-
"Inspec::Backend::Class @transport=#{backend.class}"
|
18
|
+
def self.add_resource_methods # TODO: remove
|
19
|
+
Inspec::Resource.registry.each do |id, r|
|
20
|
+
define_method id.to_sym do |*args|
|
21
|
+
r.new(self, id.to_s, *args)
|
22
|
+
end
|
38
23
|
end
|
39
24
|
end
|
40
25
|
|
@@ -71,31 +56,48 @@ module Inspec
|
|
71
56
|
connection.disable_cache(:command)
|
72
57
|
end
|
73
58
|
|
74
|
-
|
75
|
-
include Base
|
76
|
-
|
77
|
-
define_method :backend do
|
78
|
-
connection
|
79
|
-
end
|
80
|
-
|
81
|
-
def method_missing(id, *args, &blk)
|
82
|
-
Inspec::DSL.method_missing_resource(self, id, *args)
|
83
|
-
rescue LoadError
|
84
|
-
super
|
85
|
-
end
|
86
|
-
|
87
|
-
Inspec::Resource.registry.each do |id, r|
|
88
|
-
define_method id.to_sym do |*args|
|
89
|
-
r.new(self, id.to_s, *args)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
cls.new
|
59
|
+
Inspec::Backend.new(connection)
|
95
60
|
rescue Train::ClientError => e
|
96
61
|
raise "Client error, can't connect to '#{transport_name}' backend: #{e.message}"
|
97
62
|
rescue Train::TransportError => e
|
98
63
|
raise "Transport error, can't connect to '#{transport_name}' backend: #{e.message}"
|
99
64
|
end
|
65
|
+
|
66
|
+
def initialize(backend)
|
67
|
+
self.backend = backend
|
68
|
+
self.class.add_resource_methods
|
69
|
+
end
|
70
|
+
|
71
|
+
# Provide a shorthand to retrieve the inspec version from within a profile
|
72
|
+
#
|
73
|
+
# @return [String] inspec version
|
74
|
+
def version
|
75
|
+
Inspec::VERSION
|
76
|
+
end
|
77
|
+
|
78
|
+
# Determine whether the connection/transport is a local connection
|
79
|
+
# Useful for resources to modify behavior as necessary, such as using
|
80
|
+
# the Ruby stdlib for a better experience.
|
81
|
+
def local_transport?
|
82
|
+
return false unless defined?(Train::Transports::Local)
|
83
|
+
|
84
|
+
backend.is_a?(Train::Transports::Local::Connection)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Ruby internal for printing a nice name for this class
|
88
|
+
def to_s
|
89
|
+
"Inspec::Backend::Class"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Ruby internal for pretty-printing a summary for this class
|
93
|
+
def inspect
|
94
|
+
"Inspec::Backend::Class @transport=#{backend.class}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def method_missing(id, *args, &blk)
|
98
|
+
Inspec::DSL.method_missing_resource(self, id, *args)
|
99
|
+
rescue LoadError
|
100
|
+
super
|
101
|
+
end
|
100
102
|
end
|
101
103
|
end
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -101,7 +101,7 @@ module Inspec
|
|
101
101
|
desc: "Specify which transport to use, defaults to negotiate (WinRM)."
|
102
102
|
option :winrm_disable_sspi, type: :boolean,
|
103
103
|
desc: "Whether to use disable sspi authentication, defaults to false (WinRM)."
|
104
|
-
option :
|
104
|
+
option :winrm_basic_auth_only, type: :boolean,
|
105
105
|
desc: "Whether to use basic authentication, defaults to false (WinRM)."
|
106
106
|
option :config, type: :string,
|
107
107
|
desc: "Read configuration from JSON file (`-` reads from stdin)."
|
@@ -284,7 +284,7 @@ module Inspec
|
|
284
284
|
return false
|
285
285
|
end
|
286
286
|
|
287
|
-
profile_vendor.vendor!
|
287
|
+
profile_vendor.vendor!(opts)
|
288
288
|
puts "Dependencies for profile #{profile_path} successfully vendored to #{profile_vendor.cache_path}"
|
289
289
|
rescue StandardError => e
|
290
290
|
pretty_handle_exception(e)
|
data/lib/inspec/cli.rb
CHANGED
@@ -173,6 +173,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
173
173
|
desc: "Generates a tar.gz archive."
|
174
174
|
option :overwrite, type: :boolean, default: false,
|
175
175
|
desc: "Overwrite existing archive."
|
176
|
+
option :airgap, type: :boolean, banner: "",
|
177
|
+
desc: "Fallback to using local archives if fetching fails."
|
176
178
|
option :ignore_errors, type: :boolean, default: false,
|
177
179
|
desc: "Ignore profile warnings."
|
178
180
|
def archive(path)
|
@@ -327,11 +329,14 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
327
329
|
desc: "A space-delimited list of local folders containing profiles whose libraries and resources will be loaded into the new shell"
|
328
330
|
option :distinct_exit, type: :boolean, default: true,
|
329
331
|
desc: "Exit with code 100 if any tests fail, and 101 if any are skipped but none failed (default). If disabled, exit 0 on skips and 1 for failures."
|
332
|
+
option :inspect, type: :boolean, default: false, desc: "Use verbose/debugging output for resources."
|
330
333
|
def shell_func
|
331
334
|
o = config
|
332
335
|
diagnose(o)
|
333
336
|
o[:debug_shell] = true
|
334
337
|
|
338
|
+
Inspec::Resource.toggle_inspect unless o[:inspect]
|
339
|
+
|
335
340
|
log_device = suppress_log_output?(o) ? nil : $stdout
|
336
341
|
o[:logger] = Logger.new(log_device)
|
337
342
|
o[:logger].level = get_log_level(o[:log_level])
|
data/lib/inspec/config.rb
CHANGED
@@ -12,236 +12,168 @@ module Inspec
|
|
12
12
|
# etc).
|
13
13
|
#
|
14
14
|
class ControlEvalContext
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
15
|
+
include Inspec::DSL
|
16
|
+
include Inspec::DSL::RequireOverride
|
17
|
+
|
18
|
+
attr_accessor :skip_file
|
19
|
+
attr_accessor :profile_context
|
20
|
+
attr_accessor :resources_dsl
|
21
|
+
|
22
|
+
def initialize(profile_context, resources_dsl, backend, conf, dependencies, require_loader, skip_only_if_eval)
|
23
|
+
@profile_context = profile_context
|
24
|
+
@resources_dsl = resources_dsl
|
25
|
+
@backend = backend
|
26
|
+
@conf = conf
|
27
|
+
@dependencies = dependencies
|
28
|
+
@require_loader = require_loader
|
29
|
+
@skip_file_message = nil
|
30
|
+
@skip_file = false
|
31
|
+
@skip_only_if_eval = skip_only_if_eval
|
32
|
+
|
33
|
+
extend resources_dsl # TODO: remove? push to method_missing?
|
34
|
+
end
|
37
35
|
|
38
|
-
|
39
|
-
# Will return nil on a miss.
|
40
|
-
define_method :input_object do |input_name|
|
41
|
-
Inspec::InputRegistry.find_or_register_input(input_name, profile_id)
|
42
|
-
end
|
36
|
+
alias profile_context_owner profile_context
|
43
37
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
38
|
+
def profile_id
|
39
|
+
profile_context.profile_id
|
40
|
+
end
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
def method_missing(method_name, *arguments, &block)
|
53
|
-
# Check to see if there is a control_dsl plugin activator hook with the method name
|
54
|
-
registry = Inspec::Plugin::V2::Registry.instance
|
55
|
-
hook = registry.find_activators(plugin_type: :control_dsl, activator_name: method_name).first
|
56
|
-
if hook
|
57
|
-
# OK, load the hook if it hasn't been already. We'll then know a module,
|
58
|
-
# which we can then inject into the context
|
59
|
-
hook.activate
|
60
|
-
|
61
|
-
# Inject the module's methods into the context.
|
62
|
-
# implementation_class is the field name, but this is actually a module.
|
63
|
-
self.class.include(hook.implementation_class)
|
64
|
-
# Now that the module is loaded, it defined one or more methods
|
65
|
-
# (presumably the one we were looking for.)
|
66
|
-
# We still haven't called it, so do so now.
|
67
|
-
send(method_name, *arguments, &block)
|
68
|
-
else
|
69
|
-
begin
|
70
|
-
Inspec::DSL.method_missing_resource(inspec, method_name, *arguments)
|
71
|
-
rescue LoadError
|
72
|
-
super
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
42
|
+
def to_s
|
43
|
+
"Control Evaluation Context (#{profile_name})"
|
44
|
+
end
|
76
45
|
|
77
|
-
|
46
|
+
def title(arg)
|
47
|
+
profile_context_owner.set_header(:title, arg)
|
78
48
|
end
|
79
49
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# and exposes them to the a test file.
|
84
|
-
#
|
85
|
-
# @param profile_context [Inspec::ProfileContext]
|
86
|
-
# @param outer_dsl [OuterDSLClass]
|
87
|
-
# @return [ProfileContextClass]
|
88
|
-
def self.create(profile_context, resources_dsl) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
89
|
-
profile_context_owner = profile_context
|
90
|
-
profile_id = profile_context.profile_id
|
91
|
-
rule_class = rule_context(resources_dsl, profile_id)
|
92
|
-
Class.new do # rubocop:disable Metrics/BlockLength
|
93
|
-
include Inspec::DSL
|
94
|
-
include Inspec::DSL::RequireOverride
|
95
|
-
include resources_dsl
|
96
|
-
|
97
|
-
attr_accessor :skip_file
|
98
|
-
|
99
|
-
def initialize(backend, conf, dependencies, require_loader, skip_only_if_eval)
|
100
|
-
@backend = backend
|
101
|
-
@conf = conf
|
102
|
-
@dependencies = dependencies
|
103
|
-
@require_loader = require_loader
|
104
|
-
@skip_file_message = nil
|
105
|
-
@skip_file = false
|
106
|
-
@skip_only_if_eval = skip_only_if_eval
|
107
|
-
end
|
50
|
+
def profile_name
|
51
|
+
profile_id
|
52
|
+
end
|
108
53
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
54
|
+
def control(id, opts = {}, &block)
|
55
|
+
opts[:skip_only_if_eval] = @skip_only_if_eval
|
112
56
|
|
113
|
-
|
114
|
-
|
115
|
-
|
57
|
+
register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
|
58
|
+
end
|
59
|
+
alias rule control
|
116
60
|
|
117
|
-
|
118
|
-
|
119
|
-
|
61
|
+
# Describe allows users to write rspec-like bare describe
|
62
|
+
# blocks without declaring an inclosing control. Here, we
|
63
|
+
# generate a control for them automatically and then execute
|
64
|
+
# the describe block in the context of that control.
|
65
|
+
#
|
66
|
+
def describe(*args, &block)
|
67
|
+
loc = block_location(block, caller(1..1).first)
|
68
|
+
id = "(generated from #{loc} #{SecureRandom.hex})"
|
120
69
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
70
|
+
res = nil
|
71
|
+
rule = Inspec::Rule.new(id, profile_id, resources_dsl, {}) do
|
72
|
+
res = describe(*args, &block)
|
73
|
+
end
|
74
|
+
register_control(rule, &block)
|
127
75
|
|
128
|
-
|
129
|
-
|
130
|
-
# blocks without declaring an inclosing control. Here, we
|
131
|
-
# generate a control for them automatically and then execute
|
132
|
-
# the describe block in the context of that control.
|
133
|
-
#
|
134
|
-
define_method :describe do |*args, &block|
|
135
|
-
loc = block_location(block, caller(1..1).first)
|
136
|
-
id = "(generated from #{loc} #{SecureRandom.hex})"
|
137
|
-
|
138
|
-
res = nil
|
139
|
-
rule = rule_class.new(id, profile_id, {}) do
|
140
|
-
res = describe(*args, &block)
|
141
|
-
end
|
142
|
-
register_control(rule, &block)
|
143
|
-
|
144
|
-
res
|
145
|
-
end
|
76
|
+
res
|
77
|
+
end
|
146
78
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
152
|
-
end
|
79
|
+
def add_resource(name, new_res)
|
80
|
+
resources_dsl.module_exec do
|
81
|
+
define_method name.to_sym do |*args|
|
82
|
+
new_res.new(@backend, name.to_s, *args)
|
153
83
|
end
|
84
|
+
end
|
85
|
+
end
|
154
86
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
87
|
+
def add_resources(context)
|
88
|
+
# # TODO: write real unit tests for this and then make this change:
|
89
|
+
# dsl = context.to_resources_dsl
|
90
|
+
# self.class.include dsl
|
91
|
+
# Inspec::Rule.include dsl
|
159
92
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
93
|
+
self.class.class_eval do
|
94
|
+
include context.to_resources_dsl
|
95
|
+
end
|
164
96
|
|
165
|
-
|
166
|
-
|
167
|
-
|
97
|
+
# TODO: seriously consider getting rid of the NPM model
|
98
|
+
extend context.to_resources_dsl
|
99
|
+
end
|
168
100
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
101
|
+
def add_subcontext(context)
|
102
|
+
profile_context_owner.add_subcontext(context)
|
103
|
+
end
|
173
104
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
105
|
+
def register_control(control, &block)
|
106
|
+
if @skip_file
|
107
|
+
::Inspec::Rule.set_skip_rule(control, true, @skip_file_message)
|
108
|
+
end
|
179
109
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
110
|
+
unless profile_context_owner.profile_supports_platform?
|
111
|
+
platform = inspec.platform
|
112
|
+
msg = "Profile `#{profile_id}` is not supported on platform #{platform.name}/#{platform.release}."
|
113
|
+
::Inspec::Rule.set_skip_rule(control, true, msg)
|
114
|
+
end
|
184
115
|
|
185
|
-
|
186
|
-
|
116
|
+
unless profile_context_owner.profile_supports_inspec_version?
|
117
|
+
msg = "Profile `#{profile_id}` is not supported on InSpec version (#{Inspec::VERSION})."
|
118
|
+
::Inspec::Rule.set_skip_rule(control, true, msg)
|
119
|
+
end
|
187
120
|
|
188
|
-
|
189
|
-
|
190
|
-
# Simply an access, no event here
|
191
|
-
Inspec::InputRegistry.find_or_register_input(input_name, profile_id).value
|
192
|
-
else
|
193
|
-
options[:priority] ||= 20
|
194
|
-
options[:provider] = :inline_control_code
|
195
|
-
evt = Inspec::Input.infer_event(options)
|
196
|
-
Inspec::InputRegistry.find_or_register_input(input_name, profile_id, event: evt).value
|
197
|
-
end
|
198
|
-
end
|
121
|
+
profile_context_owner.register_rule(control, &block) unless control.nil?
|
122
|
+
end
|
199
123
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
124
|
+
def input(input_name, options = {})
|
125
|
+
if options.empty?
|
126
|
+
# Simply an access, no event here
|
127
|
+
Inspec::InputRegistry.find_or_register_input(input_name, profile_id).value
|
128
|
+
else
|
129
|
+
options[:priority] ||= 20
|
130
|
+
options[:provider] = :inline_control_code
|
131
|
+
evt = Inspec::Input.infer_event(options)
|
132
|
+
Inspec::InputRegistry.find_or_register_input(input_name, profile_id, event: evt).value
|
133
|
+
end
|
134
|
+
end
|
205
135
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
136
|
+
# Find the Input object, but don't collapse to a value.
|
137
|
+
# Will return nil on a miss.
|
138
|
+
def input_object(input_name)
|
139
|
+
Inspec::InputRegistry.find_or_register_input(input_name, profile_id)
|
140
|
+
end
|
210
141
|
|
211
|
-
|
212
|
-
|
213
|
-
|
142
|
+
def attribute(name, options = {})
|
143
|
+
Inspec.deprecate(:attrs_dsl, "Input name: #{name}, Profile: #{profile_id}")
|
144
|
+
input(name, options)
|
145
|
+
end
|
214
146
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
147
|
+
def skip_control(id)
|
148
|
+
profile_context_owner.unregister_rule(id)
|
149
|
+
end
|
150
|
+
alias skip_rule skip_control
|
219
151
|
|
220
|
-
|
152
|
+
def only_if(message = nil, &block)
|
153
|
+
return unless block
|
154
|
+
return if @skip_file == true
|
155
|
+
return if @skip_only_if_eval == true
|
221
156
|
|
222
|
-
|
223
|
-
profile_context_owner.rules.values.each do |r|
|
224
|
-
sources_match = r.source_file == block.source_location[0]
|
225
|
-
Inspec::Rule.set_skip_rule(r, true, message) if sources_match
|
226
|
-
end
|
157
|
+
return if block.yield == true
|
227
158
|
|
228
|
-
|
229
|
-
|
230
|
-
|
159
|
+
# Apply `set_skip_rule` for other rules in the same file
|
160
|
+
profile_context_owner.rules.values.each do |r|
|
161
|
+
sources_match = r.source_file == block.source_location[0]
|
162
|
+
Inspec::Rule.set_skip_rule(r, true, message) if sources_match
|
163
|
+
end
|
231
164
|
|
232
|
-
|
233
|
-
|
165
|
+
@skip_file_message = message
|
166
|
+
@skip_file = true
|
167
|
+
end
|
234
168
|
|
235
|
-
|
169
|
+
private
|
236
170
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
end
|
244
|
-
end
|
171
|
+
def block_location(block, alternate_caller)
|
172
|
+
if block.nil?
|
173
|
+
alternate_caller[/^(.+:\d+):in .+$/, 1] || "unknown"
|
174
|
+
else
|
175
|
+
path, line = block.source_location
|
176
|
+
"#{File.basename(path)}:#{line}"
|
245
177
|
end
|
246
178
|
end
|
247
179
|
end
|