hammer_cli_foreman 2.0.2 → 2.1.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 (57) 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 +20 -4
  5. data/lib/hammer_cli_foreman.rb +8 -0
  6. data/lib/hammer_cli_foreman/api/oauth/authentication_code_grant.rb +7 -4
  7. data/lib/hammer_cli_foreman/associating_commands.rb +33 -5
  8. data/lib/hammer_cli_foreman/auth.rb +6 -6
  9. data/lib/hammer_cli_foreman/bookmark.rb +50 -0
  10. data/lib/hammer_cli_foreman/command_extensions.rb +2 -0
  11. data/lib/hammer_cli_foreman/command_extensions/puppet_environment.rb +13 -7
  12. data/lib/hammer_cli_foreman/command_extensions/puppet_environments.rb +13 -7
  13. data/lib/hammer_cli_foreman/command_extensions/subnet.rb +25 -0
  14. data/lib/hammer_cli_foreman/command_extensions/user.rb +17 -0
  15. data/lib/hammer_cli_foreman/commands.rb +14 -9
  16. data/lib/hammer_cli_foreman/compute_resource.rb +15 -0
  17. data/lib/hammer_cli_foreman/compute_resource/ec2.rb +11 -0
  18. data/lib/hammer_cli_foreman/compute_resource/gce.rb +9 -0
  19. data/lib/hammer_cli_foreman/compute_resource/libvirt.rb +11 -0
  20. data/lib/hammer_cli_foreman/compute_resource/openstack.rb +7 -0
  21. data/lib/hammer_cli_foreman/compute_resource/ovirt.rb +21 -9
  22. data/lib/hammer_cli_foreman/compute_resource/vmware.rb +15 -2
  23. data/lib/hammer_cli_foreman/hostgroup.rb +11 -19
  24. data/lib/hammer_cli_foreman/hosts/common_update_options.rb +32 -10
  25. data/lib/hammer_cli_foreman/id_resolver.rb +12 -11
  26. data/lib/hammer_cli_foreman/mail_notification.rb +31 -0
  27. data/lib/hammer_cli_foreman/option_builders.rb +70 -48
  28. data/lib/hammer_cli_foreman/option_sources.rb +1 -0
  29. data/lib/hammer_cli_foreman/option_sources/referenced_resource_id_params.rb +47 -0
  30. data/lib/hammer_cli_foreman/subnet.rb +26 -15
  31. data/lib/hammer_cli_foreman/task_helper.rb +180 -0
  32. data/lib/hammer_cli_foreman/user.rb +3 -17
  33. data/lib/hammer_cli_foreman/version.rb +1 -1
  34. data/lib/hammer_cli_foreman/virtual_machine.rb +55 -0
  35. data/locale/ca/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  36. data/locale/de/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  37. data/locale/en/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  38. data/locale/en_GB/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  39. data/locale/es/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  40. data/locale/fr/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  41. data/locale/it/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  42. data/locale/ja/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  43. data/locale/ko/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  44. data/locale/pt_BR/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  45. data/locale/ru/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  46. data/locale/zh_CN/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  47. data/locale/zh_TW/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  48. data/test/data/2.1/foreman_api.json +1 -0
  49. data/test/functional/associating_commands_test.rb +134 -30
  50. data/test/functional/bookmark_test.rb +193 -0
  51. data/test/functional/host_test.rb +27 -1
  52. data/test/functional/mail_notification_test.rb +57 -0
  53. data/test/functional/subnet/create_test.rb +28 -5
  54. data/test/functional/template_test.rb +2 -2
  55. data/test/functional/virtual_machine_test.rb +129 -0
  56. data/test/test_helper.rb +1 -1
  57. metadata +23 -6
@@ -1,4 +1,5 @@
1
1
  require 'hammer_cli_foreman/image'
2
+ require 'hammer_cli_foreman/virtual_machine'
2
3
  require 'hammer_cli_foreman/compute_resource/register_compute_resources'
3
4
 
4
5
  module HammerCLIForeman
@@ -223,7 +224,21 @@ module HammerCLIForeman
223
224
  build_options
224
225
  end
225
226
 
227
+ class AvailableVirtualMachinesCommand < HammerCLIForeman::ListCommand
228
+ action :available_virtual_machines
229
+ command_name 'virtual-machines'
230
+
231
+ output do
232
+ field :id, _("Id")
233
+ field :name, _("Name")
234
+ end
235
+
236
+ build_options
237
+ end
238
+
226
239
  autoload_subcommands
240
+ subcommand 'virtual-machine', HammerCLIForeman::VirtualMachine.desc,
241
+ HammerCLIForeman::VirtualMachine
227
242
  subcommand 'image', HammerCLIForeman::Image.desc, HammerCLIForeman::Image
228
243
  end
229
244
 
@@ -15,6 +15,17 @@ module HammerCLIForeman
15
15
  ]
16
16
  end
17
17
 
18
+ def provider_vm_specific_fields
19
+ [
20
+ Fields::Field.new(:label => _('DNS'), :path => [:dns_name]),
21
+ Fields::Field.new(:label => _('Type'), :path => [:flavor_id]),
22
+ Fields::Field.new(:label => _('State'), :path => [:state]),
23
+ Fields::Field.new(:label => _('Owner Id'), :path => [:ownerId]),
24
+ Fields::Field.new(:label => _('DNS Name'), :path => [:dns_name]),
25
+ Fields::Field.new(:label => _('Virtualization Type'), :path => [:virtualization_type])
26
+ ]
27
+ end
28
+
18
29
  def mandatory_resource_options
19
30
  super + %i[region user password]
20
31
  end
@@ -28,6 +28,15 @@ module HammerCLIForeman
28
28
  ]
29
29
  end
30
30
 
31
+ def provider_vm_specific_fields
32
+ [
33
+ Fields::Field.new(:label => _('Machine Type'), :path => [:machine_type]),
34
+ Fields::Field.new(:label => _('Status'), :path => [:status]),
35
+ Fields::Field.new(:label => _('Description'), :path => [:description]),
36
+ Fields::Field.new(:label => _('Zone'), :path => [:zone])
37
+ ]
38
+ end
39
+
31
40
  def mandatory_resource_options
32
41
  super + %I{project key_path zone}
33
42
  end
@@ -41,6 +41,17 @@ module HammerCLIForeman
41
41
  'nics_attributes'
42
42
  end
43
43
 
44
+ def provider_vm_specific_fields
45
+ [
46
+ Fields::Field.new(:label => _('CPUs'), :path => [:cpus]),
47
+ Fields::Field.new(:label => _('Memory'), :path => [:memory_size]),
48
+ Fields::Field.new(:label => _('Status'), :path => [:state]),
49
+ Fields::Field.new(:label => _('OS Type'), :path => [:os_type]),
50
+ Fields::Field.new(:label => _('Domain Type'), :path => [:domain_type]),
51
+ Fields::Field.new(:label => _('Persistent'), :path => [:persistent])
52
+ ]
53
+ end
54
+
44
55
  def mandatory_resource_options
45
56
  super + %i[url]
46
57
  end
@@ -20,6 +20,13 @@ module HammerCLIForeman
20
20
  def mandatory_resource_options
21
21
  super + %i[url user password]
22
22
  end
23
+
24
+ def provider_vm_specific_fields
25
+ [
26
+ Fields::Field.new(:label => _('State'), :path => [:state]),
27
+ Fields::Field.new(:label => _('Tenant Id'), :path => [:tenant_id])
28
+ ]
29
+ end
23
30
  end
24
31
 
25
32
  HammerCLIForeman.register_compute_resource('openstack', OpenStack.new)
@@ -7,17 +7,19 @@ module HammerCLIForeman
7
7
 
8
8
  def compute_attributes
9
9
  [
10
- ['cluster', _('ID or name of cluster to use')],
11
- ['template', _('Hardware profile to use')],
12
- ['cores', _('Integer value, number of cores')],
13
- ['sockets', _('Integer value, number of sockets')],
14
- ['memory', _('Amount of memory, integer value in bytes')]
10
+ ['cluster', _('ID or name of cluster to use')],
11
+ ['template', _('Hardware profile to use')],
12
+ ['cores', _('Integer value, number of cores')],
13
+ ['sockets', _('Integer value, number of sockets')],
14
+ ['memory', _('Amount of memory, integer value in bytes')],
15
+ ['display_type', _('Possible values: %s') % 'VNC, SPICE'],
16
+ ['keyboard_layout', _('Possible values: %s. Not usable if display type is SPICE.') % 'ar, de-ch, es, fo, fr-ca, hu, ja, mk, no, pt-br, sv, da, en-gb, et, fr, fr-ch, is, lt, nl, pl, ru, th, de, en-us, fi, fr-be, hr, it, lv, nl-be, pt, sl, tr']
15
17
  ]
16
18
  end
17
19
 
18
20
  def host_attributes
19
21
  [
20
- ['start', _('Boolean (expressed as 0 or 1), whether to start the machine or not')]
22
+ ['start', _('Boolean, set 1 to start the vm')]
21
23
  ]
22
24
  end
23
25
 
@@ -33,9 +35,9 @@ module HammerCLIForeman
33
35
  [
34
36
  ['size_gb', _('Volume size in GB, integer value')],
35
37
  ['storage_domain', _('ID or name of storage domain')],
36
- ['bootable', _('Boolean, only one volume can be bootable')],
37
- ['preallocate', _('Boolean, set %s to preallocate') % 'true'],
38
- ['wipe_after_delete', _('Boolean, set %s to wipe disk after delete') % 'true'],
38
+ ['bootable', _('Boolean, set 1 for bootable, only one volume can be bootable')],
39
+ ['preallocate', _('Boolean, set 1 to preallocate')],
40
+ ['wipe_after_delete', _('Boolean, set 1 to wipe disk after delete')],
39
41
  ['interface', _('Disk interface name, must be ide, virto or virto_scsi')]
40
42
  ]
41
43
  end
@@ -46,6 +48,16 @@ module HammerCLIForeman
46
48
  ]
47
49
  end
48
50
 
51
+ def provider_vm_specific_fields
52
+ [
53
+ Fields::Field.new(:label => _('CPUs'), :path => [:cpu]),
54
+ Fields::Field.new(:label => _('Memory'), :path => [:memory]),
55
+ Fields::Field.new(:label => _('Status'), :path => [:status]),
56
+ Fields::Field.new(:label => _('Cores'), :path => [:cores]),
57
+ Fields::Field.new(:label => _('Type'), :path => [:type])
58
+ ]
59
+ end
60
+
49
61
  def mandatory_resource_options
50
62
  super + %i[url user password datacenter]
51
63
  end
@@ -18,8 +18,8 @@ module HammerCLIForeman
18
18
  ['firmware', 'automatic/bios/efi'],
19
19
  ['guest_id', _('Guest OS ID form VMware')],
20
20
  ['hardware_version', _('Hardware version ID from VMware')],
21
- ['memoryHotAddEnabled', _('Must be a 1 or 0, lets you add CPU resources while the machine is on')],
22
- ['cpuHotAddEnabled', _('Must be a 1 or 0, lets you add memory resources while the machine is on')],
21
+ ['memoryHotAddEnabled', _('Must be a 1 or 0, lets you add memory resources while the machine is on')],
22
+ ['cpuHotAddEnabled', _('Must be a 1 or 0, lets you add CPU resources while the machine is on')],
23
23
  ['add_cdrom', _('Must be a 1 or 0, Add a CD-ROM drive to the virtual machine')],
24
24
  ['annotation', _('Annotation Notes')],
25
25
  ['scsi_controllers', [_('List with SCSI controllers definitions'),
@@ -67,6 +67,19 @@ module HammerCLIForeman
67
67
  ]
68
68
  end
69
69
 
70
+ def provider_vm_specific_fields
71
+ [
72
+ Fields::Field.new(:label => _('CPUs'), :path => [:cpus]),
73
+ Fields::Field.new(:label => _('Memory'), :path => [:memory_mb]),
74
+ Fields::Field.new(:label => _('Power Status'), :path => [:power_state]),
75
+ Fields::Field.new(:label => _('Host Name'), :path => [:hostname]),
76
+ Fields::Field.new(:label => _('Connection Status'), :path => [:connection_status]),
77
+ Fields::Field.new(:label => _('Hardware Version'), :path => [:hardware_version]),
78
+ Fields::Field.new(:label => _('Path'), :path => [:path]),
79
+ Fields::Field.new(:label => _('Operating System'), :path => [:operatingsystem])
80
+ ]
81
+ end
82
+
70
83
  def mandatory_resource_options
71
84
  super + %i[user password datacenter server]
72
85
  end
@@ -15,10 +15,14 @@ module HammerCLIForeman
15
15
  base.option "--puppet-ca-proxy", "PUPPET_CA_PROXY_NAME", _("Name of puppet CA proxy")
16
16
  base.option "--puppet-proxy", "PUPPET_PROXY_NAME", _("Name of puppet proxy")
17
17
  base.option "--parent", "PARENT_NAME", _("Name of parent hostgroup")
18
- base.option "--root-pass", "ROOT_PASSWORD", _("Root password")
19
- base.option "--ask-root-pass", "ASK_ROOT_PW", "",
20
- :format => HammerCLI::Options::Normalizers::Bool.new
18
+ base.option ["--root-password", "--root-pass"], "ROOT_PASSWORD", _("Root password"),
19
+ deprecated: { '--root-pass' => _("Use --root-password instead") }
20
+ base.option ["--ask-root-password", "--ask-root-pass"], "ASK_ROOT_PW", "",
21
+ format: HammerCLI::Options::Normalizers::Bool.new,
22
+ deprecated: { '--ask-root-pass' => _("Use --ask-root-password instead") }
21
23
  base.option "--subnet6", "SUBNET6_NAME", _("Subnet IPv6 name")
24
+
25
+ base.build_options without: %i[root_pass]
22
26
  end
23
27
 
24
28
  def self.ask_password
@@ -32,12 +36,8 @@ module HammerCLIForeman
32
36
  params['hostgroup']["puppet_proxy_id"] ||= proxy_id(option_puppet_proxy) if option_puppet_proxy
33
37
  params['hostgroup']["puppet_ca_proxy_id"] ||= proxy_id(option_puppet_ca_proxy) if option_puppet_ca_proxy
34
38
 
35
- # Remove after API docs are fixed: https://projects.theforeman.org/issues/28923
36
- puppetclass_ids = option_puppetclass_ids || puppet_class_ids(option_puppetclass_names)
37
- params['hostgroup']['puppetclass_ids'] = puppetclass_ids unless puppetclass_ids.nil?
38
-
39
- params['hostgroup']['root_pass'] = option_root_pass if option_root_pass
40
- params['hostgroup']['root_pass'] = HammerCLIForeman::HostgroupUpdateCreateCommons::ask_password if option_ask_root_pass
39
+ params['hostgroup']['root_pass'] = option_root_password if option_root_password
40
+ params['hostgroup']['root_pass'] = HammerCLIForeman::HostgroupUpdateCreateCommons::ask_password if option_ask_root_password
41
41
 
42
42
  params['hostgroup']['subnet6_id'] = resolver.subnet_id('option_name' => option_subnet6) if option_subnet6
43
43
  params
@@ -48,11 +48,6 @@ module HammerCLIForeman
48
48
  def proxy_id(name)
49
49
  resolver.smart_proxy_id('option_name' => name) if name
50
50
  end
51
-
52
- def puppet_class_ids(names)
53
- resolver.puppetclass_ids('option_names' => names) if names
54
- end
55
-
56
51
  end
57
52
 
58
53
  class Hostgroup < HammerCLIForeman::Command
@@ -87,7 +82,8 @@ module HammerCLIForeman
87
82
  field nil, _("Parent"), Fields::SingleReference, :key => :parent, :hide_blank => true
88
83
  field nil, _("Puppet CA Proxy"), Fields::SingleReference, :key => :puppet_ca_proxy
89
84
  field nil, _("Puppet Master Proxy"), Fields::SingleReference, :key => :puppet_proxy
90
- field nil, _("ComputeProfile"), Fields::SingleReference, :key => :compute_profile
85
+ field nil, _("Compute Profile"), Fields::SingleReference, :key => :compute_profile
86
+ field nil, _("Compute Resource"), Fields::SingleReference, :key => :compute_resource
91
87
  label _('Network') do
92
88
  field nil, _("Subnet ipv4"), Fields::SingleReference, :key => :subnet
93
89
  field nil, _("Subnet ipv6"), Fields::SingleReference, :key => :subnet6
@@ -116,8 +112,6 @@ module HammerCLIForeman
116
112
  success_message _("Hostgroup created.")
117
113
  failure_message _("Could not create the hostgroup")
118
114
 
119
- build_options
120
-
121
115
  extend_with(HammerCLIForeman::CommandExtensions::PuppetEnvironment.new)
122
116
  end
123
117
 
@@ -128,8 +122,6 @@ module HammerCLIForeman
128
122
  success_message _("Hostgroup updated.")
129
123
  failure_message _("Could not update the hostgroup")
130
124
 
131
- build_options
132
-
133
125
  extend_with(HammerCLIForeman::CommandExtensions::PuppetEnvironment.new)
134
126
  end
135
127
 
@@ -14,15 +14,22 @@ module HammerCLIForeman
14
14
  base.option "--ask-root-password", "ASK_ROOT_PW", " ",
15
15
  :format => HammerCLI::Options::Normalizers::Bool.new
16
16
 
17
- base.option "--puppet-proxy", "PUPPET_PROXY_NAME", ""
18
- base.option "--puppet-ca-proxy", "PUPPET_CA_PROXY_NAME", ""
19
- base.option "--puppet-class-ids", "PUPPET_CLASS_IDS", "",
20
- :format => HammerCLI::Options::Normalizers::List.new,
21
- :attribute_name => :option_puppetclass_ids
22
- base.option "--puppet-classes", "PUPPET_CLASS_NAMES", "",
23
- :format => HammerCLI::Options::Normalizers::List.new,
24
- :attribute_name => :option_puppetclass_names
25
-
17
+ base.option '--puppet-proxy', 'PUPPET_PROXY_NAME', '',
18
+ referenced_resource: 'puppet_proxy',
19
+ aliased_resource: 'puppet_proxy'
20
+ base.option '--puppet-ca-proxy', 'PUPPET_CA_PROXY_NAME', '',
21
+ referenced_resource: 'puppet_ca_proxy',
22
+ aliased_resource: 'puppet_ca_proxy'
23
+ base.option_family(
24
+ format: HammerCLI::Options::Normalizers::List.new,
25
+ aliased_resource: 'puppet-class',
26
+ description: 'Names/Ids of associated puppet classes'
27
+ ) do
28
+ parent '--puppet-class-ids', 'PUPPET_CLASS_IDS', '',
29
+ attribute_name: :option_puppetclass_ids
30
+ child '--puppet-classes', 'PUPPET_CLASS_NAMES', '',
31
+ attribute_name: :option_puppetclass_names
32
+ end
26
33
  bme_options = {}
27
34
  bme_options[:default] = 'true' if base.action.to_sym == :create
28
35
 
@@ -59,7 +66,7 @@ module HammerCLIForeman
59
66
 
60
67
  def request_params
61
68
  params = super
62
- owner_id = get_resource_id(HammerCLIForeman.foreman_resource(:users), :required => false, :scoped => true)
69
+ owner_id = owner_id(option_user_login, params['host']['owner_type'])
63
70
  params['host']['owner_id'] ||= owner_id unless owner_id.nil?
64
71
 
65
72
  puppet_proxy_id = proxy_id(option_puppet_proxy)
@@ -79,6 +86,14 @@ module HammerCLIForeman
79
86
  params['host']['host_parameters_attributes'] ||= option_typed_parameters unless option_typed_parameters.nil?
80
87
  params['host']['compute_attributes'] = option_compute_attributes || {}
81
88
 
89
+ compute_attributes = params['host']['compute_attributes']
90
+ compute_attributes['display'] = {} unless compute_attributes['display_type'].nil? && compute_attributes['keyboard_layout'].nil?
91
+ compute_attributes['display']['type'] = compute_attributes['display_type'] unless compute_attributes['display_type'].nil?
92
+ compute_attributes['display']['keyboard_layout'] = compute_attributes['keyboard_layout'] unless compute_attributes['keyboard_layout'].nil?
93
+ compute_attributes.delete('display_type')
94
+ compute_attributes.delete('keyboard_layout')
95
+ params['host']['compute_attributes'] = compute_attributes
96
+
82
97
  if action == :update
83
98
  params['host']['compute_attributes']['volumes_attributes'] = nested_attributes(option_volume_list) unless option_volume_list.empty?
84
99
  params['host']['interfaces_attributes'] = interfaces_attributes unless option_interface_list.empty?
@@ -119,6 +134,13 @@ module HammerCLIForeman
119
134
 
120
135
  private
121
136
 
137
+ def owner_id(name, type = 'User')
138
+ return unless name
139
+ return resolver.user_id('option_login' => name) if type == 'User'
140
+
141
+ resolver.usergroup_id('option_name' => name)
142
+ end
143
+
122
144
  def proxy_id(name)
123
145
  resolver.smart_proxy_id('option_name' => name) if name
124
146
  end
@@ -1,16 +1,16 @@
1
1
  module HammerCLIForeman
2
2
 
3
3
  class Searchable
4
+ attr_reader :name, :description, :format
4
5
 
5
6
  def initialize(name, description, options={})
6
7
  @name = name
7
8
  @description = description
8
9
  @editable = options[:editable].nil? ? true : options[:editable]
9
10
  @format = options[:format]
11
+ @parent = options[:parent]
10
12
  end
11
13
 
12
- attr_reader :name, :description
13
-
14
14
  def plural_name
15
15
  ApipieBindings::Inflector.pluralize(@name)
16
16
  end
@@ -19,10 +19,9 @@ module HammerCLIForeman
19
19
  @editable
20
20
  end
21
21
 
22
- def format
23
- @format
22
+ def parent?
23
+ @parent
24
24
  end
25
-
26
25
  end
27
26
 
28
27
  class Searchables
@@ -51,15 +50,17 @@ module HammerCLIForeman
51
50
  :hostgroup => [ s_name(_("Hostgroup name")), s("title", _("Hostgroup title"), :editable => false) ],
52
51
  # :image => [],
53
52
  :interface => [],
54
- :location => [ s("name", _("Location Name, Set the current location context for the request")),
55
- s("title", _("Location title, Set the current location context for the request" ),:editable => false),
56
- s("id", _("Set the current location context for the request"), :editable => false, :format => HammerCLI::Options::Normalizers::Number.new),
53
+ :location => [ s('name', _('Location Name, Set the current location context for the request')),
54
+ s('title', _('Location title, Set the current location context for the request' ),
55
+ editable: false
56
+ )
57
57
  ],
58
58
  :medium => [ s_name(_("Medium name")) ],
59
59
  :model => [ s_name(_("Model name")) ],
60
- :organization => [ s("name", _("Set the current organization context for the request")),
61
- s("title", _("Set the current organization context for the request"),:editable => false),
62
- s("id", _("Set the current organization context for the request"), :editable => false, :format => HammerCLI::Options::Normalizers::Number.new),
60
+ :organization => [ s('name', _('Set the current organization context for the request')),
61
+ s('title', _('Set the current organization context for the request'),
62
+ editable: false
63
+ )
63
64
  ],
64
65
  :operatingsystem => [ s("title", _("Operating system title"), :editable => false) ],
65
66
  :override_value => [],
@@ -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
+
@@ -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: _('%{types} of associated %{resource}') % { 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