hammer_cli_foreman 2.0.0 → 2.1.2

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/doc/developer_docs.md +1 -0
  3. data/doc/plugin.md +22 -0
  4. data/doc/release_notes.md +33 -0
  5. data/lib/hammer_cli_foreman.rb +9 -1
  6. data/lib/hammer_cli_foreman/api/connection.rb +1 -18
  7. data/lib/hammer_cli_foreman/api/oauth/authentication_code_grant.rb +7 -4
  8. data/lib/hammer_cli_foreman/api/session_authenticator_wrapper.rb +0 -1
  9. data/lib/hammer_cli_foreman/associating_commands.rb +33 -5
  10. data/lib/hammer_cli_foreman/audit.rb +7 -0
  11. data/lib/hammer_cli_foreman/auth.rb +6 -6
  12. data/lib/hammer_cli_foreman/bookmark.rb +50 -0
  13. data/lib/hammer_cli_foreman/command_extensions.rb +2 -0
  14. data/lib/hammer_cli_foreman/command_extensions/puppet_environment.rb +13 -7
  15. data/lib/hammer_cli_foreman/command_extensions/puppet_environments.rb +13 -7
  16. data/lib/hammer_cli_foreman/command_extensions/subnet.rb +25 -0
  17. data/lib/hammer_cli_foreman/command_extensions/user.rb +17 -0
  18. data/lib/hammer_cli_foreman/commands.rb +20 -11
  19. data/lib/hammer_cli_foreman/compute_resource.rb +15 -0
  20. data/lib/hammer_cli_foreman/compute_resource/ec2.rb +11 -0
  21. data/lib/hammer_cli_foreman/compute_resource/gce.rb +9 -0
  22. data/lib/hammer_cli_foreman/compute_resource/libvirt.rb +11 -0
  23. data/lib/hammer_cli_foreman/compute_resource/openstack.rb +7 -0
  24. data/lib/hammer_cli_foreman/compute_resource/ovirt.rb +21 -9
  25. data/lib/hammer_cli_foreman/compute_resource/vmware.rb +15 -2
  26. data/lib/hammer_cli_foreman/hostgroup.rb +11 -19
  27. data/lib/hammer_cli_foreman/hosts/common_update_options.rb +32 -10
  28. data/lib/hammer_cli_foreman/id_resolver.rb +12 -11
  29. data/lib/hammer_cli_foreman/mail_notification.rb +31 -0
  30. data/lib/hammer_cli_foreman/operating_system.rb +1 -1
  31. data/lib/hammer_cli_foreman/option_builders.rb +70 -48
  32. data/lib/hammer_cli_foreman/option_sources.rb +1 -0
  33. data/lib/hammer_cli_foreman/option_sources/referenced_resource_id_params.rb +47 -0
  34. data/lib/hammer_cli_foreman/sessions.rb +1 -3
  35. data/lib/hammer_cli_foreman/subnet.rb +26 -15
  36. data/lib/hammer_cli_foreman/task_helper.rb +180 -0
  37. data/lib/hammer_cli_foreman/user.rb +7 -17
  38. data/lib/hammer_cli_foreman/user_mail_notification.rb +51 -0
  39. data/lib/hammer_cli_foreman/version.rb +1 -1
  40. data/lib/hammer_cli_foreman/virtual_machine.rb +55 -0
  41. data/locale/ca/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  42. data/locale/de/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  43. data/locale/en/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  44. data/locale/en_GB/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  45. data/locale/es/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  46. data/locale/fr/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  47. data/locale/it/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  48. data/locale/ja/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  49. data/locale/ko/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  50. data/locale/pt_BR/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  51. data/locale/ru/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  52. data/locale/zh_CN/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  53. data/locale/zh_TW/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  54. data/test/data/2.1/foreman_api.json +1 -0
  55. data/test/functional/associating_commands_test.rb +134 -30
  56. data/test/functional/bookmark_test.rb +193 -0
  57. data/test/functional/host_test.rb +27 -1
  58. data/test/functional/http_proxy_test.rb +1 -4
  59. data/test/functional/mail_notification_test.rb +57 -0
  60. data/test/functional/subnet/create_test.rb +28 -5
  61. data/test/functional/template_test.rb +2 -2
  62. data/test/functional/user_mail_notification_test.rb +89 -0
  63. data/test/functional/virtual_machine_test.rb +129 -0
  64. data/test/reports/TEST-Minitest-Result.xml +4344 -0
  65. data/test/test_helper.rb +1 -1
  66. data/test/unit/audit_test.rb +1 -0
  67. data/test/unit/sessions_test.rb +2 -13
  68. metadata +28 -6
@@ -0,0 +1,31 @@
1
+
2
+ module HammerCLIForeman
3
+
4
+ class MailNotification < HammerCLIForeman::Command
5
+ resource :mail_notifications
6
+
7
+ class ListCommand < HammerCLIForeman::ListCommand
8
+
9
+ output do
10
+ field :id, _("Id")
11
+ field :name, _("Name")
12
+ end
13
+
14
+ build_options
15
+ end
16
+
17
+ class InfoCommand < HammerCLIForeman::InfoCommand
18
+ output do
19
+ field :id, _("Id")
20
+ field :name, _("Name")
21
+ field :description, _("Description")
22
+ field :subscription_type, _("Subscription type")
23
+ end
24
+
25
+ build_options
26
+ end
27
+
28
+ autoload_subcommands
29
+ end
30
+ end
31
+
@@ -136,7 +136,7 @@ module HammerCLIForeman
136
136
  params = {
137
137
  "os_default_template" => {
138
138
  "provisioning_template_id" => option_provisioning_template_id,
139
- "provisioning_kind_name" => tpl_kind_name
139
+ "template_kind_name" => tpl_kind_name
140
140
  }
141
141
  }.merge base_action_params
142
142
 
@@ -73,12 +73,15 @@ module HammerCLIForeman
73
73
  builders << SearchablesOptionBuilder.new(resource, @searchables)
74
74
  dependent_resources += @dependency_resolver.resource_dependencies(resource, :only_required => true, :recursive => true)
75
75
  end
76
-
77
76
  dependent_resources += @dependency_resolver.action_dependencies(action, :only_required => false, :recursive => false)
78
77
  dependent_resources += @dependency_resolver.action_dependencies(action, :only_required => true, :recursive => true)
79
78
 
80
79
  dependent_resources.uniq(&:name).each do |dep_resource|
81
- builders << DependentSearchablesOptionBuilder.new(dep_resource, @searchables)
80
+ builders << DependentSearchablesOptionBuilder.new(
81
+ dep_resource,
82
+ @searchables,
83
+ context: { action: action }
84
+ )
82
85
  end
83
86
 
84
87
  IdArrayParamsFilter.new(:only_required => false).for_action(action).each do |p|
@@ -181,9 +184,10 @@ module HammerCLIForeman
181
184
 
182
185
  class DependentSearchablesOptionBuilder < SearchablesAbstractOptionBuilder
183
186
 
184
- def initialize(resource, searchables)
187
+ def initialize(resource, searchables, options = {})
185
188
  @resource = resource
186
189
  @searchables = searchables
190
+ @context = options[:context] || {}
187
191
  end
188
192
 
189
193
  attr_reader :resource
@@ -200,6 +204,13 @@ module HammerCLIForeman
200
204
  searchables = @searchables.for(resource)
201
205
  resource_name = resource.singular_name
202
206
  aliased_name = aliased(resource_name, resource_name_map)
207
+ types = searchables.map(&:name).push('id').map(&:capitalize).join('/')
208
+ associated_resource = resource.singular_name.to_s.tr('_', ' ')
209
+ family = HammerCLI::Options::OptionFamily.new(
210
+ referenced_resource: resource_name,
211
+ aliased_resource: aliased_name,
212
+ description: _('Set the current %{resource} context for the request. %{types} can be used') % { types: types, resource: associated_resource }
213
+ )
203
214
 
204
215
  unless searchables.empty?
205
216
  first = searchables[0]
@@ -207,36 +218,34 @@ module HammerCLIForeman
207
218
 
208
219
  # First option is named by the resource
209
220
  # Eg. --organization with accessor option_organization_name
210
- options << option(
221
+ options << family.child(
211
222
  optionamize("--#{aliased_name}"),
212
223
  "#{aliased_name}_#{first.name}".upcase,
213
224
  first.description || " ",
214
- :attribute_name => HammerCLI.option_accessor_name("#{resource_name}_#{first.name}"),
215
- :referenced_resource => resource.singular_name
225
+ attribute_name: HammerCLI.option_accessor_name("#{resource_name}_#{first.name}")
216
226
  )
217
-
218
227
  # Other options are named by the resource plus the searchable name
219
228
  # Eg. --organization-label with accessor option_organization_label
220
229
  remaining.each do |s|
221
- options << option(
230
+ options << family.send(s.parent? ? :parent : :child,
222
231
  optionamize("--#{aliased_name}-#{s.name}"),
223
232
  "#{aliased_name}_#{s.name}".upcase,
224
233
  s.description || " ",
225
- :attribute_name => HammerCLI.option_accessor_name("#{resource_name}_#{s.name}"),
226
- :referenced_resource => resource.singular_name,
227
- :format => s.format
234
+ attribute_name: HammerCLI.option_accessor_name("#{resource_name}_#{s.name}"),
235
+ format: s.format
228
236
  )
229
237
  end
230
238
  end
231
239
 
232
- options << option(
233
- optionamize("--#{aliased_name}-id"),
234
- "#{aliased_name}_id".upcase,
235
- description("id", :show),
236
- :attribute_name => HammerCLI.option_accessor_name("#{resource_name}_id"),
237
- :format => HammerCLI::Options::Normalizers::Number.new,
238
- :referenced_resource => resource.singular_name
239
- )
240
+ unless options.any? { |o| o.handles?("--#{aliased_name}-id") }
241
+ options << family.parent(
242
+ optionamize("--#{aliased_name}-id"),
243
+ "#{aliased_name}_id".upcase,
244
+ description("#{aliased_name}_id", @context[:action]),
245
+ attribute_name: HammerCLI.option_accessor_name("#{resource_name}_id"),
246
+ format: HammerCLI::Options::Normalizers::Number.new
247
+ )
248
+ end
240
249
  options
241
250
  end
242
251
 
@@ -244,6 +253,14 @@ module HammerCLIForeman
244
253
  resource_name_map[name.to_s] || resource_name_map[name.to_sym] || name
245
254
  end
246
255
 
256
+ def description(param_name, action)
257
+ return super('id', :show) if action.nil?
258
+
259
+ param = ParamsNameFilter.new(param_name).for_action(action).first
260
+ return ' ' if param.nil?
261
+
262
+ param.description
263
+ end
247
264
  end
248
265
 
249
266
  class UpdateDependentSearchablesOptionBuilder < DependentSearchablesOptionBuilder
@@ -254,42 +271,44 @@ module HammerCLIForeman
254
271
  searchables = @searchables.for(resource)
255
272
  resource_name = resource.singular_name
256
273
  aliased_name = aliased(resource_name, resource_name_map)
257
-
274
+ family = HammerCLI::Options::OptionFamily.new(
275
+ prefix: 'new-',
276
+ aliased_resource: aliased_name,
277
+ referenced_resource: resource_name
278
+ )
258
279
  unless searchables.empty?
259
280
  first = searchables[0]
260
281
  remaining = searchables[1..-1] || []
261
282
 
262
283
  # First option is named by the resource
263
284
  # Eg. --new-organization with accessor option_new_organization_name
264
- options << option(
285
+ options << family.child(
265
286
  optionamize("--new-#{aliased_name}"),
266
287
  "new_#{aliased_name}_#{first.name}".upcase,
267
- first.description || ' ',
268
- attribute_name: HammerCLI.option_accessor_name("new_#{resource_name}_#{first.name}"),
269
- referenced_resource: resource.singular_name
288
+ _('Use to update'),
289
+ attribute_name: HammerCLI.option_accessor_name("new_#{resource_name}_#{first.name}")
270
290
  )
271
-
272
291
  # Other options are named by the resource plus the searchable name
273
292
  # Eg. --new-organization-label with accessor option_new_organization_label
274
293
  remaining.each do |s|
275
- options << option(
294
+ options << family.send(s.parent? ? :parent : :child,
276
295
  optionamize("--new-#{aliased_name}-#{s.name}"),
277
296
  "new_#{aliased_name}_#{s.name}".upcase,
278
- s.description || ' ',
279
- attribute_name: HammerCLI.option_accessor_name("new_#{resource_name}_#{s.name}"),
280
- referenced_resource: resource.singular_name
297
+ _('Use to update'),
298
+ attribute_name: HammerCLI.option_accessor_name("new_#{resource_name}_#{s.name}")
281
299
  )
282
300
  end
283
301
  end
284
302
 
285
- options << option(
286
- optionamize("--new-#{aliased_name}-id"),
287
- "new_#{aliased_name}_id".upcase,
288
- description('id', :show),
289
- attribute_name: HammerCLI.option_accessor_name("new_#{resource_name}_id"),
290
- format: HammerCLI::Options::Normalizers::Number.new,
291
- referenced_resource: resource.singular_name
292
- )
303
+ unless options.any? { |o| o.handles?("--new-#{aliased_name}-id") }
304
+ options << family.parent(
305
+ optionamize("--new-#{aliased_name}-id"),
306
+ "new_#{aliased_name}_id".upcase,
307
+ _('Use to update'),
308
+ attribute_name: HammerCLI.option_accessor_name("new_#{resource_name}_id"),
309
+ format: HammerCLI::Options::Normalizers::Number.new
310
+ )
311
+ end
293
312
  options
294
313
  end
295
314
  end
@@ -308,28 +327,31 @@ module HammerCLIForeman
308
327
  unless searchables.empty?
309
328
  first = searchables[0]
310
329
  remaining = searchables[1..-1] || []
311
-
330
+ types = searchables.map(&:plural_name).map(&:capitalize).join('/')
331
+ associated_resource = resource.name.to_s.tr('_', ' ')
332
+ family = HammerCLI::Options::OptionFamily.new(
333
+ format: HammerCLI::Options::Normalizers::List.new,
334
+ referenced_resource: resource_name,
335
+ aliased_resource: aliased_name,
336
+ description: _('%{types} of associated %{resource}') % { types: types, resource: associated_resource }
337
+ )
312
338
  # First option is named by the resource
313
339
  # Eg. --organizations with accessor option_organization_names
314
- options << option(
340
+ options << family.child(
315
341
  optionamize("--#{aliased_plural_name}"),
316
342
  "#{aliased_name}_#{first.plural_name}".upcase,
317
- " ",
318
- :attribute_name => HammerCLI.option_accessor_name("#{resource_name}_#{first.plural_name}"),
319
- :format => HammerCLI::Options::Normalizers::List.new,
320
- :referenced_resource => resource.singular_name
343
+ ' ',
344
+ attribute_name: HammerCLI.option_accessor_name("#{resource_name}_#{first.plural_name}")
321
345
  )
322
346
 
323
347
  # Other options are named by the resource plus the searchable name
324
348
  # Eg. --organization-labels with accessor option_organization_labels
325
349
  remaining.each do |s|
326
- options << option(
350
+ options << family.send(s.parent? ? :parent : :child,
327
351
  optionamize("--#{aliased_name}-#{s.plural_name}"),
328
352
  "#{aliased_name}_#{s.plural_name}".upcase,
329
- " ",
330
- :attribute_name => HammerCLI.option_accessor_name("#{resource_name}_#{s.plural_name}"),
331
- :format => HammerCLI::Options::Normalizers::List.new,
332
- :referenced_resource => resource.singular_name
353
+ ' ',
354
+ attribute_name: HammerCLI.option_accessor_name("#{resource_name}_#{s.plural_name}")
333
355
  )
334
356
  end
335
357
  end
@@ -5,3 +5,4 @@ require 'hammer_cli_foreman/option_sources/user_params'
5
5
  require 'hammer_cli_foreman/option_sources/fields_params'
6
6
  require 'hammer_cli_foreman/option_sources/puppet_environment_params'
7
7
  require 'hammer_cli_foreman/option_sources/new_params'
8
+ require 'hammer_cli_foreman/option_sources/referenced_resource_id_params'
@@ -0,0 +1,47 @@
1
+ module HammerCLIForeman
2
+ module OptionSources
3
+ class ReferencedResourceIdParams < HammerCLIForeman::OptionSources::IdParams
4
+ def param_updatable?(resource, api_param)
5
+ resource && @command.respond_to?(HammerCLI.option_accessor_name(api_param.name))
6
+ end
7
+
8
+ def get_options(defined_options, result)
9
+ return result if @command.action.nil?
10
+
11
+ available_id_params.each do |api_param|
12
+ attr_name = HammerCLI.option_accessor_name(api_param.name.gsub('_id', '_name'))
13
+ option = @command.class.find_options(attribute_name: attr_name).first
14
+ next unless option
15
+
16
+ resource = HammerCLIForeman.foreman_resource(option.referenced_resource, singular: true)
17
+ if result[HammerCLI.option_accessor_name(api_param.name)].nil? && param_updatable?(resource, api_param)
18
+ scope = { HammerCLI.option_accessor_name("#{resource.singular_name}_name") => result[attr_name] }
19
+ resource_id = @command.get_resource_id(
20
+ resource, scoped: true, required: api_param.required?,
21
+ all_options: result.merge(scope))
22
+ result[HammerCLI.option_accessor_name(api_param.name)] = resource_id if resource_id
23
+ end
24
+ end
25
+ result
26
+ rescue HammerCLIForeman::MissingSearchOptions => e
27
+ switches = @command.class.find_options(:referenced_resource => e.resource.singular_name).map(&:long_switch)
28
+
29
+ if switches.empty?
30
+ error_message = _("Could not find %{resource}. Some search options were missing, please see --help.")
31
+ elsif switches.length == 1
32
+ error_message = _("Could not find %{resource}, please set option %{switches}.")
33
+ else
34
+ error_message = _("Could not find %{resource}, please set one of options %{switches}.")
35
+ end
36
+
37
+ raise MissingSearchOptions.new(
38
+ error_message % {
39
+ :resource => e.resource.singular_name,
40
+ :switches => switches.join(", ")
41
+ },
42
+ e.resource
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
@@ -55,7 +55,7 @@ module HammerCLIForeman
55
55
  end
56
56
 
57
57
  class Session
58
- attr_accessor :id, :user_name, :auth_type
58
+ attr_accessor :id, :user_name
59
59
 
60
60
  def initialize(session_path)
61
61
  @session_path = File.expand_path(session_path)
@@ -63,7 +63,6 @@ module HammerCLIForeman
63
63
  session_data = JSON.parse(File.read(@session_path))
64
64
  @id = session_data['id']
65
65
  @user_name = session_data['user_name']
66
- @auth_type = session_data['auth_type']
67
66
  end
68
67
  rescue JSON::ParserError
69
68
  warn _('Invalid session data. Resetting the session.')
@@ -73,7 +72,6 @@ module HammerCLIForeman
73
72
  File.open(@session_path,"w") do |f|
74
73
  f.write({
75
74
  id: id,
76
- auth_type: auth_type,
77
75
  user_name: user_name
78
76
  }.to_json)
79
77
  end
@@ -1,25 +1,28 @@
1
1
  module HammerCLIForeman
2
2
 
3
- module SubnetUpdateCreateCommons
4
-
5
- def self.included(base)
6
- base.option "--dns", "DNS_NAME", _("DNS Proxy to use within this subnet")
7
- base.option "--dhcp", "DHCP_NAME", _("DHCP Proxy to use within this subnet")
8
- base.option "--tftp", "TFTP_NAME", _("TFTP Proxy to use within this subnet")
9
- end
10
-
3
+ module SubnetUpdateCreateCommons
11
4
  def request_params
12
5
  params = super
13
- params['subnet']["dns_id"] ||= proxy_feature_id(option_dns) if option_dns
14
- params['subnet']["dhcp_id"] ||= proxy_feature_id(option_dhcp) if option_dhcp
15
- params['subnet']["tftp_id"] ||= proxy_feature_id(option_tftp) if option_tftp
6
+ if option_prefix || option_mask
7
+ if params['subnet']['network_type'] == 'IPv6'
8
+ params['subnet']['cidr'] = (option_prefix || network_prefix).to_s
9
+ else
10
+ params['subnet']['mask'] = option_mask || network_mask
11
+ end
12
+ end
16
13
  params
17
14
  end
18
15
 
19
16
  private
20
17
 
21
- def proxy_feature_id(name)
22
- resolver.smart_proxy_id('option_name' => name) if name
18
+ def network_mask
19
+ require 'ipaddr'
20
+ IPAddr.new('255.255.255.255').mask(option_prefix).to_s
21
+ end
22
+
23
+ def network_prefix
24
+ require 'ipaddr'
25
+ IPAddr.new(option_mask).to_i.to_s(2).count('1')
23
26
  end
24
27
  end
25
28
 
@@ -84,7 +87,13 @@ module HammerCLIForeman
84
87
  success_message _("Subnet created.")
85
88
  failure_message _("Could not create the subnet")
86
89
 
87
- build_options :without => [:subnet_parameters_attributes]
90
+ validate_options do
91
+ any(:option_mask, :option_prefix).required
92
+ end
93
+
94
+ build_options :without => [:subnet_parameters_attributes, :cidr]
95
+
96
+ extend_with(HammerCLIForeman::CommandExtensions::Subnet.new)
88
97
  end
89
98
 
90
99
 
@@ -94,7 +103,9 @@ module HammerCLIForeman
94
103
  success_message _("Subnet updated.")
95
104
  failure_message _("Could not update the subnet")
96
105
 
97
- build_options :without => [:subnet_parameters_attributes]
106
+ build_options :without => [:subnet_parameters_attributes, :cidr]
107
+
108
+ extend_with(HammerCLIForeman::CommandExtensions::Subnet.new)
98
109
  end
99
110
 
100
111
 
@@ -0,0 +1,180 @@
1
+ require 'fileutils'
2
+
3
+ module HammerCLIForeman
4
+ module TaskHelper
5
+ class PluginDraft
6
+ attr_reader :name, :path
7
+
8
+ def initialize(name, path, options = {})
9
+ @plain_name = name
10
+ @name = "hammer_cli_foreman_#{name}"
11
+ @path = File.expand_path(@name.tr('_', '-'), path)
12
+ @capitalized_bits = name.split('_').map(&:capitalize)
13
+ @plugin_namespace = "HammerCLIForeman#{@capitalized_bits.join}"
14
+ @core_location = File.expand_path('../../', File.dirname(__FILE__))
15
+ @options = options
16
+ end
17
+
18
+ def build
19
+ FileUtils.mkpath("#{@path}/lib/#{@name}")
20
+ FileUtils.mkpath("#{@path}/config")
21
+ FileUtils.mkpath("#{@path}/test")
22
+ FileUtils.mkpath("#{@path}/locale")
23
+ end
24
+
25
+ def fill(&block)
26
+ FileUtils.cd(@path) do
27
+ self.instance_exec(&block)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def cp_license
34
+ FileUtils.cp(File.expand_path('LICENSE', @core_location), FileUtils.pwd)
35
+ end
36
+
37
+ def mk_config
38
+ File.open("config/foreman_#{@plain_name}.yml", 'w') do |config|
39
+ config.write <<-EOF
40
+ :foreman_#{@plain_name}:
41
+ :enable_module: true
42
+ EOF
43
+ end
44
+ end
45
+
46
+ def mk_readme
47
+ File.open('README.md', 'w') do |readme|
48
+ readme.write <<-EOF
49
+ # TODO
50
+ EOF
51
+ end
52
+ end
53
+
54
+ def mk_gemfile
55
+ File.open('Gemfile', 'w') do |gemfile|
56
+ gemfile.write <<-EOF
57
+ source "https://rubygems.org"
58
+
59
+ gemspec
60
+ EOF
61
+ end
62
+ end
63
+
64
+ def mk_gemspec
65
+ File.open("#{@name}.gemspec", 'w') do |gemspec|
66
+ gemspec.write <<-EOF
67
+ lib = File.expand_path('../lib', __FILE__)
68
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
69
+ require '#{@name}/version'
70
+
71
+ Gem::Specification.new do |spec|
72
+ spec.name = '#{@name}'
73
+ spec.version = #{@plugin_namespace}.version.dup
74
+ spec.authors = ['#{@options[:author]}']
75
+ spec.email = ['#{@options[:email]}']
76
+ spec.homepage = 'https://github.com/theforeman/#{@name.tr('_', '-')}'
77
+ spec.license = 'GPL-3.0'
78
+
79
+ spec.platform = Gem::Platform::RUBY
80
+ spec.summary = 'Foreman #{@capitalized_bits.join(' ')} plugin for Hammer CLI'
81
+
82
+ # TODO: Don't forget to update required files accordingly!
83
+ spec.files = Dir['{lib,config}/**/*', 'LICENSE', 'README*']
84
+ spec.require_paths = ['lib']
85
+ spec.test_files = Dir['{test}/**/*']
86
+
87
+ spec.add_dependency 'hammer_cli_foreman', '>= 2.0.0', '< 3.0.0'
88
+ end
89
+ EOF
90
+ end
91
+ end
92
+
93
+ def mk_version
94
+ File.open("lib/#{@name}/version.rb", 'w') do |version|
95
+ version.write <<-EOF
96
+ module #{@plugin_namespace}
97
+ def self.version
98
+ @version ||= Gem::Version.new '0.0.1'
99
+ end
100
+ end
101
+ EOF
102
+ end
103
+ end
104
+
105
+ def mk_root
106
+ File.open("lib/#{@name}.rb", 'w') do |plugin|
107
+ plugin.write <<-EOF
108
+ module #{@plugin_namespace}
109
+ require 'hammer_cli'
110
+ require 'hammer_cli_foreman'
111
+
112
+ require '#{@name}/version'
113
+ require '#{@name}/resource'
114
+
115
+ HammerCLI::MainCommand.lazy_subcommand(
116
+ 'resource',
117
+ 'Manage resources',
118
+ '#{@plugin_namespace}::ResourceCommand',
119
+ '#{@name}/resource'
120
+ )
121
+ end
122
+ EOF
123
+ end
124
+ end
125
+
126
+ def mk_boilerplate
127
+ File.open("lib/#{@name}/resource.rb", 'w') do |resource_command|
128
+ resource_command.write <<-EOF
129
+ module #{@plugin_namespace}
130
+ class ResourceCommand < HammerCLIForeman::Command
131
+ resource :resources
132
+
133
+ class ListCommand < HammerCLIForeman::ListCommand
134
+ output do
135
+ field :id, _('Id')
136
+ field :name, _('Name')
137
+ end
138
+
139
+ build_options
140
+ end
141
+
142
+ class InfoCommand < HammerCLIForeman::InfoCommand
143
+ output ResourceCommand::ListCommand.output_definition do
144
+ field :head_type, _('Head type')
145
+ end
146
+
147
+ build_options
148
+ end
149
+
150
+ class CreateCommand < HammerCLIForeman::CreateCommand
151
+ success_message _('Resource created.')
152
+ failure_message _('Could not create the resource')
153
+
154
+ build_options
155
+ end
156
+
157
+ class UpdateCommand < HammerCLIForeman::UpdateCommand
158
+ success_message _('Resource updated.')
159
+ failure_message _('Could not update the resource')
160
+
161
+ build_options without: [:sprig]
162
+ option '--head', 'HEAD', _('Head type'), attribute_name: :option_head
163
+ end
164
+
165
+ class DeleteCommand < HammerCLIForeman::DeleteCommand
166
+ success_message _('Resource deleted.')
167
+ failure_message _('Could not delete the resource')
168
+
169
+ build_options
170
+ end
171
+
172
+ autoload_subcommands
173
+ end
174
+ end
175
+ EOF
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end