hammer_cli_foreman 0.1.0 → 0.1.1

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.

Potentially problematic release.


This version of hammer_cli_foreman might be problematic. Click here for more details.

Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -1
  3. data/doc/configuration.md +13 -0
  4. data/lib/hammer_cli_foreman.rb +3 -0
  5. data/lib/hammer_cli_foreman/architecture.rb +9 -9
  6. data/lib/hammer_cli_foreman/associating_commands.rb +57 -34
  7. data/lib/hammer_cli_foreman/commands.rb +188 -101
  8. data/lib/hammer_cli_foreman/common_parameter.rb +7 -10
  9. data/lib/hammer_cli_foreman/compute_resource.rb +8 -11
  10. data/lib/hammer_cli_foreman/domain.rb +14 -40
  11. data/lib/hammer_cli_foreman/environment.rb +10 -15
  12. data/lib/hammer_cli_foreman/exceptions.rb +4 -0
  13. data/lib/hammer_cli_foreman/fact.rb +5 -5
  14. data/lib/hammer_cli_foreman/host.rb +76 -132
  15. data/lib/hammer_cli_foreman/hostgroup.rb +26 -61
  16. data/lib/hammer_cli_foreman/id_resolver.rb +163 -0
  17. data/lib/hammer_cli_foreman/image.rb +14 -50
  18. data/lib/hammer_cli_foreman/location.rb +35 -17
  19. data/lib/hammer_cli_foreman/media.rb +9 -16
  20. data/lib/hammer_cli_foreman/model.rb +6 -8
  21. data/lib/hammer_cli_foreman/operating_system.rb +129 -63
  22. data/lib/hammer_cli_foreman/organization.rb +36 -16
  23. data/lib/hammer_cli_foreman/output/fields.rb +10 -2
  24. data/lib/hammer_cli_foreman/output/formatters.rb +44 -18
  25. data/lib/hammer_cli_foreman/parameter.rb +45 -41
  26. data/lib/hammer_cli_foreman/partition_table.rb +9 -12
  27. data/lib/hammer_cli_foreman/puppet_class.rb +14 -14
  28. data/lib/hammer_cli_foreman/references.rb +122 -0
  29. data/lib/hammer_cli_foreman/report.rb +3 -6
  30. data/lib/hammer_cli_foreman/searchables_option_builder.rb +99 -0
  31. data/lib/hammer_cli_foreman/smart_class_parameter.rb +17 -13
  32. data/lib/hammer_cli_foreman/smart_proxy.rb +18 -28
  33. data/lib/hammer_cli_foreman/subnet.rb +12 -13
  34. data/lib/hammer_cli_foreman/template.rb +10 -19
  35. data/lib/hammer_cli_foreman/user.rb +9 -28
  36. data/lib/hammer_cli_foreman/version.rb +1 -1
  37. data/locale/hammer-cli-foreman.pot +828 -817
  38. data/test/unit/apipie_resource_mock.rb +33 -11
  39. data/test/unit/architecture_test.rb +7 -10
  40. data/test/unit/commands_test.rb +8 -9
  41. data/test/unit/common_parameter_test.rb +6 -8
  42. data/test/unit/compute_resource_test.rb +9 -12
  43. data/test/unit/data/1.5/foreman_api.json +14130 -0
  44. data/test/unit/domain_test.rb +19 -22
  45. data/test/unit/environment_test.rb +9 -11
  46. data/test/unit/fact_test.rb +5 -6
  47. data/test/unit/helpers/command.rb +115 -59
  48. data/test/unit/helpers/fake_searchables.rb +19 -0
  49. data/test/unit/host_test.rb +44 -33
  50. data/test/unit/hostgroup_test.rb +19 -26
  51. data/test/unit/id_resolver_test.rb +225 -0
  52. data/test/unit/image_test.rb +16 -18
  53. data/test/unit/location_test.rb +8 -10
  54. data/test/unit/media_test.rb +11 -13
  55. data/test/unit/model_test.rb +8 -10
  56. data/test/unit/operating_system_test.rb +23 -23
  57. data/test/unit/organization_test.rb +9 -10
  58. data/test/unit/output/formatters_test.rb +133 -20
  59. data/test/unit/partition_table_test.rb +12 -9
  60. data/test/unit/puppet_class_test.rb +3 -7
  61. data/test/unit/report_test.rb +3 -7
  62. data/test/unit/searchables_option_builder_test.rb +172 -0
  63. data/test/unit/smart_class_parameter_test.rb +5 -7
  64. data/test/unit/smart_proxy_test.rb +11 -12
  65. data/test/unit/subnet_test.rb +15 -16
  66. data/test/unit/template_test.rb +15 -12
  67. data/test/unit/test_helper.rb +1 -1
  68. data/test/unit/user_test.rb +9 -12
  69. metadata +536 -509
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4664c32a15e81c3db327542d918d9eaebf516e11
4
- data.tar.gz: 324c167ab2dba9419c86d16bec1b59ab313df949
3
+ metadata.gz: a6d49542beab521eda5d1780bf6effc51714df49
4
+ data.tar.gz: c8e9298892d68c30f192251b2beea23fe7ce53d6
5
5
  SHA512:
6
- metadata.gz: d5b642b1ba7581539d667ac94de9ed9cc27daaa194d4d26e5101b0983dba77ab3d184e628359d8b32c2e90b72b4c66624a322ce02dab081a01bb3fde6397e703
7
- data.tar.gz: 62f07b9d348b8ec921380b17b900a26622dff382733ce28d1d52908a684bd303f40b9617a9f46b4681286482ce5840ac5dbfca1f15b9a387e905d70de8d4c045
6
+ metadata.gz: f5335b895f5de74ccf6ad621cfea4e6e405ed8185e5f01c1c1755230332157018880b46f5d1f5ec022ba3474e4fccbf2469312b7f0c44a6db2025613412a7dcb
7
+ data.tar.gz: 01ba227af3fb1b4d11e242b373e0b6df484eeace5b37360b2a76ad487489c0178cba9fa385b8fe78f8b89d009c3921abddd51791f06969018ef16ac47da2b8cc
data/README.md CHANGED
@@ -1,12 +1,14 @@
1
1
  Foreman commands for Hammer CLI
2
2
  ===============================
3
3
 
4
- This Hammer CLI plugin contains set of commands for [Foreman](http://theforeman.org/).
4
+ This [Hammer CLI](https://github.com/theforeman/hammer-cli) plugin contains
5
+ set of commands for [Foreman](http://theforeman.org/).
5
6
 
6
7
 
7
8
  Documentation
8
9
  -------------
9
10
 
11
+ - [Configuration](doc/configuration.md#configuration)
10
12
  - [Host creation](doc/host_create.md#host-creation)
11
13
 
12
14
  How to run
@@ -16,6 +18,15 @@ The work is still in progress and there are no builds ready yet. You can install
16
18
  See [Hammer CLI readme](https://github.com/theforeman/hammer-cli/blob/master/README.md#how-to-run) for details.
17
19
 
18
20
 
21
+ Having issues?
22
+ --------------
23
+
24
+ If one of hammer commands doesn't work as you would expect, you can run `hammer -d ...` to get
25
+ full debug output from the loggers. It should give you an idea what went wrong.
26
+
27
+ If you have questions, don't hesitate to contact us on `foreman-users@googlegroups.com` or
28
+ `FreeNode#foreman` irc channel.
29
+
19
30
  How to test
20
31
  ------------
21
32
 
@@ -0,0 +1,13 @@
1
+ Configuration
2
+ =============
3
+
4
+ Configuration is expected to be placed in one of hammer's configuration directories for plugins:
5
+ - `/etc/hammer/cli.modules.d/`
6
+ - `~/.hammer/cli.modules.d/`
7
+ - `./.config/cli.modules.d/` (config dir in CWD)
8
+
9
+ If you install `hammer_cli_foreman` from source you'll have to copy the config file manually
10
+ from `config/foreman.yml`.
11
+
12
+ See our [sample config file](https://github.com/theforeman/hammer-cli-foreman/blob/master/config/foreman.yml)
13
+ that lists all available configuration options with descriptions.
@@ -14,10 +14,13 @@ module HammerCLIForeman
14
14
  require 'hammer_cli_foreman/output'
15
15
  require 'hammer_cli_foreman/credentials'
16
16
  require 'hammer_cli_foreman/exception_handler'
17
+ require 'hammer_cli_foreman/searchables_option_builder'
18
+ require 'hammer_cli_foreman/id_resolver'
17
19
 
18
20
  begin
19
21
  require 'hammer_cli_foreman/commands'
20
22
  require 'hammer_cli_foreman/associating_commands'
23
+ require 'hammer_cli_foreman/references'
21
24
  require 'hammer_cli_foreman/parameter'
22
25
  require 'hammer_cli_foreman/common_parameter'
23
26
 
@@ -11,19 +11,19 @@ module HammerCLIForeman
11
11
  field :name, _("Name")
12
12
  end
13
13
 
14
- apipie_options
14
+ build_options
15
15
  end
16
16
 
17
17
 
18
18
  class InfoCommand < HammerCLIForeman::InfoCommand
19
19
 
20
20
  output ListCommand.output_definition do
21
- field :operatingsystem_ids, _("OS ids"), Fields::List
22
- field :created_at, _("Created at"), Fields::Date
23
- field :updated_at, _("Updated at"), Fields::Date
21
+ HammerCLIForeman::References.operating_systems(self)
22
+ HammerCLIForeman::References.taxonomies(self)
23
+ HammerCLIForeman::References.timestamps(self)
24
24
  end
25
25
 
26
- apipie_options
26
+ build_options
27
27
  end
28
28
 
29
29
 
@@ -31,7 +31,7 @@ module HammerCLIForeman
31
31
  success_message _("Architecture created")
32
32
  failure_message _("Could not create the architecture")
33
33
 
34
- apipie_options
34
+ build_options
35
35
  end
36
36
 
37
37
 
@@ -39,7 +39,7 @@ module HammerCLIForeman
39
39
  success_message _("Architecture deleted")
40
40
  failure_message _("Could not delete the architecture")
41
41
 
42
- apipie_options
42
+ build_options
43
43
  end
44
44
 
45
45
 
@@ -47,10 +47,10 @@ module HammerCLIForeman
47
47
  success_message _("Architecture updated")
48
48
  failure_message _("Could not update the architecture")
49
49
 
50
- apipie_options
50
+ build_options
51
51
  end
52
52
 
53
- include HammerCLIForeman::AssociatingCommands::OperatingSystem
53
+ HammerCLIForeman::AssociatingCommands::OperatingSystem.extend_command(self)
54
54
 
55
55
  autoload_subcommands
56
56
  end
@@ -1,82 +1,114 @@
1
1
  module HammerCLIForeman
2
2
  module AssociatingCommands
3
3
 
4
+ module CommandExtension
5
+
6
+ def extend_command(base_command)
7
+ commands = self.constants.map {|c| self.const_get(c)}.select {|c| c < HammerCLI::AbstractCommand }
8
+
9
+ commands.each do |cmd|
10
+ plug_command(cmd, base_command)
11
+ end
12
+ end
13
+
14
+ def plug_command(command, base_command)
15
+ cmd_name = base_name(command)
16
+ base_name = base_name(base_command)
17
+
18
+ name = base_name + cmd_name
19
+
20
+ cmd_cls = Class.new(command)
21
+ base_command.const_set(name, cmd_cls)
22
+
23
+ cmd_cls.resource(base_command.resource.name)
24
+ #TODO: update messages to inherit from parents
25
+ cmd_cls.success_message(command.success_message)
26
+ cmd_cls.failure_message(command.failure_message)
27
+ cmd_cls.build_options
28
+ end
29
+
30
+ def base_name(cls)
31
+ cls.name.split("::")[-1]
32
+ end
33
+ end
34
+
4
35
  module Hostgroup
36
+ extend CommandExtension
37
+
5
38
  class AddHostgroupCommand < HammerCLIForeman::AddAssociatedCommand
6
39
  associated_resource :hostgroups
7
- apipie_options
8
40
  end
9
41
 
10
42
  class RemoveHostgroupCommand < HammerCLIForeman::RemoveAssociatedCommand
11
43
  associated_resource :hostgroups
12
- apipie_options
13
44
  end
14
45
  end
15
46
 
16
47
  module Environment
48
+ extend CommandExtension
49
+
17
50
  class AddEnvironmentCommand < HammerCLIForeman::AddAssociatedCommand
18
51
  associated_resource :environments
19
- apipie_options
20
52
  end
21
53
 
22
54
  class RemoveEnvironmentCommand < HammerCLIForeman::RemoveAssociatedCommand
23
55
  associated_resource :environments
24
- apipie_options
25
56
  end
26
57
  end
27
58
 
28
59
  module Domain
60
+ extend CommandExtension
61
+
29
62
  class AddDomainCommand < HammerCLIForeman::AddAssociatedCommand
30
63
  associated_resource :domains
31
- apipie_options
32
64
  end
33
65
 
34
66
  class RemoveDomainCommand < HammerCLIForeman::RemoveAssociatedCommand
35
67
  associated_resource :domains
36
- apipie_options
37
68
  end
38
69
  end
39
70
 
40
71
  module Medium
72
+ extend CommandExtension
73
+
41
74
  class AddMediumCommand < HammerCLIForeman::AddAssociatedCommand
42
75
  associated_resource :media
43
- apipie_options
44
76
  end
45
77
 
46
78
  class RemoveMediumCommand < HammerCLIForeman::RemoveAssociatedCommand
47
79
  associated_resource :media
48
- apipie_options
49
80
  end
50
81
  end
51
82
 
52
83
  module Subnet
84
+ extend CommandExtension
85
+
53
86
  class AddSubnetCommand < HammerCLIForeman::AddAssociatedCommand
54
87
  associated_resource :subnets
55
- apipie_options
56
88
  end
57
89
 
58
90
  class RemoveSubnetCommand < HammerCLIForeman::RemoveAssociatedCommand
59
91
  associated_resource :subnets
60
- apipie_options
61
92
  end
62
93
  end
63
94
 
64
95
  module ComputeResource
96
+ extend CommandExtension
97
+
65
98
  class AddComputeResourceCommand < HammerCLIForeman::AddAssociatedCommand
66
99
  associated_resource :compute_resources
67
- apipie_options
68
100
  end
69
101
 
70
102
  class RemoveComputeResourceCommand < HammerCLIForeman::RemoveAssociatedCommand
71
103
  associated_resource :compute_resources
72
- apipie_options
73
104
  end
74
105
  end
75
106
 
76
107
  module SmartProxy
108
+ extend CommandExtension
109
+
77
110
  class AddSmartProxyCommand < HammerCLIForeman::AddAssociatedCommand
78
111
  associated_resource :smart_proxies
79
- apipie_options
80
112
 
81
113
  def associated_resource_name
82
114
  "smart-proxy"
@@ -85,7 +117,6 @@ module HammerCLIForeman
85
117
 
86
118
  class RemoveSmartProxyCommand < HammerCLIForeman::RemoveAssociatedCommand
87
119
  associated_resource :smart_proxies
88
- apipie_options
89
120
 
90
121
  def associated_resource_name
91
122
  "smart-proxy"
@@ -94,21 +125,17 @@ module HammerCLIForeman
94
125
  end
95
126
 
96
127
  module User
97
- class AddUserCommand < HammerCLIForeman::AddAssociatedCommand
98
- associated_identifiers :id
128
+ extend CommandExtension
99
129
 
130
+ class AddUserCommand < HammerCLIForeman::AddAssociatedCommand
100
131
  associated_resource :users
101
- apipie_options
102
132
 
103
133
  success_message "The user has been associated"
104
134
  failure_message "Could not associate the user"
105
135
  end
106
136
 
107
137
  class RemoveUserCommand < HammerCLIForeman::RemoveAssociatedCommand
108
- associated_identifiers :id
109
-
110
138
  associated_resource :users
111
- apipie_options
112
139
 
113
140
  success_message "The user has been disassociated"
114
141
  failure_message "Could not disassociate the user"
@@ -116,36 +143,35 @@ module HammerCLIForeman
116
143
  end
117
144
 
118
145
  module ConfigTemplate
146
+ extend CommandExtension
147
+
119
148
  class AddConfigTemplateCommand < HammerCLIForeman::AddAssociatedCommand
120
149
  associated_resource :config_templates
121
- apipie_options
122
150
  end
123
151
 
124
152
  class RemoveConfigTemplateCommand < HammerCLIForeman::RemoveAssociatedCommand
125
153
  associated_resource :config_templates
126
- apipie_options
127
154
  end
128
155
  end
129
156
 
130
157
  module Organization
158
+ extend CommandExtension
159
+
131
160
  class AddOrganizationCommand < HammerCLIForeman::AddAssociatedCommand
132
161
  associated_resource :organizations
133
- apipie_options
134
162
  end
135
163
 
136
164
  class RemoveOrganizationCommand < HammerCLIForeman::RemoveAssociatedCommand
137
165
  associated_resource :organizations
138
- apipie_options
139
166
  end
140
167
  end
141
168
 
142
169
  module OperatingSystem
170
+ extend CommandExtension
171
+
143
172
  class AddOSCommand < HammerCLIForeman::AddAssociatedCommand
144
173
  associated_resource :operatingsystems
145
174
 
146
- associated_identifiers :id
147
- apipie_options
148
-
149
175
  success_message _("Operating system has been associated")
150
176
  failure_message _("Could not associate the operating system")
151
177
  end
@@ -154,18 +180,16 @@ module HammerCLIForeman
154
180
  class RemoveOSCommand < HammerCLIForeman::RemoveAssociatedCommand
155
181
  associated_resource :operatingsystems
156
182
 
157
- associated_identifiers :id
158
- apipie_options
159
-
160
183
  success_message _("Operating system has been disassociated")
161
184
  failure_message _("Could not disassociate the operating system")
162
185
  end
163
186
  end
164
187
 
165
188
  module Architecture
189
+ extend CommandExtension
190
+
166
191
  class AddArchitectureCommand < HammerCLIForeman::AddAssociatedCommand
167
192
  associated_resource :architectures
168
- apipie_options
169
193
 
170
194
  success_message _("Architecture has been associated")
171
195
  failure_message _("Could not associate the architecture")
@@ -174,7 +198,6 @@ module HammerCLIForeman
174
198
 
175
199
  class RemoveArchitectureCommand < HammerCLIForeman::RemoveAssociatedCommand
176
200
  associated_resource :architectures
177
- apipie_options
178
201
 
179
202
  success_message _("Architecture has been disassociated")
180
203
  failure_message _("Could not disassociate the architecture")
@@ -182,9 +205,10 @@ module HammerCLIForeman
182
205
  end
183
206
 
184
207
  module PartitionTable
208
+ extend CommandExtension
209
+
185
210
  class AddPartitionTableCommand < HammerCLIForeman::AddAssociatedCommand
186
211
  associated_resource :ptables
187
- apipie_options
188
212
 
189
213
  success_message _("Partition table has been associated")
190
214
  failure_message _("Could not associate the partition table")
@@ -193,7 +217,6 @@ module HammerCLIForeman
193
217
 
194
218
  class RemovePartitionTableCommand < HammerCLIForeman::RemoveAssociatedCommand
195
219
  associated_resource :ptables
196
- apipie_options
197
220
 
198
221
  success_message _("Partition table has been disassociated")
199
222
  failure_message _("Could not disassociate the partition table")
@@ -18,25 +18,22 @@ module HammerCLIForeman
18
18
  config[:api_version] = 2
19
19
  config[:aggressive_cache_checking] = HammerCLI::Settings.get(:foreman, :refresh_cache) || true
20
20
  config[:headers] = { "Accept-Language" => HammerCLI::I18n.locale }
21
+ config[:language] = HammerCLI::I18n.locale
21
22
  config[:timeout] = HammerCLI::Settings.get(:foreman, :request_timeout)
23
+ config[:timeout] = -1 if (config[:timeout] && config[:timeout].to_i < 0)
22
24
  config
23
25
  end
24
26
 
25
- def self.foreman_resource(resource)
27
+ def self.foreman_api_connection
26
28
  HammerCLI::Connection.create(
27
- CONNECTION_NAME,
28
- HammerCLI::Apipie::Command.resource_config.merge(resource_config),
29
- HammerCLI::Apipie::Command.connection_options).api.resource(resource)
29
+ CONNECTION_NAME,
30
+ HammerCLI::Apipie::Command.resource_config.merge(resource_config),
31
+ HammerCLI::Apipie::Command.connection_options
32
+ )
30
33
  end
31
34
 
32
- module ConnectionSetup
33
- def connection_name(resource_class)
34
- CONNECTION_NAME
35
- end
36
-
37
- def resource_config
38
- super.merge(HammerCLIForeman.resource_config)
39
- end
35
+ def self.foreman_resource(resource)
36
+ foreman_api_connection.api.resource(resource)
40
37
  end
41
38
 
42
39
  def self.collection_to_common_format(data)
@@ -65,23 +62,71 @@ module HammerCLIForeman
65
62
  data.class <= Hash && data.keys.length == 1 ? data[data.keys[0]] : data
66
63
  end
67
64
 
68
- class ReadCommand < HammerCLI::Apipie::ReadCommand
69
- extend HammerCLIForeman::ConnectionSetup
70
- end
71
65
 
72
- class Command < ReadCommand
73
- end
66
+ class Command < HammerCLI::Apipie::Command
67
+
68
+ def self.connection_name(resource_class)
69
+ CONNECTION_NAME
70
+ end
71
+
72
+ def self.resource_config
73
+ super.merge(HammerCLIForeman.resource_config)
74
+ end
75
+
76
+ def resolver
77
+ self.class.resolver
78
+ end
79
+
80
+ def searchables
81
+ self.class.searchables
82
+ end
83
+
84
+ def get_identifier
85
+ @identifier ||= get_resource_id(resource)
86
+ @identifier
87
+ end
88
+
89
+ def get_resource_id(resource, options={})
90
+ if options[:scoped]
91
+ opts = resolver.scoped_options(resource.singular_name, all_options)
92
+ else
93
+ opts = all_options
94
+ end
95
+ begin
96
+ resolver.send("#{resource.singular_name}_id", opts)
97
+ rescue HammerCLIForeman::MissingSeachOptions => e
98
+ raise e unless (options[:required] == false)
99
+ end
100
+ end
101
+
102
+ def self.resolver
103
+ api = HammerCLI::Connection.get("foreman").api
104
+ HammerCLIForeman::IdResolver.new(api, HammerCLIForeman::Searchables.new)
105
+ end
74
106
 
75
- class WriteCommand < HammerCLI::Apipie::WriteCommand
76
- extend HammerCLIForeman::ConnectionSetup
107
+ def self.searchables
108
+ @searchables ||= HammerCLIForeman::Searchables.new
109
+ @searchables
110
+ end
77
111
 
78
112
  def send_request
79
113
  HammerCLIForeman.record_to_common_format(super)
80
114
  end
81
115
 
116
+ def request_params
117
+ params = super
118
+ resolver.id_params(resource.action(action)).each do |api_param|
119
+ param_resource = resolver.param_to_resource(api_param.name)
120
+ resource_id = get_resource_id(param_resource, :scoped => true, :required => api_param.required?)
121
+ params[api_param.name] = resource_id if resource_id
122
+ end
123
+ params
124
+ end
125
+
82
126
  end
83
127
 
84
- class ListCommand < ReadCommand
128
+
129
+ class ListCommand < Command
85
130
 
86
131
  action :index
87
132
 
@@ -91,7 +136,7 @@ module HammerCLIForeman
91
136
  :table
92
137
  end
93
138
 
94
- def retrieve_data
139
+ def send_request
95
140
  data = super
96
141
  set = HammerCLIForeman.collection_to_common_format(data)
97
142
  set.map! { |r| extend_data(r) }
@@ -120,6 +165,7 @@ module HammerCLIForeman
120
165
 
121
166
  protected
122
167
 
168
+
123
169
  def browse_collection
124
170
  list_next = true
125
171
 
@@ -137,31 +183,89 @@ module HammerCLIForeman
137
183
  end
138
184
 
139
185
  def retrieve_and_print
140
- d = retrieve_data
141
- logger.watch "Retrieved data: ", d
186
+ d = send_request
142
187
  print_data d
143
188
  d
144
189
  end
145
190
 
191
+ def self.custom_option_builders
192
+ builders = super
193
+ if resource_defined?
194
+ builders += [
195
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => true, :recursive => true), searchables),
196
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => false, :recursive => false), searchables)
197
+ ]
198
+ end
199
+ builders
200
+ end
201
+
146
202
  end
147
203
 
148
204
 
149
- class InfoCommand < ReadCommand
205
+ class SingleResourceCommand < Command
150
206
 
151
- action :show
207
+ def self.custom_option_builders
208
+ builders = super
209
+ if resource_defined?
210
+ builders += [
211
+ SearchablesOptionBuilder.new(resource, searchables),
212
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => true, :recursive => true), searchables),
213
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => false, :recursive => false), searchables)
214
+ ]
215
+ end
216
+ builders
217
+ end
152
218
 
153
- def self.command_name(name=nil)
154
- super(name) || "info"
219
+ def request_params
220
+ params = super
221
+ params['id'] ||= get_identifier
222
+ params
223
+ end
224
+
225
+ end
226
+
227
+
228
+ class AssociatedResourceListCommand < ListCommand
229
+
230
+ option "--id", "ID", " "
231
+
232
+ def parent_resource
233
+ self.class.parent_resource
155
234
  end
156
235
 
157
- identifiers :id, :name
236
+ def self.parent_resource(name=nil)
237
+ @parent_api_resource = HammerCLIForeman.foreman_resource(name) unless name.nil?
238
+ return @parent_api_resource if @parent_api_resource
239
+ return superclass.parent_resource if superclass.respond_to? :parent_resource
240
+ end
241
+
242
+ def self.custom_option_builders
243
+ [
244
+ HammerCLI::Apipie::OptionBuilder.new(resource.action(action), :require_options => false),
245
+ SearchablesOptionBuilder.new(parent_resource, searchables)
246
+ ]
247
+ end
158
248
 
159
249
  def request_params
250
+ id_param_name = "#{parent_resource.singular_name}_id"
251
+
160
252
  params = method_options
161
- params.update('id' => get_identifier[0])
253
+ params[id_param_name] = get_resource_id(parent_resource)
254
+ params
255
+ end
256
+
257
+ end
258
+
259
+
260
+ class InfoCommand < SingleResourceCommand
261
+
262
+ action :show
263
+
264
+ def self.command_name(name=nil)
265
+ super(name) || "info"
162
266
  end
163
267
 
164
- def retrieve_data
268
+ def send_request
165
269
  data = super
166
270
  record = HammerCLIForeman.record_to_common_format(data)
167
271
  extend_data(record)
@@ -178,7 +282,7 @@ module HammerCLIForeman
178
282
  end
179
283
 
180
284
 
181
- class CreateCommand < WriteCommand
285
+ class CreateCommand < Command
182
286
 
183
287
  action :create
184
288
 
@@ -186,10 +290,22 @@ module HammerCLIForeman
186
290
  super(name) || "create"
187
291
  end
188
292
 
293
+ def self.custom_option_builders
294
+ builders = super
295
+ if resource_defined?
296
+ builders += [
297
+ SearchablesOptionBuilder.new(resource, searchables),
298
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => true, :recursive => true), searchables),
299
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => false, :recursive => false), searchables)
300
+ ]
301
+ end
302
+ builders
303
+ end
304
+
189
305
  end
190
306
 
191
307
 
192
- class UpdateCommand < WriteCommand
308
+ class UpdateCommand < SingleResourceCommand
193
309
 
194
310
  action :update
195
311
 
@@ -197,23 +313,30 @@ module HammerCLIForeman
197
313
  super(name) || "update"
198
314
  end
199
315
 
200
- identifiers :id, :name => :option_current_name
201
-
202
- def self.setup_identifier_options
203
- super
204
- option "--new-name", "NEW_NAME", _("new name for the resource"), :attribute_name => :option_name if identifier? :name
316
+ def self.custom_option_builders
317
+ builders = super
318
+ if resource_defined?
319
+ builders += [
320
+ SearchablesUpdateOptionBuilder.new(resource, searchables)
321
+ ]
322
+ end
323
+ builders
205
324
  end
206
325
 
207
- def request_params
208
- params = method_options
209
- params['id'] = get_identifier[0]
210
- params
326
+ def method_options_for_params(params, include_nil=true)
327
+ opts = super
328
+ # overwrite searchables with correct values
329
+ searchables.for(resource).each do |s|
330
+ new_value = get_option_value("new_#{s.name}")
331
+ opts[s.name] = new_value unless new_value.nil?
332
+ end
333
+ opts
211
334
  end
212
335
 
213
336
  end
214
337
 
215
338
 
216
- class DeleteCommand < WriteCommand
339
+ class DeleteCommand < SingleResourceCommand
217
340
 
218
341
  action :destroy
219
342
 
@@ -221,75 +344,44 @@ module HammerCLIForeman
221
344
  super(name) || "delete"
222
345
  end
223
346
 
224
- identifiers :id, :name
225
-
226
- def request_params
227
- {'id' => get_identifier[0]}
228
- end
229
-
230
347
  end
231
348
 
232
349
 
233
- class AssociatedCommand < WriteCommand
234
-
235
- identifiers :name, :id
236
- action :update
237
-
238
- def validate_options
239
- associated_ids = self.class.declared_associated_identifiers.collect {|id_name| "associated_#{id_name}" }
240
- validator.any(*associated_ids).required
241
- validator.any(*self.class.declared_identifiers.values).required
242
- end
350
+ class AssociatedCommand < Command
243
351
 
244
- def self.apipie_options(options={})
245
- setup_associated_identifier_options
246
- super
247
- end
352
+ option "--id", "ID", " "
248
353
 
249
- def self.setup_associated_identifier_options
250
- name = associated_resource.singular_name
251
- option_switch = "--"+name.gsub('_', '-')
354
+ action :update
252
355
 
253
- option option_switch, name.upcase, " ", :attribute_name => :associated_name do |value|
254
- name_to_id(value, "name", associated_resource)
255
- end if declared_associated_identifiers.include? :name
256
- option option_switch+"-id", name.upcase+"_ID", " ", :attribute_name => :associated_id if declared_associated_identifiers.include? :id
356
+ def self.custom_option_builders
357
+ [
358
+ SearchablesOptionBuilder.new(resource, searchables),
359
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(resource, :required => true, :recursive => true), searchables),
360
+ DependentSearchablesOptionBuilder.new(associated_resource, searchables),
361
+ DependentSearchablesOptionBuilder.new(resolver.dependent_resources(associated_resource, :required => true, :recursive => true), searchables)
362
+ ]
257
363
  end
258
364
 
259
-
260
365
  def associated_resource
261
366
  self.class.associated_resource
262
367
  end
263
368
 
264
- def self.associated_resource(resource_class=nil)
265
- @associated_api_resource = HammerCLIForeman.foreman_resource(resource_class) unless resource_class.nil?
266
- return @associated_api_resource
369
+ def self.associated_resource(name=nil)
370
+ @associated_api_resource = HammerCLIForeman.foreman_resource(name) unless name.nil?
371
+ return @associated_api_resource if @associated_api_resource
372
+ return superclass.associated_resource if superclass.respond_to? :associated_resource
267
373
  end
268
374
 
269
-
270
-
271
- def self.associated_identifiers(*keys)
272
- @associated_identifiers = keys
375
+ def get_associated_identifier
376
+ get_resource_id(associated_resource, :scoped => true)
273
377
  end
274
378
 
275
- def self.declared_associated_identifiers
276
- if @associated_identifiers
277
- return @associated_identifiers
278
- elsif superclass.respond_to?(:declared_associated_identifiers, true)
279
- superclass.declared_associated_identifiers
280
- else
281
- []
282
- end
283
- end
284
-
285
- associated_identifiers :name, :id
286
-
287
379
  def get_new_ids
288
380
  []
289
381
  end
290
382
 
291
383
  def get_current_ids
292
- item = HammerCLIForeman.record_to_common_format(resource.call(:show, {:id => get_identifier[0]}))
384
+ item = HammerCLIForeman.record_to_common_format(resource.call(:show, {:id => get_identifier}))
293
385
  if item.has_key?(association_name(true))
294
386
  item[association_name(true)].map { |assoc| assoc['id'] }
295
387
  else
@@ -297,19 +389,14 @@ module HammerCLIForeman
297
389
  end
298
390
  end
299
391
 
300
- def get_required_id
301
- item = HammerCLIForeman.record_to_common_format(associated_resource.call(:show, {:id => associated_id || associated_name}))
302
- item['id']
303
- end
304
-
305
392
  def request_params
306
- params = super
393
+ params = method_options
307
394
  if params.key?(resource.singular_name)
308
395
  params[resource.singular_name] = {"#{association_name}_ids" => get_new_ids }
309
396
  else
310
397
  params["#{association_name}_ids"] = get_new_ids
311
398
  end
312
- params['id'] = get_identifier[0]
399
+ params['id'] = get_identifier
313
400
  params
314
401
  end
315
402
 
@@ -331,8 +418,8 @@ module HammerCLIForeman
331
418
  end
332
419
 
333
420
  def get_new_ids
334
- ids = get_current_ids
335
- required_id = get_required_id
421
+ ids = get_current_ids.map(&:to_s)
422
+ required_id = get_associated_identifier.to_s
336
423
 
337
424
  ids << required_id unless ids.include? required_id
338
425
  ids
@@ -352,8 +439,8 @@ module HammerCLIForeman
352
439
  end
353
440
 
354
441
  def get_new_ids
355
- ids = get_current_ids
356
- required_id = get_required_id
442
+ ids = get_current_ids.map(&:to_s)
443
+ required_id = get_associated_identifier.to_s
357
444
 
358
445
  ids = ids.delete_if { |id| id == required_id }
359
446
  ids