inspec-core 4.50.3 → 5.7.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -11
  3. data/etc/deprecations.json +12 -11
  4. data/inspec-core.gemspec +2 -2
  5. data/lib/bundles/inspec-supermarket/README.md +21 -2
  6. data/lib/bundles/inspec-supermarket/cli.rb +20 -3
  7. data/lib/bundles/inspec-supermarket/target.rb +3 -2
  8. data/lib/inspec/base_cli.rb +22 -2
  9. data/lib/inspec/cli.rb +15 -0
  10. data/lib/inspec/config.rb +5 -1
  11. data/lib/inspec/dependencies/requirement.rb +2 -1
  12. data/lib/inspec/dependency_installer.rb +74 -0
  13. data/lib/inspec/dependency_loader.rb +97 -0
  14. data/lib/inspec/dsl.rb +11 -2
  15. data/lib/inspec/errors.rb +7 -0
  16. data/lib/inspec/formatters/base.rb +31 -6
  17. data/lib/inspec/library_eval_context.rb +2 -0
  18. data/lib/inspec/metadata.rb +36 -0
  19. data/lib/inspec/plugin/v1/registry.rb +1 -1
  20. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +53 -0
  21. data/lib/inspec/profile.rb +63 -0
  22. data/lib/inspec/profile_context.rb +1 -6
  23. data/lib/inspec/reporters/automate.rb +1 -1
  24. data/lib/inspec/reporters/cli.rb +1 -1
  25. data/lib/inspec/reporters/json.rb +31 -11
  26. data/lib/inspec/resource.rb +6 -0
  27. data/lib/inspec/resources/auditd.rb +5 -4
  28. data/lib/inspec/resources/bash.rb +2 -0
  29. data/lib/inspec/resources/cron.rb +49 -0
  30. data/lib/inspec/resources/file.rb +38 -0
  31. data/lib/inspec/resources/firewalld.rb +83 -9
  32. data/lib/inspec/resources/grub_conf.rb +1 -1
  33. data/lib/inspec/resources/http.rb +31 -2
  34. data/lib/inspec/resources/ibmdb2_session.rb +2 -2
  35. data/lib/inspec/resources/ipfilter.rb +59 -0
  36. data/lib/inspec/resources/ipnat.rb +58 -0
  37. data/lib/inspec/resources/iptables.rb +18 -2
  38. data/lib/inspec/resources/kernel_parameters.rb +58 -0
  39. data/lib/inspec/resources/mssql_session.rb +11 -3
  40. data/lib/inspec/resources/oracledb_session.rb +3 -1
  41. data/lib/inspec/resources/package.rb +74 -1
  42. data/lib/inspec/resources/packages.rb +21 -0
  43. data/lib/inspec/resources/registry_key.rb +30 -0
  44. data/lib/inspec/resources/selinux.rb +6 -1
  45. data/lib/inspec/resources/service.rb +58 -9
  46. data/lib/inspec/resources/ssl.rb +7 -0
  47. data/lib/inspec/resources/timezone.rb +65 -0
  48. data/lib/inspec/resources.rb +5 -16
  49. data/lib/inspec/runner.rb +18 -1
  50. data/lib/inspec/runner_rspec.rb +45 -0
  51. data/lib/inspec/schema/exec_json.rb +59 -58
  52. data/lib/inspec/schema/exec_json_min.rb +16 -16
  53. data/lib/inspec/schema/primitives.rb +68 -51
  54. data/lib/inspec/schema/profile_json.rb +27 -27
  55. data/lib/inspec/schema.rb +1 -0
  56. data/lib/inspec/ui.rb +1 -0
  57. data/lib/inspec/utils/deprecated_cloud_resources_list.rb +54 -0
  58. data/lib/inspec/utils/filter.rb +46 -2
  59. data/lib/inspec/utils/run_data_filters.rb +1 -1
  60. data/lib/inspec/version.rb +1 -1
  61. data/lib/inspec.rb +3 -0
  62. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +1 -1
  63. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +4 -3
  64. data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
  65. data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +9 -0
  66. data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +126 -0
  67. data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +9 -8
  68. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.erb +16 -0
  69. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/streaming_reporter.erb +31 -0
  70. data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
  71. data/lib/plugins/inspec-init/templates/resources/basic/docs/resource-doc.erb +77 -0
  72. data/lib/plugins/inspec-init/templates/resources/basic/libraries/inspec-resource-template.erb +94 -0
  73. data/lib/plugins/inspec-init/templates/resources/plural/docs/resource-doc.erb +62 -0
  74. data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb +73 -0
  75. data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +2 -0
  76. data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +3 -0
  77. data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +1 -0
  78. data/lib/plugins/inspec-reporter-html2/templates/result.html.erb +1 -0
  79. data/lib/plugins/inspec-streaming-reporter-progress-bar/README.md +5 -0
  80. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/plugin.rb +13 -0
  81. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +112 -0
  82. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/version.rb +8 -0
  83. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar.rb +15 -0
  84. metadata +25 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 506be4d9918c8af46f6b3784e8a18550cee990ad73c7c731bb1afea7197c5370
4
- data.tar.gz: b48fa274325e96ac07185653b2eeb997ed5ea6fa39f570b0400706331a3b4d52
3
+ metadata.gz: 4c3af1b1fd71ded2286e8aa90c46c74dd20f7fb31c525e56ae03e52952c26b0f
4
+ data.tar.gz: 507db51585f790cc26af852626b3bb52f8a35f36870ee563902234f1c2664a2a
5
5
  SHA512:
6
- metadata.gz: 4eb19bed92e35c49395e513e263f3afdb3f59abcf873b88f0c7dc07775a64c4e6aea3db57f069b19be73e9aa92de106db95ecb4b60fc3fc4c5b080f4fc97df6c
7
- data.tar.gz: e8eac56320e4c0e36078bdcef95dde1b6ec710d7bfdba1bbd4f8301ee0f5799c5a913f96edc5c31ba78c2dcc3647e671454b30ac430729943a0dca071191aa63
6
+ metadata.gz: 00447ba26c980417a501be959fb8ca85268db4e600417c11a912181da2c75c41169d419f1177fac484a12c1c405cae3aab5912ec9cab24f9a9e4adf355d40faa
7
+ data.tar.gz: f007b4bc1998187a7313f34f8739145f5e511500e2c9ca280b7163495a6909646be25fed9b4307a27f370e5e36b94b36b558c9e8d5c67079dc6cf24fb93029ea
data/Gemfile CHANGED
@@ -11,11 +11,6 @@ gem "inspec-bin", path: "./inspec-bin"
11
11
 
12
12
  gem "ffi", ">= 1.9.14", "!= 1.13.0", "!= 1.14.2"
13
13
 
14
- if Gem.ruby_version.to_s.start_with?("2.5")
15
- # 16.7.23 required ruby 2.6+
16
- gem "chef-utils", "< 16.7.23" # TODO: remove when we drop ruby 2.5
17
- end
18
-
19
14
  # inspec tests depend text output that changed in the 3.10 release
20
15
  # but our runtime dep is still 3.9+
21
16
  gem "rspec", ">= 3.10"
@@ -30,11 +25,7 @@ end
30
25
  group :test do
31
26
  gem "chefstyle", "~> 2.0.3"
32
27
  gem "concurrent-ruby", "~> 1.0"
33
- if Gem.ruby_version.to_s.start_with?("2.5")
34
- gem "html-proofer", "= 3.19.1" , platforms: :ruby # do not attempt to run proofer on windows
35
- else
36
- gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
37
- end
28
+ gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
38
29
  gem "json_schemer", ">= 0.2.1", "< 0.2.19"
39
30
  gem "m"
40
31
  gem "minitest-sprint", "~> 1.0"
@@ -45,7 +36,8 @@ group :test do
45
36
  gem "pry", "~> 0.10"
46
37
  gem "rake", ">= 10"
47
38
  gem "ruby-progressbar", "~> 1.8"
48
- gem "simplecov", "~> 0.18"
39
+ gem "simplecov", "~> 0.21"
40
+ gem "simplecov_json_formatter"
49
41
  gem "webmock", "~> 3.0"
50
42
  end
51
43
 
@@ -66,3 +58,7 @@ if Gem.ruby_version >= Gem::Version.new("2.7.0")
66
58
  gem "git"
67
59
  end
68
60
  end
61
+
62
+ if Gem.ruby_version < Gem::Version.new("2.7.0")
63
+ gem "activesupport", "6.1.4.4"
64
+ end
@@ -17,9 +17,14 @@
17
17
  "prefix": "Inputs should be specified by using the 'inputs' key in profile metadata, not 'attributes'."
18
18
  },
19
19
  "aws_resources_in_resource_pack": {
20
- "comment": "See #3822",
21
- "action": "warn",
22
- "prefix": "AWS resources shipped with core InSpec are being to moved to a resource pack for faster iteration. Please update your profiles to depend on git@github.com:inspec/inspec-aws.git ."
20
+ "comment": "Deprecated in InSpec 5",
21
+ "action": "exit",
22
+ "prefix": "AWS resources in core InSpec are deprecated and have been removed in InSpec 5. They are now part of a resource pack. Please update your profiles to depend on git@github.com:inspec/inspec-aws.git ."
23
+ },
24
+ "azure_resources_in_resource_pack": {
25
+ "comment": "Deprecated in InSpec 5",
26
+ "action": "exit",
27
+ "prefix": "Azure resources in core InSpec are deprecated and have been removed in InSpec 5. They are now part of a resource pack. Please update your profiles to depend on git@github.com:inspec/inspec-azure.git ."
23
28
  },
24
29
  "cli_option_json_config": {
25
30
  "action": "ignore",
@@ -55,10 +60,6 @@
55
60
  "action": "fail_control",
56
61
  "suffix": "This property was removed in InSpec 4.0."
57
62
  },
58
- "properties_aws_iam_user": {
59
- "action": "fail_control",
60
- "suffix": "This property was removed in InSpec 4.0."
61
- },
62
63
  "properties_shadow": {
63
64
  "action": "fail_control",
64
65
  "suffix": "This property was removed in InSpec 4.0."
@@ -72,10 +73,6 @@
72
73
  "action": "exit",
73
74
  "suffix": "This resource was removed in InSpec 4.0."
74
75
  },
75
- "resource_azure_generic_resource": {
76
- "action": "warn",
77
- "prefix": "The azure_generic_resource is deprecated. Please use a specific resource. See: 'https://github.com/inspec/inspec/issues/3131'"
78
- },
79
76
  "resource_iis_website": {
80
77
  "action": "exit",
81
78
  "suffix": "This resource was removed in InSpec 4.0.",
@@ -125,6 +122,10 @@
125
122
  "action": "warn",
126
123
  "prefix": "The --hook option is being replaced by the --activator option.",
127
124
  "suffix": "This options will be removed in InSpec 4.0."
125
+ },
126
+ "cli_option_target_id":{
127
+ "action": "warn",
128
+ "prefix": "The --target-id option is deprecated in InSpec 5. Its value will be ignored."
128
129
  }
129
130
  }
130
131
  }
data/inspec-core.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.license = "Apache-2.0"
14
14
  spec.require_paths = ["lib"]
15
15
 
16
- spec.required_ruby_version = ">= 2.5"
16
+ spec.required_ruby_version = ">= 2.7"
17
17
 
18
18
  # the gemfile and gemspec are necessary for appbundler so don't remove it
19
19
  spec.files =
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "thor", ">= 0.20", "< 2.0"
29
29
  spec.add_dependency "method_source", ">= 0.8", "< 2.0"
30
30
  spec.add_dependency "rubyzip", ">= 1.2.2", "< 3.0"
31
- spec.add_dependency "rspec", ">= 3.9", "< 3.11"
31
+ spec.add_dependency "rspec", ">= 3.9", "<= 3.11"
32
32
  spec.add_dependency "rspec-its", "~> 1.2"
33
33
  spec.add_dependency "pry", "~> 0.13"
34
34
  spec.add_dependency "hashie", ">= 3.4", "< 5.0"
@@ -8,8 +8,27 @@ To use the CLI, this InSpec add-on adds the following commands:
8
8
 
9
9
  Compliance profiles from Supermarket can be executed in two ways:
10
10
 
11
- - via supermarket exec: `inspec supermarket exec nathenharvey/tmp-compliance-profile`
12
- - via supermarket scheme: `inspec exec supermarket://nathenharvey/tmp-compliance-profile`
11
+ - via supermarket exec:
12
+
13
+ **Public Supermarket**
14
+
15
+ `inspec supermarket exec nathenharvey/tmp-compliance-profile`
16
+
17
+ **Private Supermarket**
18
+
19
+ `inspec supermarket exec nathenharvey/tmp-compliance-profile --supermarket_url="PRIVATE_SUPERMARKET_URL"`
20
+
21
+
22
+ - via supermarket scheme:
23
+
24
+ **Public Supermarket**
25
+
26
+ `inspec exec supermarket://nathenharvey/tmp-compliance-profile`
27
+
28
+ **Private Supermarket**
29
+
30
+ `inspec exec supermarket://nathenharvey/tmp-compliance-profile --supermarket_url="PRIVATE_SUPERMARKET_URL"`
31
+
13
32
 
14
33
  ## Usage
15
34
 
@@ -15,10 +15,18 @@ module Supermarket
15
15
  end
16
16
 
17
17
  desc "profiles", "list all available profiles in Chef Supermarket"
18
+ supermarket_options
18
19
  def profiles
19
- # display profiles in format user/profile
20
- supermarket_profiles = Supermarket::API.profiles
20
+ o = config
21
+ diagnose(o)
22
+ configure_logger(o)
21
23
 
24
+ # display profiles in format user/profile
25
+ supermarket_profiles = if o["supermarket_url"]
26
+ Supermarket::API.profiles(o["supermarket_url"])
27
+ else
28
+ Supermarket::API.profiles
29
+ end
22
30
  headline("Available profiles:")
23
31
  supermarket_profiles.each do |p|
24
32
  li("#{p["tool_name"]} #{mark_text(p["tool_owner"] + "/" + p["slug"])}")
@@ -45,9 +53,18 @@ module Supermarket
45
53
  end
46
54
 
47
55
  desc "info PROFILE", "display Supermarket profile details"
56
+ supermarket_options
48
57
  def info(profile)
58
+ o = config
59
+ diagnose(o)
60
+ configure_logger(o)
61
+
49
62
  # check that the profile is available
50
- supermarket_profiles = Supermarket::API.profiles
63
+ supermarket_profiles = if o["supermarket_url"]
64
+ Supermarket::API.profiles(o["supermarket_url"])
65
+ else
66
+ Supermarket::API.profiles
67
+ end
51
68
  found = supermarket_profiles.select do |p|
52
69
  profile == "#{p["tool_owner"]}/#{p["slug"]}"
53
70
  end
@@ -9,10 +9,11 @@ module Supermarket
9
9
  priority 500
10
10
 
11
11
  def self.resolve(target, opts = {})
12
+ supermarket_url = opts["supermarket_url"] || Supermarket::API::SUPERMARKET_URL
12
13
  supermarket_uri, supermarket_server = if target.is_a?(String) && URI(target).scheme == "supermarket"
13
- [target, Supermarket::API::SUPERMARKET_URL]
14
+ [target, supermarket_url]
14
15
  elsif target.respond_to?(:key?) && target.key?(:supermarket)
15
- supermarket_server = target[:supermarket_url] || Supermarket::API::SUPERMARKET_URL
16
+ supermarket_server = target[:supermarket_url] || supermarket_url
16
17
  ["supermarket://#{target[:supermarket]}", supermarket_server]
17
18
  end
18
19
  return nil unless supermarket_uri
@@ -99,8 +99,18 @@ module Inspec
99
99
  desc: "Specify a particular shell to use."
100
100
  option :ssl, type: :boolean,
101
101
  desc: "Use SSL for transport layer encryption (WinRM)."
102
+ option :ssl_peer_fingerprint, type: :string,
103
+ desc: "Specify peer fingerprint for SSL authentication, used in lieu of certificates"
102
104
  option :self_signed, type: :boolean,
103
105
  desc: "Allow remote scans with self-signed certificates (WinRM)."
106
+ option :ca_trust_file, type: :string,
107
+ desc: "Specify CA trust file for SSL authentication"
108
+ option :client_cert, type: :string,
109
+ desc: "Specify client certificate for SSL authentication"
110
+ option :client_key, type: :string,
111
+ desc: "Specify client key required with client cert for SSL authentication"
112
+ option :client_key_pass, type: :string, lazy_default: -1,
113
+ desc: "Specify client cert password, if required for SSL authentication"
104
114
  option :winrm_transport, type: :string, default: "negotiate",
105
115
  desc: "Specify which transport to use, defaults to negotiate (WinRM)."
106
116
  option :winrm_disable_sspi, type: :boolean,
@@ -121,11 +131,13 @@ module Inspec
121
131
  option :insecure, type: :boolean, default: false,
122
132
  desc: "Disable SSL verification on select targets"
123
133
  option :target_id, type: :string,
124
- desc: "Provide a ID which will be included on reports"
134
+ desc: "Provide a ID which will be included on reports - deprecated"
125
135
  option :winrm_shell_type, type: :string, default: "powershell",
126
136
  desc: "Specify a shell type for winrm (eg. 'elevated' or 'powershell')"
127
137
  option :docker_url, type: :string,
128
138
  desc: "Provides path to Docker API endpoint (Docker)"
139
+ option :ssh_config_file, type: :array,
140
+ desc: "A list of paths to the ssh config file, e.g ~/.ssh/config or /etc/ssh/ssh_config"
129
141
  end
130
142
 
131
143
  def self.profile_options
@@ -133,18 +145,26 @@ module Inspec
133
145
  desc: "Folder which contains referenced profiles."
134
146
  option :vendor_cache, type: :string,
135
147
  desc: "Use the given path for caching dependencies. (default: ~/.inspec/cache)"
148
+ option :auto_install_gems, type: :boolean, default: false,
149
+ desc: "Auto installs gem dependencies of the profile or resource pack."
150
+ end
151
+
152
+ def self.supermarket_options
153
+ option :supermarket_url, type: :string,
154
+ desc: "Specify the URL of a private Chef Supermarket."
136
155
  end
137
156
 
138
157
  def self.exec_options
139
158
  target_options
140
159
  profile_options
160
+ supermarket_options
141
161
  option :controls, type: :array,
142
162
  desc: "A list of control names to run, or a list of /regexes/ to match against control names. Ignore all other tests."
143
163
  option :tags, type: :array,
144
164
  desc: "A list of tags names that are part of controls to filter and run controls, or a list of /regexes/ to match against tags names of controls. Ignore all other tests."
145
165
  option :reporter, type: :array,
146
166
  banner: "one two:/output/file/path",
147
- desc: "Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml"
167
+ desc: "Enable one or more output reporters: cli, documentation, html, progress, progress-bar, json, json-min, json-rspec, junit, yaml"
148
168
  option :reporter_message_truncation, type: :string,
149
169
  desc: "Number of characters to truncate failure messages and code_desc in report data to (default: no truncation)"
150
170
  option :reporter_backtrace_inclusion, type: :boolean,
data/lib/inspec/cli.rb CHANGED
@@ -201,6 +201,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
201
201
  vendor_deps(path, vendor_options)
202
202
 
203
203
  profile = Inspec::Profile.for_target(path, o)
204
+ gem_deps = profile.metadata.gem_dependencies + \
205
+ profile.locked_dependencies.list.map { |_k, v| v.profile.metadata.gem_dependencies }.flatten
206
+ unless gem_deps.empty?
207
+ o[:logger].warn "Archiving a profile that contains gem dependencies, but InSpec cannot package gems with the profile! Please archive your ~/.inspec/gems directory separately."
208
+ end
209
+
204
210
  result = profile.check
205
211
 
206
212
  if result && !o[:ignore_errors] == false
@@ -296,6 +302,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
296
302
  def exec(*targets)
297
303
  o = config
298
304
  diagnose(o)
305
+ deprecate_target_id(config)
299
306
  configure_logger(o)
300
307
 
301
308
  runner = Inspec::Runner.new(o)
@@ -314,6 +321,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
314
321
  option :format, type: :string
315
322
  def detect
316
323
  o = config
324
+ deprecate_target_id(config)
317
325
  o[:command] = "platform.params"
318
326
 
319
327
  configure_logger(o)
@@ -354,6 +362,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
354
362
  desc: "Specify one or more inputs directly on the command line to the shell, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
355
363
  def shell_func
356
364
  o = config
365
+ deprecate_target_id(config)
357
366
  diagnose(o)
358
367
  o[:debug_shell] = true
359
368
 
@@ -441,6 +450,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
441
450
 
442
451
  private
443
452
 
453
+ def deprecate_target_id(config)
454
+ unless config[:target_id].nil?
455
+ Inspec.deprecate "cli_option_target_id"
456
+ end
457
+ end
458
+
444
459
  def run_command(opts)
445
460
  runner = Inspec::Runner.new(Inspec::Config.new(opts))
446
461
  res = runner.eval_with_virtual_profile(opts[:command])
data/lib/inspec/config.rb CHANGED
@@ -367,7 +367,11 @@ module Inspec
367
367
  .find_activators(plugin_type: :reporter)\
368
368
  .map(&:activator_name).map(&:to_s)
369
369
 
370
- valid_types = rspec_built_in_formatters + inspec_reporters_that_are_not_yet_plugins + plugin_reporters
370
+ streaming_reporters = Inspec::Plugin::V2::Registry.instance\
371
+ .find_activators(plugin_type: :streaming_reporter)\
372
+ .map(&:activator_name).map(&:to_s)
373
+
374
+ valid_types = rspec_built_in_formatters + inspec_reporters_that_are_not_yet_plugins + plugin_reporters + streaming_reporters
371
375
 
372
376
  reporters.each do |reporter_name, reporter_config|
373
377
  raise NotImplementedError, "'#{reporter_name}' is not a valid reporter type." unless valid_types.include?(reporter_name)
@@ -102,7 +102,8 @@ module Inspec
102
102
  end
103
103
 
104
104
  def fetcher
105
- @fetcher ||= Inspec::CachedFetcher.new(opts, @cache)
105
+ @runner_options ||= (Inspec::Config.cached || {})
106
+ @fetcher ||= Inspec::CachedFetcher.new(opts, @cache, @runner_options)
106
107
  end
107
108
 
108
109
  # load dependencies of the dependency
@@ -0,0 +1,74 @@
1
+ # This class will install the gem depedencies for profiles etc.
2
+ # The basic things which is required to install dependencies is the gem path where gem needs to be installed
3
+ # and the list of gems needs to be installed.
4
+ require "rubygems/remote_fetcher"
5
+ require "forwardable" unless defined?(Forwardable)
6
+
7
+ module Inspec
8
+ class DependencyInstaller
9
+ extend Forwardable
10
+
11
+ attr_reader :gem_path, :requested_gems, :dependency_loader
12
+
13
+ def_delegator :dependency_loader, :inspec_gem_path
14
+
15
+ def initialize(gem_path = nil, requested_gems = [])
16
+ @dependency_loader = Inspec::DependencyLoader.new
17
+ @gem_path = gem_path || inspec_gem_path
18
+ @requested_gems = requested_gems
19
+ end
20
+
21
+ def install
22
+ requested_gems.each do |requested_gem|
23
+ version = requested_gem[:version].nil? ? "> 0" : requested_gem[:version]
24
+ install_from_remote_gems(requested_gem[:name], { version: version })
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def install_from_remote_gems(requested_gem_name, opts)
31
+ version = opts[:version].split(",")
32
+ begin
33
+ gem_dependency = Gem::Dependency.new(requested_gem_name, version || "> 0")
34
+
35
+ # BestSet is rubygems.org API + indexing, APISet is for custom sources
36
+ sources = if opts[:source]
37
+ Gem::Resolver::APISet.new(URI.join(opts[:source] + "/api/v1/dependencies"))
38
+ else
39
+ Gem::Resolver::BestSet.new
40
+ end
41
+
42
+ install_gem_to_gems_dir(gem_dependency, [sources], opts[:update_mode])
43
+ rescue Gem::RemoteFetcher::FetchError => gem_ex
44
+ ex = Inspec::GemDependencyInstallError.new(gem_ex.message)
45
+ ex.gem_name = requested_gem_name
46
+ raise ex
47
+ rescue Gem::Requirement::BadRequirementError => gem_ex
48
+ ex = Inspec::GemDependencyInstallError.new(gem_ex.message)
49
+ ex.gem_name = requested_gem_name
50
+ raise "Unparseable gem dependency '#{version}' for '#{ex.gem_name}'"
51
+ end
52
+ end
53
+
54
+ def install_gem_to_gems_dir(gem_dependency, extra_request_sets = [], update_mode = false)
55
+ # Solve the dependency (that is, find a way to install the new gem and anything it needs)
56
+ request_set = Gem::RequestSet.new(gem_dependency)
57
+
58
+ begin
59
+ solution = request_set.resolve
60
+ rescue Gem::UnsatisfiableDependencyError => gem_ex
61
+ ex = Inspec::GemDependencyInstallError.new(gem_ex.message)
62
+ ex.gem_name = gem_dependency.name
63
+ raise ex
64
+ end
65
+
66
+ # OK, perform the installation.
67
+ # Ignore deps here, because any needed deps should already be baked into gem_dependency
68
+ request_set.install_into(gem_path, true, ignore_dependencies: true, document: [])
69
+
70
+ # Locate the GemVersion for the new dependency and return it
71
+ solution.detect { |g| g.name == gem_dependency.name }.version
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,97 @@
1
+ # This class will load the gem depedencies for profiles etc.
2
+ # The basic things which is required to load gem dependencies is the path from which gems needs to be loaded
3
+ # and the list of gems needs to be loaded.
4
+
5
+ module Inspec
6
+ class DependencyLoader
7
+ attr_accessor :gem_path, :gem_list
8
+
9
+ # initializes the dependency_loader
10
+ def initialize(gem_path = nil, gem_list = [])
11
+ @gem_path = gem_path || inspec_gem_path
12
+ @gem_list = gem_list
13
+ end
14
+
15
+ def load
16
+ Gem.path << gem_path
17
+ Gem.refresh
18
+
19
+ gem_list.each do |gem_data|
20
+ version = gem_data[:version].nil? ? "> 0" : gem_data[:version]
21
+ activate_gem_dependency(gem_data[:name], version)
22
+ end
23
+ end
24
+
25
+ def inspec_gem_path
26
+ self.class.inspec_gem_path
27
+ end
28
+
29
+ def self.inspec_gem_path
30
+ require "rbconfig" unless defined?(RbConfig)
31
+ ruby_abi_version = RbConfig::CONFIG["ruby_version"]
32
+ # TODO: why are we installing under the api directory for plugins?
33
+ base_dir = Inspec.config_dir
34
+ base_dir = File.realpath base_dir if File.exist? base_dir
35
+ File.join(base_dir, "gems", ruby_abi_version)
36
+ end
37
+
38
+ # Lists all gems found in the inspec_gem_path.
39
+ # @return [Array[Gem::Specification]] Specs of all gems found.
40
+ def list_managed_gems
41
+ Dir.glob(File.join(gem_path, "specifications", "*.gemspec")).map { |p| Gem::Specification.load(p) }
42
+ end
43
+
44
+ def list_installed_gems
45
+ list_managed_gems
46
+ end
47
+
48
+ def gem_installed?(name)
49
+ list_installed_gems.any? { |spec| spec.name == name }
50
+ end
51
+
52
+ def gem_version_installed?(name, version)
53
+ list_installed_gems.any? { |s| s.name == name && Gem::Requirement.new(version.split(",")) =~ s.version }
54
+ end
55
+
56
+ private
57
+
58
+ def activate_gem_dependency(name, version_constraint = "> 0")
59
+ version_constraint = version_constraint.split(",")
60
+ gem_deps = [Gem::Dependency.new(name.to_s, version_constraint)]
61
+ managed_gem_set = Gem::Resolver::VendorSet.new
62
+
63
+ # Note: There is an issue in resolving gem dependency.
64
+ # This block resolves that issue partially.
65
+ # But this will still fail for the gems which don't have the .gemspec file.
66
+ # TODO: Find the solution to resolve gem dependencies that work for the unpackaged gems which don't have the .gemspec file.
67
+ list_managed_gems.each do |spec|
68
+ unless Dir["#{spec.gem_dir}/*.gemspec"].empty?
69
+ managed_gem_set.add_vendor_gem(spec.name, spec.gem_dir)
70
+ end
71
+ end
72
+
73
+ # TODO: Next two lines merge our managed gems with the other gems available
74
+ # in our "local universe" - which may be the system, or it could be in a Bundler microcosm,
75
+ # or rbenv, etc. Do we want to merge that, though?
76
+ distrib_gem_set = Gem::Resolver::CurrentSet.new
77
+ installed_gem_set = Gem::Resolver.compose_sets(managed_gem_set, distrib_gem_set)
78
+
79
+ # So, given what we need, and what we have available, what activations are needed?
80
+ resolver = Gem::Resolver.new(gem_deps, installed_gem_set)
81
+
82
+ begin
83
+ solution = resolver.resolve
84
+ rescue Gem::UnsatisfiableDependencyError => gem_ex
85
+ # If you broke your install, or downgraded to a plugin with a bad gemspec, you could get here.
86
+ ex = Inspec::GemDependencyLoadError.new(gem_ex.message)
87
+ raise ex
88
+ end
89
+ solution.each do |activation_request|
90
+ next if activation_request.full_spec.activated?
91
+
92
+ activation_request.full_spec.activate
93
+ # TODO: If we are under Bundler, inform it that we loaded a gem
94
+ end
95
+ end
96
+ end
97
+ end
data/lib/inspec/dsl.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # copyright: 2015, Dominik Richter
2
2
  require "inspec/log"
3
3
  require "inspec/plugin/v2"
4
+ require "inspec/utils/deprecated_cloud_resources_list"
4
5
 
5
6
  module Inspec::DSL
6
7
  attr_accessor :backend
@@ -38,8 +39,16 @@ module Inspec::DSL
38
39
 
39
40
  begin
40
41
  require "inspec/resources/#{id}"
41
- rescue LoadError
42
- require "resources/aws/#{id}"
42
+ rescue LoadError => e
43
+ include DeprecatedCloudResourcesList
44
+ cloud_resource = id.start_with?("aws_") ? "aws" : "azure"
45
+
46
+ # Deprecated AWS and Azure resources in InSpec 5.
47
+ if CLOUD_RESOURCES_DEPRECATED.include? id
48
+ Inspec.deprecate(:"#{cloud_resource}_resources_in_resource_pack", "Resource '#{id}'")
49
+ else
50
+ raise LoadError, "#{e.message}"
51
+ end
43
52
  end
44
53
 
45
54
  klass = Inspec::Resource.registry[id.to_s]
data/lib/inspec/errors.rb CHANGED
@@ -15,4 +15,11 @@ module Inspec
15
15
  class ConfigError::Invalid < ConfigError; end
16
16
 
17
17
  class UserInteractionRequired < Error; end
18
+
19
+ class GemDependencyLoadError < Error; end
20
+
21
+ class GemDependencyInstallError < Error
22
+ attr_accessor :gem_name
23
+ attr_accessor :version
24
+ end
18
25
  end
@@ -1,5 +1,6 @@
1
1
  require "rspec/core"
2
2
  require "rspec/core/formatters/base_formatter"
3
+ require "set" unless defined?(Set)
3
4
 
4
5
  module Inspec::Formatters
5
6
  class Base < RSpec::Core::Formatters::BaseFormatter
@@ -14,6 +15,8 @@ module Inspec::Formatters
14
15
  @profiles = []
15
16
  @profiles_info = nil
16
17
  @backend = nil
18
+ @all_controls_count = nil
19
+ @control_checks_count_map = {}
17
20
  end
18
21
 
19
22
  # RSpec Override: #dump_summary
@@ -70,6 +73,7 @@ module Inspec::Formatters
70
73
  name: platform(:name),
71
74
  release: platform(:release),
72
75
  target: backend_target,
76
+ target_id: platform(:uuid),
73
77
  }
74
78
  end
75
79
 
@@ -79,6 +83,26 @@ module Inspec::Formatters
79
83
  @profiles.push(profile)
80
84
  end
81
85
 
86
+ # These control count related methods are called via runner rspec library of inspec
87
+ # And these are used within streaming plugins to determine end of control
88
+ ######### Start of control count related methods
89
+ def set_controls_count(controls_count)
90
+ @all_controls_count = controls_count
91
+ end
92
+
93
+ def set_control_checks_count_map(mapping)
94
+ @control_checks_count_map = mapping
95
+ end
96
+
97
+ def get_controls_count
98
+ @all_controls_count
99
+ end
100
+
101
+ def get_control_checks_count_map
102
+ @control_checks_count_map
103
+ end
104
+ ######### end of control count related methods
105
+
82
106
  # Return all the collected output to the caller
83
107
  def results
84
108
  run_data
@@ -205,12 +229,13 @@ module Inspec::Formatters
205
229
  def platform(field)
206
230
  return nil if @backend.nil?
207
231
 
208
- begin
209
- @backend.platform[field]
210
- rescue Train::Error => e
211
- Inspec::Log.warn(e.message)
212
- nil
213
- end
232
+ @backend.platform[field]
233
+ rescue Train::PlatformUuidDetectionFailed
234
+ Inspec::Log.warn("Could not find platform target_id.")
235
+ nil
236
+ rescue Train::Error => e
237
+ Inspec::Log.warn(e.message)
238
+ nil
214
239
  end
215
240
 
216
241
  def backend_target
@@ -30,6 +30,8 @@ module Inspec
30
30
 
31
31
  c3 = Class.new do
32
32
  include Inspec::DSL::RequireOverride
33
+ include Inspec::Resources
34
+
33
35
  def initialize(require_loader)
34
36
  @require_loader = require_loader
35
37
  @inspec_binding = nil