inspec-core 5.24.7 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/Chef-EULA +9 -0
  3. data/Gemfile +25 -36
  4. data/etc/features.sig +6 -0
  5. data/etc/features.yaml +94 -0
  6. data/inspec-core.gemspec +21 -19
  7. data/lib/inspec/archive/tar.rb +0 -1
  8. data/lib/inspec/backend.rb +2 -0
  9. data/lib/inspec/base_cli.rb +80 -14
  10. data/lib/inspec/cached_fetcher.rb +24 -3
  11. data/lib/inspec/cli.rb +292 -235
  12. data/lib/inspec/config.rb +24 -11
  13. data/lib/inspec/dependencies/cache.rb +33 -0
  14. data/lib/inspec/dependencies/dependency_set.rb +2 -2
  15. data/lib/inspec/dsl.rb +1 -1
  16. data/lib/inspec/enhanced_outcomes.rb +1 -0
  17. data/lib/inspec/errors.rb +5 -0
  18. data/lib/inspec/exceptions.rb +1 -0
  19. data/lib/inspec/feature/config.rb +75 -0
  20. data/lib/inspec/feature/runner.rb +26 -0
  21. data/lib/inspec/feature.rb +34 -0
  22. data/lib/inspec/fetcher/git.rb +6 -21
  23. data/lib/inspec/fetcher/url.rb +7 -29
  24. data/lib/inspec/file_provider.rb +0 -1
  25. data/lib/inspec/globals.rb +6 -0
  26. data/lib/inspec/input_registry.rb +1 -5
  27. data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +7 -0
  28. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +30 -2
  29. data/lib/inspec/profile.rb +49 -13
  30. data/lib/inspec/reporters/cli.rb +1 -1
  31. data/lib/inspec/reporters.rb +67 -54
  32. data/lib/inspec/resources/audit_policy.rb +2 -8
  33. data/lib/inspec/resources/groups.rb +0 -52
  34. data/lib/inspec/resources/mssql_session.rb +1 -13
  35. data/lib/inspec/resources/nftables.rb +1 -14
  36. data/lib/inspec/resources/oracledb_session.rb +11 -72
  37. data/lib/inspec/resources/postgres_session.rb +5 -9
  38. data/lib/inspec/resources/sybase_session.rb +2 -11
  39. data/lib/inspec/resources/virtualization.rb +1 -1
  40. data/lib/inspec/rule.rb +9 -14
  41. data/lib/inspec/run_data.rb +7 -5
  42. data/lib/inspec/runner.rb +35 -6
  43. data/lib/inspec/runner_rspec.rb +12 -9
  44. data/lib/inspec/secrets/yaml.rb +5 -1
  45. data/lib/inspec/shell.rb +10 -0
  46. data/lib/inspec/ui.rb +4 -0
  47. data/lib/inspec/utils/licensing_config.rb +9 -0
  48. data/lib/inspec/utils/profile_ast_helpers.rb +12 -39
  49. data/lib/inspec/utils/waivers/csv_file_reader.rb +1 -1
  50. data/lib/inspec/utils/waivers/excel_file_reader.rb +1 -1
  51. data/lib/inspec/version.rb +1 -1
  52. data/lib/inspec/waiver_file_reader.rb +18 -35
  53. data/lib/inspec.rb +2 -1
  54. data/lib/matchers/matchers.rb +3 -3
  55. data/lib/plugins/inspec-compliance/README.md +1 -11
  56. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +189 -170
  57. data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +10 -3
  58. data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
  59. data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +23 -21
  60. data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +15 -13
  61. data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +15 -13
  62. data/lib/plugins/inspec-license/README.md +16 -0
  63. data/lib/plugins/inspec-license/inspec-license.gemspec +6 -0
  64. data/lib/plugins/inspec-license/lib/inspec-license/cli.rb +26 -0
  65. data/lib/plugins/inspec-license/lib/inspec-license.rb +14 -0
  66. data/lib/plugins/inspec-parallel/README.md +27 -0
  67. data/lib/plugins/inspec-parallel/inspec-parallel.gemspec +6 -0
  68. data/lib/plugins/inspec-parallel/lib/inspec-parallel/child_status_reporter.rb +61 -0
  69. data/lib/plugins/inspec-parallel/lib/inspec-parallel/cli.rb +39 -0
  70. data/lib/plugins/inspec-parallel/lib/inspec-parallel/command.rb +219 -0
  71. data/lib/plugins/inspec-parallel/lib/inspec-parallel/runner.rb +265 -0
  72. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/base.rb +24 -0
  73. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/silent.rb +7 -0
  74. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/status.rb +124 -0
  75. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/text.rb +23 -0
  76. data/lib/plugins/inspec-parallel/lib/inspec-parallel/validator.rb +170 -0
  77. data/lib/plugins/inspec-parallel/lib/inspec-parallel.rb +18 -0
  78. data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +10 -11
  79. data/lib/plugins/inspec-sign/lib/inspec-sign/cli.rb +11 -4
  80. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +6 -13
  81. data/lib/source_readers/inspec.rb +1 -1
  82. metadata +55 -47
@@ -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}"
@@ -123,132 +136,138 @@ module InspecPlugins
123
136
  desc: "Overwrite existing profile on Server."
124
137
  option :owner, type: :string, required: false,
125
138
  desc: "Owner that should own the profile"
126
- option :legacy, type: :boolean, default: false,
127
- desc: "Enable legacy functionality, activating both legacy export and legacy check."
128
139
  def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
129
- config = InspecPlugins::Compliance::Configuration.new
130
- return unless loggedin(config)
140
+ Inspec.with_feature("inspec-cli-compliance-upload") {
141
+ config = InspecPlugins::Compliance::Configuration.new
142
+ return unless loggedin(config)
131
143
 
132
- # set owner to config
133
- config["owner"] = options["owner"] || config["user"]
144
+ # set owner to config
145
+ config["owner"] = options["owner"] || config["user"]
134
146
 
135
- unless File.exist?(path)
136
- puts "Directory #{path} does not exist."
137
- exit 1
138
- end
147
+ unless File.exist?(path)
148
+ puts "Directory #{path} does not exist."
149
+ exit 1
150
+ end
139
151
 
140
- vendor_deps(path, options) if File.directory?(path)
152
+ vendor_deps(path, options) if File.directory?(path)
141
153
 
142
- o = options.dup
143
- configure_logger(o)
154
+ o = options.dup
155
+ configure_logger(o)
144
156
 
145
- # only run against the mock backend, otherwise we run against the local system
146
- o[:backend] = Inspec::Backend.create(Inspec::Config.mock)
147
- o[:check_mode] = true
148
- 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])
149
161
 
150
- # check the profile, we only allow to upload valid profiles
151
- 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)
152
164
 
153
- # start verification process
154
- error_count = 0
155
- error = lambda { |msg|
156
- error_count += 1
157
- puts msg
158
- }
165
+ # start verification process
166
+ error_count = 0
167
+ error = lambda { |msg|
168
+ error_count += 1
169
+ puts msg
170
+ }
159
171
 
160
- result = options["legacy"] ? profile.legacy_check : profile.check
161
- unless result[:summary][:valid]
162
- error.call("Profile check failed. Please fix the profile before upload.")
163
- else
164
- puts("Profile is valid")
165
- end
166
-
167
- # determine user information
168
- if (config["token"].nil? && config["refresh_token"].nil?) || config["user"].nil?
169
- error.call("Please login via `#{EXEC_NAME} #{subcommand_name} login`")
170
- end
171
-
172
- # read profile name from inspec.yml
173
- profile_name = profile.name
174
-
175
- # read profile version from inspec.yml
176
- profile_version = profile.version
177
-
178
- # check that the profile is not uploaded already,
179
- # confirm upload to the user (overwrite with --force)
180
- if InspecPlugins::Compliance::API.exist?(config, "#{config["owner"]}/#{profile_name}##{profile_version}") && !options["overwrite"]
181
- error.call("Profile exists on the server, use --overwrite")
182
- end
183
-
184
- # abort if we found an error
185
- if error_count > 0
186
- puts "Found #{error_count} error(s)"
187
- exit 1
188
- end
189
-
190
- # if it is a directory, tar it to tmp directory
191
- generated = false
192
- if File.directory?(path)
193
- generated = true
194
- archive_path = Dir::Tmpname.create([profile_name, ".tar.gz"]) {}
195
- puts "Generate temporary profile archive at #{archive_path}"
196
- profile.archive({ output: archive_path, ignore_errors: false, overwrite: true, legacy_export: options["legacy"] })
197
- else
198
- archive_path = path
199
- end
200
-
201
- puts "Start upload to #{config["owner"]}/#{profile_name}"
202
- pname = ERB::Util.url_encode(profile_name)
203
-
204
- puts "Uploading to #{AUTOMATE_PRODUCT_NAME}"
205
-
206
- success, msg = InspecPlugins::Compliance::API.upload(config, config["owner"], pname, archive_path)
207
-
208
- # delete temp file if it was temporary generated
209
- File.delete(archive_path) if generated && File.exist?(archive_path)
210
-
211
- if success
212
- puts "Successfully uploaded profile"
213
- else
214
- puts "Error during profile upload:"
215
- puts msg
216
- exit 1
217
- 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
+ }
218
231
  end
219
232
 
220
233
  desc "version", "displays the version of the #{AUTOMATE_PRODUCT_NAME} server"
221
234
  def version
222
- config = InspecPlugins::Compliance::Configuration.new
223
- info = InspecPlugins::Compliance::API.version(config)
224
- if !info.nil? && info["build_timestamp"]
225
- # key info["api"] is not longer available in latest version api response
226
- puts "Name: automate"
227
- puts "Version: #{info["build_timestamp"]}"
228
- else
229
- puts "Could not determine server version."
230
- exit 1
231
- end
232
- rescue InspecPlugins::Compliance::ServerConfigurationMissing
233
- puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
234
- 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
+ }
235
252
  end
236
253
 
237
254
  desc "logout", "user logout from #{AUTOMATE_PRODUCT_NAME}"
238
255
  def logout
239
- config = InspecPlugins::Compliance::Configuration.new
240
- unless config.supported?(:oidc) || config["token"].nil? || config["server_type"] == "automate"
256
+ Inspec.with_feature("inspec-cli-compliance-logout") {
241
257
  config = InspecPlugins::Compliance::Configuration.new
242
- url = "#{config["server"]}/logout"
243
- InspecPlugins::Compliance::HTTP.post(url, config["token"], config["insecure"], !config.supported?(:oidc))
244
- end
245
- success = config.destroy
246
-
247
- if success
248
- puts "Successfully logged out"
249
- else
250
- puts "Could not log out"
251
- 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
+ }
252
271
  end
253
272
 
254
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