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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +61 -0
  3. data/README.md +3 -3
  4. data/inspec-core.gemspec +51 -0
  5. data/lib/bundles/inspec-supermarket/cli.rb +1 -0
  6. data/lib/inspec/backend.rb +49 -47
  7. data/lib/inspec/base_cli.rb +2 -2
  8. data/lib/inspec/cached_fetcher.rb +4 -0
  9. data/lib/inspec/cli.rb +5 -0
  10. data/lib/inspec/config.rb +1 -1
  11. data/lib/inspec/control_eval_context.rb +131 -199
  12. data/lib/inspec/dependencies/requirement.rb +1 -1
  13. data/lib/inspec/dependencies/resolver.rb +46 -0
  14. data/lib/inspec/dsl_shared.rb +25 -3
  15. data/lib/inspec/fetcher.rb +0 -3
  16. data/lib/inspec/fetcher/git.rb +4 -0
  17. data/lib/inspec/fetcher/url.rb +1 -2
  18. data/lib/inspec/file_provider.rb +4 -2
  19. data/lib/inspec/library_eval_context.rb +37 -37
  20. data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +27 -0
  21. data/lib/inspec/plugin/v1/plugins.rb +0 -1
  22. data/lib/inspec/profile.rb +8 -6
  23. data/lib/inspec/profile_context.rb +74 -9
  24. data/lib/inspec/profile_vendor.rb +48 -3
  25. data/lib/inspec/resource.rb +192 -41
  26. data/lib/inspec/resources/aide_conf.rb +1 -1
  27. data/lib/inspec/resources/apache_conf.rb +15 -31
  28. data/lib/inspec/resources/command.rb +1 -1
  29. data/lib/inspec/resources/crontab.rb +56 -56
  30. data/lib/inspec/resources/etc_fstab.rb +1 -1
  31. data/lib/inspec/resources/etc_group.rb +1 -1
  32. data/lib/inspec/resources/etc_hosts.rb +2 -3
  33. data/lib/inspec/resources/etc_hosts_allow_deny.rb +1 -1
  34. data/lib/inspec/resources/file.rb +2 -2
  35. data/lib/inspec/resources/filesystem.rb +4 -4
  36. data/lib/inspec/resources/groups.rb +16 -2
  37. data/lib/inspec/resources/iis_app.rb +1 -1
  38. data/lib/inspec/resources/ini.rb +1 -2
  39. data/lib/inspec/resources/mount.rb +2 -2
  40. data/lib/inspec/resources/oracledb_session.rb +1 -1
  41. data/lib/inspec/resources/package.rb +22 -0
  42. data/lib/inspec/resources/passwd.rb +1 -1
  43. data/lib/inspec/resources/platform.rb +36 -36
  44. data/lib/inspec/resources/port.rb +1 -1
  45. data/lib/inspec/resources/postfix_conf.rb +1 -1
  46. data/lib/inspec/resources/service.rb +23 -15
  47. data/lib/inspec/resources/users.rb +3 -3
  48. data/lib/inspec/resources/virtualization.rb +15 -11
  49. data/lib/inspec/resources/x509_certificate.rb +18 -4
  50. data/lib/inspec/resources/xinetd_conf.rb +1 -1
  51. data/lib/inspec/resources/xml.rb +1 -2
  52. data/lib/inspec/rspec_extensions.rb +12 -0
  53. data/lib/inspec/rule.rb +63 -22
  54. data/lib/inspec/utils/filter.rb +2 -0
  55. data/lib/inspec/utils/parser.rb +244 -240
  56. data/lib/inspec/utils/simpleconfig.rb +1 -1
  57. data/lib/inspec/version.rb +1 -1
  58. data/lib/matchers/matchers.rb +11 -10
  59. data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +3 -0
  60. data/lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb +2 -2
  61. data/lib/plugins/inspec-init/templates/profiles/aws/README.md +192 -0
  62. data/lib/plugins/inspec-init/templates/profiles/aws/attributes.yml +2 -0
  63. data/lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb +39 -0
  64. data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +22 -0
  65. data/lib/plugins/inspec-init/templates/profiles/azure/README.md +56 -0
  66. data/lib/plugins/inspec-init/templates/profiles/azure/controls/example.rb +14 -0
  67. data/lib/plugins/inspec-init/templates/profiles/azure/inspec.yml +14 -0
  68. data/lib/plugins/inspec-init/templates/profiles/gcp/README.md +66 -0
  69. data/lib/plugins/inspec-init/templates/profiles/gcp/attributes.yml +2 -0
  70. data/lib/plugins/inspec-init/templates/profiles/gcp/controls/example.rb +27 -0
  71. data/lib/plugins/inspec-init/templates/profiles/gcp/inspec.yml +19 -0
  72. data/lib/source_readers/inspec.rb +1 -1
  73. metadata +87 -74
  74. data/lib/inspec/plugin/v1/plugin_types/resource.rb +0 -176
  75. 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: 91c5fa977076e418e2372d7a78cbc45383cbec50ee57c7126b7625aef4a1a606
4
- data.tar.gz: fe4ee768878acdaddf4c933ed0e41f899319fccaff69a19f942ddbbb7771b9a1
3
+ metadata.gz: 367bf0fb9467148e5434036ec14c7ec9b9b9e560504758e0c72493bacc73270a
4
+ data.tar.gz: 352392686e13db1a8827f9d7aa29f3961c070fd0b66d7f8cdb7ab88513429f59
5
5
  SHA512:
6
- metadata.gz: 00c1bfcaef4c1b42f5d16d3d1eab4255a67959b9fd7e6f8c9494fdcd6a324afc20a4059c8c30521036e6a996a839eda354b84194cde32549e63301b4f4a28dfc
7
- data.tar.gz: c40df12e404ec13c2fd1ef689e0d59e5ea6435d534763effad5372ce027fa0732e8a19f307b50761da7ecad8f6a438f7c5c4de989d024ba5d5274d7883b97355
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\* | 7, 8, 8.1, 10, 2008, 2008R2 , 2012, 2012R2, 2016 | x86, x86_64 |
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 | 7+ | x86_64 |
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/aws/TESTING_AGAINST_AZURE.md) for details on how to setup the needed Azure accounts to perform testing.
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
 
@@ -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
@@ -1,3 +1,4 @@
1
+ require "inspec/plugin/v1"
1
2
  require "inspec/base_cli"
2
3
 
3
4
  module Supermarket
@@ -7,34 +7,19 @@ require "inspec/resource"
7
7
  require "inspec/dsl" # for method_missing_resource
8
8
 
9
9
  module Inspec
10
- module Backend
11
- module Base
12
- attr_accessor :profile
10
+ class Backend
11
+ attr_accessor :backend
12
+ attr_accessor :profile
13
13
 
14
- # Provide a shorthand to retrieve the inspec version from within a profile
15
- #
16
- # @return [String] inspec version
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
- # Ruby internal for printing a nice name for this class
31
- def to_s
32
- "Inspec::Backend::Class"
33
- end
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
- cls = Class.new do
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
@@ -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 :winrm_basic_auth, type: :boolean,
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)
@@ -22,6 +22,10 @@ module Inspec
22
22
  @fetcher.resolved_source
23
23
  end
24
24
 
25
+ def update_from_opts(_opts)
26
+ false
27
+ end
28
+
25
29
  def cache_key
26
30
  k = if target.is_a?(Hash)
27
31
  target[:sha256] || target[:ref]
@@ -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])
@@ -44,7 +44,7 @@ module Inspec
44
44
  # Use this to get a cached version of the config. This prevents you from
45
45
  # being required to pass it around everywhere.
46
46
  def self.cached
47
- @cached_config
47
+ @cached_config ||= {}
48
48
  end
49
49
 
50
50
  def self.cached=(cfg)
@@ -12,236 +12,168 @@ module Inspec
12
12
  # etc).
13
13
  #
14
14
  class ControlEvalContext
15
- # Create the context for controls. This includes all components of the DSL,
16
- # including matchers and resources.
17
- #
18
- # @param [ResourcesDSL] resources_dsl which has all resources to attach
19
- # @return [RuleContext] the inner context of rules
20
- def self.rule_context(resources_dsl, profile_id)
21
- Class.new(Inspec::Rule) do
22
- include RSpec::Core::DSL
23
- with_resource_dsl resources_dsl
24
-
25
- # allow attributes to be accessed within control blocks
26
- define_method :input do |input_name, options = {}|
27
- if options.empty?
28
- # Simply an access, no event here
29
- Inspec::InputRegistry.find_or_register_input(input_name, profile_id).value
30
- else
31
- options[:priority] ||= 20
32
- options[:provider] = :inline_control_code
33
- evt = Inspec::Input.infer_event(options)
34
- Inspec::InputRegistry.find_or_register_input(input_name, profile_id, event: evt).value
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
- # Find the Input object, but don't collapse to a value.
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
- define_method :attribute do |name, options = {}|
45
- Inspec.deprecate(:attrs_dsl, "Input name: #{name}, Profile: #{profile_id}")
46
- input(name, options)
47
- end
38
+ def profile_id
39
+ profile_context.profile_id
40
+ end
48
41
 
49
- # Support for Control DSL plugins.
50
- # This is called when an unknown method is encountered
51
- # within a control block.
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
- end
46
+ def title(arg)
47
+ profile_context_owner.set_header(:title, arg)
78
48
  end
79
49
 
80
- # Creates the heart of the control eval context:
81
- #
82
- # An instantiated object which has all resources registered to it
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
- define_method :title do |arg|
110
- profile_context_owner.set_header(:title, arg)
111
- end
54
+ def control(id, opts = {}, &block)
55
+ opts[:skip_only_if_eval] = @skip_only_if_eval
112
56
 
113
- def to_s
114
- "Control Evaluation Context (#{profile_name})"
115
- end
57
+ register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
58
+ end
59
+ alias rule control
116
60
 
117
- define_method :profile_name do
118
- profile_id
119
- end
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
- define_method :control do |*args, &block|
122
- id = args[0]
123
- opts = args[1] || {}
124
- opts[:skip_only_if_eval] = @skip_only_if_eval
125
- register_control(rule_class.new(id, profile_id, opts, &block))
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
- # Describe allows users to write rspec-like bare describe
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
- define_method :add_resource do |name, new_res|
148
- resources_dsl.module_exec do
149
- define_method name.to_sym do |*args|
150
- new_res.new(@backend, name.to_s, *args)
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
- define_method :add_resources do |context|
156
- self.class.class_eval do
157
- include context.to_resources_dsl
158
- end
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
- rule_class.class_eval do
161
- include context.to_resources_dsl
162
- end
163
- end
93
+ self.class.class_eval do
94
+ include context.to_resources_dsl
95
+ end
164
96
 
165
- define_method :add_subcontext do |context|
166
- profile_context_owner.add_subcontext(context)
167
- end
97
+ # TODO: seriously consider getting rid of the NPM model
98
+ extend context.to_resources_dsl
99
+ end
168
100
 
169
- define_method :register_control do |control, &block|
170
- if @skip_file
171
- ::Inspec::Rule.set_skip_rule(control, true, @skip_file_message)
172
- end
101
+ def add_subcontext(context)
102
+ profile_context_owner.add_subcontext(context)
103
+ end
173
104
 
174
- unless profile_context_owner.profile_supports_platform?
175
- platform = inspec.platform
176
- msg = "Profile `#{profile_context_owner.profile_id}` is not supported on platform #{platform.name}/#{platform.release}."
177
- ::Inspec::Rule.set_skip_rule(control, true, msg)
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
- unless profile_context_owner.profile_supports_inspec_version?
181
- msg = "Profile `#{profile_context_owner.profile_id}` is not supported on InSpec version (#{Inspec::VERSION})."
182
- ::Inspec::Rule.set_skip_rule(control, true, msg)
183
- end
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
- profile_context_owner.register_rule(control, &block) unless control.nil?
186
- end
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
- define_method :input do |input_name, options = {}|
189
- if options.empty?
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
- # Find the Input object, but don't collapse to a value.
201
- # Will return nil on a miss.
202
- define_method :input_object do |input_name|
203
- Inspec::InputRegistry.find_or_register_input(input_name, profile_id)
204
- end
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
- define_method :attribute do |name, options = {}|
207
- Inspec.deprecate(:attrs_dsl, "Input name: #{name}, Profile: #{profile_id}")
208
- input(name, options)
209
- end
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
- define_method :skip_control do |id|
212
- profile_context_owner.unregister_rule(id)
213
- end
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
- define_method :only_if do |message = nil, &block|
216
- return unless block
217
- return if @skip_file == true
218
- return if @skip_only_if_eval == true
147
+ def skip_control(id)
148
+ profile_context_owner.unregister_rule(id)
149
+ end
150
+ alias skip_rule skip_control
219
151
 
220
- return if block.yield == true
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
- # Apply `set_skip_rule` for other rules in the same file
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
- @skip_file_message = message
229
- @skip_file = true
230
- end
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
- alias_method :rule, :control
233
- alias_method :skip_rule, :skip_control
165
+ @skip_file_message = message
166
+ @skip_file = true
167
+ end
234
168
 
235
- private
169
+ private
236
170
 
237
- def block_location(block, alternate_caller)
238
- if block.nil?
239
- alternate_caller[/^(.+:\d+):in .+$/, 1] || "unknown"
240
- else
241
- path, line = block.source_location
242
- "#{File.basename(path)}:#{line}"
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