inspec-core 5.22.50 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/Chef-EULA +9 -0
  3. data/Gemfile +23 -13
  4. data/etc/features.sig +6 -0
  5. data/etc/features.yaml +94 -0
  6. data/inspec-core.gemspec +14 -11
  7. data/lib/inspec/backend.rb +2 -0
  8. data/lib/inspec/base_cli.rb +80 -4
  9. data/lib/inspec/cached_fetcher.rb +24 -3
  10. data/lib/inspec/cli.rb +292 -235
  11. data/lib/inspec/config.rb +24 -11
  12. data/lib/inspec/dependencies/cache.rb +33 -0
  13. data/lib/inspec/dependencies/dependency_set.rb +2 -2
  14. data/lib/inspec/dsl.rb +1 -1
  15. data/lib/inspec/enhanced_outcomes.rb +1 -0
  16. data/lib/inspec/errors.rb +5 -0
  17. data/lib/inspec/exceptions.rb +2 -0
  18. data/lib/inspec/feature/config.rb +75 -0
  19. data/lib/inspec/feature/runner.rb +26 -0
  20. data/lib/inspec/feature.rb +34 -0
  21. data/lib/inspec/fetcher/git.rb +5 -0
  22. data/lib/inspec/fetcher/url.rb +3 -5
  23. data/lib/inspec/globals.rb +6 -0
  24. data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +7 -0
  25. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +30 -2
  26. data/lib/inspec/profile.rb +46 -3
  27. data/lib/inspec/reporters/cli.rb +1 -1
  28. data/lib/inspec/reporters.rb +67 -54
  29. data/lib/inspec/resources/virtualization.rb +1 -1
  30. data/lib/inspec/rule.rb +9 -14
  31. data/lib/inspec/run_data.rb +7 -5
  32. data/lib/inspec/runner.rb +35 -6
  33. data/lib/inspec/runner_rspec.rb +12 -9
  34. data/lib/inspec/secrets/yaml.rb +9 -3
  35. data/lib/inspec/shell.rb +10 -0
  36. data/lib/inspec/ui.rb +4 -0
  37. data/lib/inspec/utils/licensing_config.rb +9 -0
  38. data/lib/inspec/utils/profile_ast_helpers.rb +2 -1
  39. data/lib/inspec/utils/waivers/csv_file_reader.rb +1 -1
  40. data/lib/inspec/utils/waivers/excel_file_reader.rb +1 -1
  41. data/lib/inspec/version.rb +1 -1
  42. data/lib/inspec/waiver_file_reader.rb +68 -27
  43. data/lib/inspec.rb +2 -1
  44. data/lib/matchers/matchers.rb +3 -3
  45. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +189 -168
  46. data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +10 -3
  47. data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
  48. data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +23 -21
  49. data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +15 -13
  50. data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +15 -13
  51. data/lib/plugins/inspec-license/README.md +16 -0
  52. data/lib/plugins/inspec-license/inspec-license.gemspec +6 -0
  53. data/lib/plugins/inspec-license/lib/inspec-license/cli.rb +26 -0
  54. data/lib/plugins/inspec-license/lib/inspec-license.rb +14 -0
  55. data/lib/plugins/inspec-parallel/README.md +27 -0
  56. data/lib/plugins/inspec-parallel/inspec-parallel.gemspec +6 -0
  57. data/lib/plugins/inspec-parallel/lib/inspec-parallel/child_status_reporter.rb +61 -0
  58. data/lib/plugins/inspec-parallel/lib/inspec-parallel/cli.rb +39 -0
  59. data/lib/plugins/inspec-parallel/lib/inspec-parallel/command.rb +219 -0
  60. data/lib/plugins/inspec-parallel/lib/inspec-parallel/runner.rb +265 -0
  61. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/base.rb +24 -0
  62. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/silent.rb +7 -0
  63. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/status.rb +124 -0
  64. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/text.rb +23 -0
  65. data/lib/plugins/inspec-parallel/lib/inspec-parallel/validator.rb +170 -0
  66. data/lib/plugins/inspec-parallel/lib/inspec-parallel.rb +18 -0
  67. data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +6 -2
  68. data/lib/plugins/inspec-sign/lib/inspec-sign/cli.rb +11 -4
  69. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +6 -13
  70. metadata +44 -18
@@ -1,6 +1,7 @@
1
1
  require "inspec/dist"
2
2
 
3
3
  require_relative "api"
4
+ require "inspec/feature"
4
5
 
5
6
  module InspecPlugins
6
7
  module Compliance
@@ -32,90 +33,102 @@ module InspecPlugins
32
33
  option :ent, type: :string, required: false,
33
34
  desc: "Enterprise for #{AUTOMATE_PRODUCT_NAME} reporting (#{AUTOMATE_PRODUCT_NAME} Only)"
34
35
  def login(server)
35
- options["server"] = server
36
- login_response = InspecPlugins::Compliance::API.login(options)
37
- puts login_response
36
+ Inspec.with_feature("inspec-cli-compliance-login") {
37
+ options["server"] = server
38
+ login_response = InspecPlugins::Compliance::API.login(options)
39
+ puts login_response
40
+ }
38
41
  end
39
42
 
40
43
  desc "profiles", "list all available profiles in #{AUTOMATE_PRODUCT_NAME}"
41
44
  option :owner, type: :string, required: false,
42
45
  desc: "owner whose profiles to list"
43
46
  def profiles
44
- config = InspecPlugins::Compliance::Configuration.new
45
- return unless loggedin(config)
46
-
47
- # set owner to config
48
- config["owner"] = options["owner"] || config["user"]
49
-
50
- msg, profiles = InspecPlugins::Compliance::API.profiles(config)
51
- profiles.sort_by! { |hsh| hsh["title"] }
52
- if !profiles.empty?
53
- # iterate over profiles
54
- headline("Available profiles:")
55
- profiles.each do |profile|
56
- owner = profile["owner_id"] || profile["owner"]
57
- li("#{profile["title"]} v#{profile["version"]} (#{mark_text(owner + "/" + profile["name"])})")
47
+ Inspec.with_feature("inspec-cli-compliance-profiles") {
48
+ begin
49
+ config = InspecPlugins::Compliance::Configuration.new
50
+ return unless loggedin(config)
51
+
52
+ # set owner to config
53
+ config["owner"] = options["owner"] || config["user"]
54
+
55
+ msg, profiles = InspecPlugins::Compliance::API.profiles(config)
56
+ profiles.sort_by! { |hsh| hsh["title"] }
57
+ if !profiles.empty?
58
+ # iterate over profiles
59
+ headline("Available profiles:")
60
+ profiles.each do |profile|
61
+ owner = profile["owner_id"] || profile["owner"]
62
+ li("#{profile["title"]} v#{profile["version"]} (#{mark_text(owner + "/" + profile["name"])})")
63
+ end
64
+ else
65
+ puts msg if msg != "success"
66
+ puts "Could not find any profiles"
67
+ exit 1
68
+ end
69
+ rescue InspecPlugins::Compliance::ServerConfigurationMissing
70
+ $stderr.puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
71
+ exit 1
58
72
  end
59
- else
60
- puts msg if msg != "success"
61
- puts "Could not find any profiles"
62
- exit 1
63
- end
64
- rescue InspecPlugins::Compliance::ServerConfigurationMissing
65
- $stderr.puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
66
- exit 1
73
+ }
67
74
  end
68
75
 
69
76
  desc "exec PROFILE", "executes a #{AUTOMATE_PRODUCT_NAME} profile"
70
77
  exec_options
71
78
  def exec(*tests)
72
- compliance_config = InspecPlugins::Compliance::Configuration.new
73
- return unless loggedin(compliance_config)
79
+ Inspec.with_feature("inspec-cli-compliance-exec") {
80
+ begin
81
+ compliance_config = InspecPlugins::Compliance::Configuration.new
82
+ return unless loggedin(compliance_config)
74
83
 
75
- o = config # o is an Inspec::Config object, provided by a helper method from Inspec::BaseCLI
76
- diagnose(o)
77
- configure_logger(o)
84
+ o = config # o is an Inspec::Config object, provided by a helper method from Inspec::BaseCLI
85
+ diagnose(o)
86
+ configure_logger(o)
78
87
 
79
- # iterate over tests and add compliance scheme
80
- tests = tests.map { |t| "compliance://" + InspecPlugins::Compliance::API.sanitize_profile_name(t) }
88
+ # iterate over tests and add compliance scheme
89
+ tests = tests.map { |t| "compliance://" + InspecPlugins::Compliance::API.sanitize_profile_name(t) }
81
90
 
82
- runner = Inspec::Runner.new(o)
83
- tests.each { |target| runner.add_target(target) }
91
+ runner = Inspec::Runner.new(o)
92
+ tests.each { |target| runner.add_target(target) }
84
93
 
85
- exit runner.run
86
- rescue ArgumentError, RuntimeError, Train::UserError => e
87
- $stderr.puts e.message
88
- exit 1
94
+ exit runner.run
95
+ rescue ArgumentError, RuntimeError, Train::UserError => e
96
+ $stderr.puts e.message
97
+ exit 1
98
+ end
99
+ }
89
100
  end
90
101
 
91
102
  desc "download PROFILE", "downloads a profile from #{AUTOMATE_PRODUCT_NAME}"
92
103
  option :name, type: :string,
93
104
  desc: "Name of the archive filename (file type will be added)"
94
105
  def download(profile_name)
95
- o = options.dup
96
- configure_logger(o)
97
-
98
- config = InspecPlugins::Compliance::Configuration.new
99
- return unless loggedin(config)
100
-
101
- profile_name = InspecPlugins::Compliance::API.sanitize_profile_name(profile_name)
102
- if InspecPlugins::Compliance::API.exist?(config, profile_name)
103
- puts "Downloading `#{profile_name}`"
104
-
105
- fetcher = InspecPlugins::Compliance::Fetcher.resolve(
106
- {
107
- compliance: profile_name,
108
- }
109
- )
110
-
111
- # we provide a name, the fetcher adds the extension
112
- _owner, id = profile_name.split("/")
113
- file_name = fetcher.fetch(o.name || id)
114
- puts "Profile stored to #{file_name}"
115
- else
116
- puts "Profile #{profile_name} is not available in #{AUTOMATE_PRODUCT_NAME}."
117
- exit 1
118
- end
106
+ Inspec.with_feature("inspec-cli-compliance-download") {
107
+ o = options.dup
108
+ configure_logger(o)
109
+
110
+ config = InspecPlugins::Compliance::Configuration.new
111
+ return unless loggedin(config)
112
+
113
+ profile_name = InspecPlugins::Compliance::API.sanitize_profile_name(profile_name)
114
+ if InspecPlugins::Compliance::API.exist?(config, profile_name)
115
+ puts "Downloading `#{profile_name}`"
116
+
117
+ fetcher = InspecPlugins::Compliance::Fetcher.resolve(
118
+ {
119
+ compliance: profile_name,
120
+ }
121
+ )
122
+
123
+ # we provide a name, the fetcher adds the extension
124
+ _owner, id = profile_name.split("/")
125
+ file_name = fetcher.fetch(o.name || id)
126
+ puts "Profile stored to #{file_name}"
127
+ else
128
+ puts "Profile #{profile_name} is not available in #{AUTOMATE_PRODUCT_NAME}."
129
+ exit 1
130
+ end
131
+ }
119
132
  end
120
133
 
121
134
  desc "upload PATH", "uploads a local profile to #{AUTOMATE_PRODUCT_NAME}"
@@ -124,129 +137,137 @@ module InspecPlugins
124
137
  option :owner, type: :string, required: false,
125
138
  desc: "Owner that should own the profile"
126
139
  def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
127
- config = InspecPlugins::Compliance::Configuration.new
128
- return unless loggedin(config)
140
+ Inspec.with_feature("inspec-cli-compliance-upload") {
141
+ config = InspecPlugins::Compliance::Configuration.new
142
+ return unless loggedin(config)
129
143
 
130
- # set owner to config
131
- config["owner"] = options["owner"] || config["user"]
144
+ # set owner to config
145
+ config["owner"] = options["owner"] || config["user"]
132
146
 
133
- unless File.exist?(path)
134
- puts "Directory #{path} does not exist."
135
- exit 1
136
- end
147
+ unless File.exist?(path)
148
+ puts "Directory #{path} does not exist."
149
+ exit 1
150
+ end
137
151
 
138
- vendor_deps(path, options) if File.directory?(path)
152
+ vendor_deps(path, options) if File.directory?(path)
139
153
 
140
- o = options.dup
141
- configure_logger(o)
154
+ o = options.dup
155
+ configure_logger(o)
142
156
 
143
- # only run against the mock backend, otherwise we run against the local system
144
- o[:backend] = Inspec::Backend.create(Inspec::Config.mock)
145
- o[:check_mode] = true
146
- o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])
157
+ # only run against the mock backend, otherwise we run against the local system
158
+ o[:backend] = Inspec::Backend.create(Inspec::Config.mock)
159
+ o[:check_mode] = true
160
+ o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])
147
161
 
148
- # check the profile, we only allow to upload valid profiles
149
- profile = Inspec::Profile.for_target(path, o)
162
+ # check the profile, we only allow to upload valid profiles
163
+ profile = Inspec::Profile.for_target(path, o)
150
164
 
151
- # start verification process
152
- error_count = 0
153
- error = lambda { |msg|
154
- error_count += 1
155
- puts msg
156
- }
165
+ # start verification process
166
+ error_count = 0
167
+ error = lambda { |msg|
168
+ error_count += 1
169
+ puts msg
170
+ }
157
171
 
158
- result = profile.check
159
- unless result[:summary][:valid]
160
- error.call("Profile check failed. Please fix the profile before upload.")
161
- else
162
- puts("Profile is valid")
163
- end
164
-
165
- # determine user information
166
- if (config["token"].nil? && config["refresh_token"].nil?) || config["user"].nil?
167
- error.call("Please login via `#{EXEC_NAME} #{subcommand_name} login`")
168
- end
169
-
170
- # read profile name from inspec.yml
171
- profile_name = profile.name
172
-
173
- # read profile version from inspec.yml
174
- profile_version = profile.version
175
-
176
- # check that the profile is not uploaded already,
177
- # confirm upload to the user (overwrite with --force)
178
- if InspecPlugins::Compliance::API.exist?(config, "#{config["owner"]}/#{profile_name}##{profile_version}") && !options["overwrite"]
179
- error.call("Profile exists on the server, use --overwrite")
180
- end
181
-
182
- # abort if we found an error
183
- if error_count > 0
184
- puts "Found #{error_count} error(s)"
185
- exit 1
186
- end
187
-
188
- # if it is a directory, tar it to tmp directory
189
- generated = false
190
- if File.directory?(path)
191
- generated = true
192
- archive_path = Dir::Tmpname.create([profile_name, ".tar.gz"]) {}
193
- puts "Generate temporary profile archive at #{archive_path}"
194
- profile.archive({ output: archive_path, ignore_errors: false, overwrite: true })
195
- else
196
- archive_path = path
197
- end
198
-
199
- puts "Start upload to #{config["owner"]}/#{profile_name}"
200
- pname = ERB::Util.url_encode(profile_name)
201
-
202
- puts "Uploading to #{AUTOMATE_PRODUCT_NAME}"
203
-
204
- success, msg = InspecPlugins::Compliance::API.upload(config, config["owner"], pname, archive_path)
205
-
206
- # delete temp file if it was temporary generated
207
- File.delete(archive_path) if generated && File.exist?(archive_path)
208
-
209
- if success
210
- puts "Successfully uploaded profile"
211
- else
212
- puts "Error during profile upload:"
213
- puts msg
214
- exit 1
215
- end
172
+ result = profile.check
173
+ unless result[:summary][:valid]
174
+ error.call("Profile check failed. Please fix the profile before upload.")
175
+ else
176
+ puts("Profile is valid")
177
+ end
178
+
179
+ # determine user information
180
+ if (config["token"].nil? && config["refresh_token"].nil?) || config["user"].nil?
181
+ error.call("Please login via `#{EXEC_NAME} #{subcommand_name} login`")
182
+ end
183
+
184
+ # read profile name from inspec.yml
185
+ profile_name = profile.name
186
+
187
+ # read profile version from inspec.yml
188
+ profile_version = profile.version
189
+
190
+ # check that the profile is not uploaded already,
191
+ # confirm upload to the user (overwrite with --force)
192
+ if InspecPlugins::Compliance::API.exist?(config, "#{config["owner"]}/#{profile_name}##{profile_version}") && !options["overwrite"]
193
+ error.call("Profile exists on the server, use --overwrite")
194
+ end
195
+
196
+ # abort if we found an error
197
+ if error_count > 0
198
+ puts "Found #{error_count} error(s)"
199
+ exit 1
200
+ end
201
+
202
+ # if it is a directory, tar it to tmp directory
203
+ generated = false
204
+ if File.directory?(path)
205
+ generated = true
206
+ archive_path = Dir::Tmpname.create([profile_name, ".tar.gz"]) {}
207
+ puts "Generate temporary profile archive at #{archive_path}"
208
+ profile.archive({ output: archive_path, ignore_errors: false, overwrite: true })
209
+ else
210
+ archive_path = path
211
+ end
212
+
213
+ puts "Start upload to #{config["owner"]}/#{profile_name}"
214
+ pname = ERB::Util.url_encode(profile_name)
215
+
216
+ puts "Uploading to #{AUTOMATE_PRODUCT_NAME}"
217
+
218
+ success, msg = InspecPlugins::Compliance::API.upload(config, config["owner"], pname, archive_path)
219
+
220
+ # delete temp file if it was temporary generated
221
+ File.delete(archive_path) if generated && File.exist?(archive_path)
222
+
223
+ if success
224
+ puts "Successfully uploaded profile"
225
+ else
226
+ puts "Error during profile upload:"
227
+ puts msg
228
+ exit 1
229
+ end
230
+ }
216
231
  end
217
232
 
218
233
  desc "version", "displays the version of the #{AUTOMATE_PRODUCT_NAME} server"
219
234
  def version
220
- config = InspecPlugins::Compliance::Configuration.new
221
- info = InspecPlugins::Compliance::API.version(config)
222
- if !info.nil? && info["build_timestamp"]
223
- # key info["api"] is not longer available in latest version api response
224
- puts "Name: automate"
225
- puts "Version: #{info["build_timestamp"]}"
226
- else
227
- puts "Could not determine server version."
228
- exit 1
229
- end
230
- rescue InspecPlugins::Compliance::ServerConfigurationMissing
231
- puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
232
- exit 1
235
+ Inspec.with_feature("inspec-cli-compliance-version") {
236
+ begin
237
+ config = InspecPlugins::Compliance::Configuration.new
238
+ info = InspecPlugins::Compliance::API.version(config)
239
+ if !info.nil? && info["build_timestamp"]
240
+ # key info["api"] is not longer available in latest version api response
241
+ puts "Name: automate"
242
+ puts "Version: #{info["build_timestamp"]}"
243
+ else
244
+ puts "Could not determine server version."
245
+ exit 1
246
+ end
247
+ rescue InspecPlugins::Compliance::ServerConfigurationMissing
248
+ puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
249
+ exit 1
250
+ end
251
+ }
233
252
  end
234
253
 
235
254
  desc "logout", "user logout from #{AUTOMATE_PRODUCT_NAME}"
236
255
  def logout
237
- config = InspecPlugins::Compliance::Configuration.new
238
- unless config.supported?(:oidc) || config["token"].nil? || config["server_type"] == "automate"
256
+ Inspec.with_feature("inspec-cli-compliance-logout") {
239
257
  config = InspecPlugins::Compliance::Configuration.new
240
- url = "#{config["server"]}/logout"
241
- InspecPlugins::Compliance::HTTP.post(url, config["token"], config["insecure"], !config.supported?(:oidc))
242
- end
243
- success = config.destroy
244
-
245
- if success
246
- puts "Successfully logged out"
247
- else
248
- puts "Could not log out"
249
- end
258
+ unless config.supported?(:oidc) || config["token"].nil? || config["server_type"] == "automate"
259
+ config = InspecPlugins::Compliance::Configuration.new
260
+ url = "#{config["server"]}/logout"
261
+ InspecPlugins::Compliance::HTTP.post(url, config["token"], config["insecure"], !config.supported?(:oidc))
262
+ end
263
+ success = config.destroy
264
+
265
+ if success
266
+ puts "Successfully logged out"
267
+ else
268
+ puts "Could not log out"
269
+ end
270
+ }
250
271
  end
251
272
 
252
273
  private
@@ -1,5 +1,6 @@
1
1
  require_relative "profile"
2
2
  require "inspec/dist"
3
+ require "inspec/feature"
3
4
 
4
5
  module InspecPlugins
5
6
  module Habitat
@@ -14,17 +15,23 @@ module InspecPlugins
14
15
  option :output_dir, type: :string, required: false,
15
16
  desc: "Output directory for the Habitat artifact. Default: current directory"
16
17
  def create(path = ".")
17
- InspecPlugins::Habitat::Profile.new(path, options).create
18
+ Inspec.with_feature("inspec-cli-habitat-profile-create") {
19
+ InspecPlugins::Habitat::Profile.new(path, options).create
20
+ }
18
21
  end
19
22
 
20
23
  desc "setup PATH", "Configure the profile at PATH for Habitat, including a plan and hooks"
21
24
  def setup(path = ".")
22
- InspecPlugins::Habitat::Profile.new(path, options).setup
25
+ Inspec.with_feature("inspec-cli-habitat-profile-setup") {
26
+ InspecPlugins::Habitat::Profile.new(path, options).setup
27
+ }
23
28
  end
24
29
 
25
30
  desc "upload PATH", "Create then upload a Habitat artifact for the profile found at PATH to the Habitat Builder Depot"
26
31
  def upload(path = ".")
27
- InspecPlugins::Habitat::Profile.new(path, options).upload
32
+ Inspec.with_feature("inspec-cli-habitat-profile-upload") {
33
+ InspecPlugins::Habitat::Profile.new(path, options).upload
34
+ }
28
35
  end
29
36
  end
30
37
 
@@ -1,5 +1,6 @@
1
1
  require "pathname" unless defined?(Pathname)
2
2
  require_relative "renderer"
3
+ require "inspec/feature"
3
4
 
4
5
  module InspecPlugins
5
6
  module Init
@@ -27,33 +27,35 @@ module InspecPlugins
27
27
  option :copyright, type: :string, default: nil, desc: "A copyright statement, to be added to LICENSE"
28
28
 
29
29
  def plugin(plugin_name)
30
- plugin_type = determine_plugin_type(plugin_name)
31
- snake_case = plugin_name.tr("-", "_")
30
+ Inspec.with_feature("inspec-cli-init-plugin") {
31
+ plugin_type = determine_plugin_type(plugin_name)
32
+ snake_case = plugin_name.tr("-", "_")
32
33
 
33
- # Handle deprecation of option --hook
34
- unless options[:hook].nil?
35
- Inspec.deprecate "cli_option_hook"
36
- options[:activator] = options.delete(:hook)
37
- end
34
+ # Handle deprecation of option --hook
35
+ unless options[:hook].nil?
36
+ Inspec.deprecate "cli_option_hook"
37
+ options[:activator] = options.delete(:hook)
38
+ end
38
39
 
39
- template_vars = {
40
- name: plugin_name,
41
- plugin_name: plugin_name,
42
- snake_case: snake_case,
43
- }.merge(plugin_vars_from_opts)
40
+ template_vars = {
41
+ name: plugin_name,
42
+ plugin_name: plugin_name,
43
+ snake_case: snake_case,
44
+ }.merge(plugin_vars_from_opts)
44
45
 
45
- template_path = File.join("plugins", plugin_type + "-plugin-template")
46
+ template_path = File.join("plugins", plugin_type + "-plugin-template")
46
47
 
47
- render_opts = {
48
- templates_path: TEMPLATES_PATH,
49
- overwrite: options[:overwrite],
50
- file_rename_map: make_rename_map(plugin_type, plugin_name, snake_case),
51
- skip_files: make_skip_list(template_vars["activators"].keys),
52
- }
48
+ render_opts = {
49
+ templates_path: TEMPLATES_PATH,
50
+ overwrite: options[:overwrite],
51
+ file_rename_map: make_rename_map(plugin_type, plugin_name, snake_case),
52
+ skip_files: make_skip_list(template_vars["activators"].keys),
53
+ }
53
54
 
54
- renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
55
+ renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
55
56
 
56
- renderer.render_with_values(template_path, plugin_type + " plugin", template_vars)
57
+ renderer.render_with_values(template_path, plugin_type + " plugin", template_vars)
58
+ }
57
59
  end
58
60
 
59
61
  private
@@ -25,22 +25,24 @@ module InspecPlugins
25
25
  option :overwrite, type: :boolean, default: false,
26
26
  desc: "Overwrites existing directory"
27
27
  def profile(new_profile_name)
28
- unless valid_profile_platforms.include?(options[:platform])
29
- ui.error "Unable to generate profile: No template available for platform '#{options[:platform]}' (expected one of: #{valid_profile_platforms.join(", ")})"
30
- ui.exit(:usage_error)
31
- end
32
- template_path = File.join("profiles", options[:platform])
28
+ Inspec.with_feature("inspec-cli-init-profile") {
29
+ unless valid_profile_platforms.include?(options[:platform])
30
+ ui.error "Unable to generate profile: No template available for platform '#{options[:platform]}' (expected one of: #{valid_profile_platforms.join(", ")})"
31
+ ui.exit(:usage_error)
32
+ end
33
+ template_path = File.join("profiles", options[:platform])
33
34
 
34
- render_opts = {
35
- templates_path: TEMPLATES_PATH,
36
- overwrite: options[:overwrite],
37
- }
38
- renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
35
+ render_opts = {
36
+ templates_path: TEMPLATES_PATH,
37
+ overwrite: options[:overwrite],
38
+ }
39
+ renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
39
40
 
40
- vars = {
41
- name: new_profile_name,
41
+ vars = {
42
+ name: new_profile_name,
43
+ }
44
+ renderer.render_with_values(template_path, "profile", vars)
42
45
  }
43
- renderer.render_with_values(template_path, "profile", vars)
44
46
  end
45
47
  end
46
48
  end
@@ -35,21 +35,23 @@ module InspecPlugins
35
35
  # + Add --overwrite option
36
36
 
37
37
  def resource(resource_name)
38
- resource_vars_from_opts_resource
39
- template_vars = {
40
- name: options[:path], # This is used for the path prefix
41
- resource_name: resource_name,
42
- }
43
- template_vars.merge!(options)
44
- template_path = File.join("resources", template_vars["template"])
38
+ Inspec.with_feature("inspec-cli-init-resource") {
39
+ resource_vars_from_opts_resource
40
+ template_vars = {
41
+ name: options[:path], # This is used for the path prefix
42
+ resource_name: resource_name,
43
+ }
44
+ template_vars.merge!(options)
45
+ template_path = File.join("resources", template_vars["template"])
45
46
 
46
- render_opts = {
47
- templates_path: TEMPLATES_PATH,
48
- overwrite: options[:overwrite],
49
- file_rename_map: make_rename_map_resource(template_vars),
47
+ render_opts = {
48
+ templates_path: TEMPLATES_PATH,
49
+ overwrite: options[:overwrite],
50
+ file_rename_map: make_rename_map_resource(template_vars),
51
+ }
52
+ renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
53
+ renderer.render_with_values(template_path, "resource", template_vars)
50
54
  }
51
- renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
52
- renderer.render_with_values(template_path, "resource", template_vars)
53
55
  end
54
56
 
55
57
  private
@@ -0,0 +1,16 @@
1
+ # License Plugin
2
+
3
+ ## license list
4
+
5
+ Implements the `inspec license list` CLI command.
6
+
7
+ ## license add
8
+
9
+ Implements the `inspec license add` CLI command.
10
+
11
+ ### What This Plugin Does
12
+
13
+ This plugin consists of the following subcommands:
14
+
15
+ 1. `add`: helps to add a new license
16
+ 2. `list`: helps to list all the licenses for the current user
@@ -0,0 +1,6 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "inspec-license"
3
+ spec.summary = "Plugin to list user licenses."
4
+ spec.description = ""
5
+ spec.license = "Apache-2.0"
6
+ end
@@ -0,0 +1,26 @@
1
+ require "chef-licensing"
2
+ module InspecPlugins::License
3
+ class CLI < Inspec.plugin(2, :cli_command)
4
+ include Inspec::Dist
5
+
6
+ subcommand_desc "license SUBCOMMAND [options]", "Manage #{PRODUCT_NAME} license"
7
+ desc "list", "List licenses (not applicable to local licensing service)"
8
+ def list
9
+ ChefLicensing.list_license_keys_info
10
+ rescue ChefLicensing::Error => e
11
+ Inspec::Log.error e.message
12
+ Inspec::UI.new.exit(Inspec::UI::EXIT_LICENSE_NOT_SET)
13
+ end
14
+
15
+ desc "add", "Add a new license (not applicable to local licensing service)"
16
+ def add
17
+ ChefLicensing.add_license
18
+ rescue ChefLicensing::LicenseKeyFetcher::LicenseKeyAddNotAllowed => e
19
+ Inspec::Log.error e.message
20
+ Inspec::UI.new.exit(Inspec::UI::EXIT_LICENSE_NOT_SET)
21
+ rescue ChefLicensing::Error => e
22
+ Inspec::Log.error e.message
23
+ Inspec::UI.new.exit(Inspec::UI::EXIT_LICENSE_NOT_SET)
24
+ end
25
+ end
26
+ end