hammer_cli_foreman 0.14.0 → 0.15.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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/doc/host_create.md +120 -85
  3. data/doc/release_notes.md +12 -0
  4. data/lib/hammer_cli_foreman/compute_resource.rb +106 -11
  5. data/lib/hammer_cli_foreman/compute_resources/vmware/host_help_extenstion.rb +25 -21
  6. data/lib/hammer_cli_foreman/host.rb +42 -1
  7. data/lib/hammer_cli_foreman/hosts/common_update_options.rb +9 -3
  8. data/lib/hammer_cli_foreman/output/fields.rb +45 -10
  9. data/lib/hammer_cli_foreman/output/formatters.rb +82 -45
  10. data/lib/hammer_cli_foreman/subnet.rb +25 -0
  11. data/lib/hammer_cli_foreman/version.rb +1 -1
  12. data/locale/ca/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  13. data/locale/de/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  14. data/locale/en/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  15. data/locale/en_GB/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  16. data/locale/es/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  17. data/locale/fr/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  18. data/locale/it/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  19. data/locale/ja/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  20. data/locale/ko/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  21. data/locale/pt_BR/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  22. data/locale/ru/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  23. data/locale/zh_CN/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  24. data/locale/zh_TW/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  25. data/test/functional/compute_resource_test.rb +260 -0
  26. data/test/functional/host_test.rb +49 -0
  27. data/test/functional/subnet/create_test.rb +131 -0
  28. data/test/functional/subnet/update_test.rb +130 -0
  29. data/test/unit/apipie_resource_mock.rb +4 -0
  30. data/test/unit/compute_resource_test.rb +22 -0
  31. data/test/unit/host_test.rb +2 -2
  32. data/test/unit/output/formatters_test.rb +77 -68
  33. metadata +10 -6
@@ -33,6 +33,7 @@ module HammerCLIForeman
33
33
  field nil, _("Host Group"), Fields::SingleReference, :key => :hostgroup, :display_field => 'title'
34
34
  field :ip, _("IP")
35
35
  field :mac, _("MAC")
36
+ field :global_status_label, _("Global Status")
36
37
  end
37
38
 
38
39
  build_options :without => [:include, :thin]
@@ -70,6 +71,11 @@ module HammerCLIForeman
70
71
  field :installed_at, _("Installed at"), Fields::Date
71
72
  field :last_report, _("Last report"), Fields::Date
72
73
 
74
+ label _("Status") do
75
+ field :global_status_label, _("Global Status")
76
+ field :build_status_label, _("Build Status")
77
+ end
78
+
73
79
  label _("Network") do
74
80
  field :ip, _("IPv4 address"), Fields::Field, :hide_blank => true
75
81
  field :ip6, _("IPv6 address"), Fields::Field, :hide_blank => true
@@ -422,6 +428,21 @@ module HammerCLIForeman
422
428
  build_options :without => :power_action
423
429
  end
424
430
 
431
+ class ResetCommand < HammerCLIForeman::SingleResourceCommand
432
+ action :power
433
+
434
+ command_name 'reset'
435
+ desc _('Reset a host')
436
+ success_message _('Host reset started.')
437
+ failure_message _('Failed to reset the host')
438
+
439
+ def option_power_action
440
+ :cycle
441
+ end
442
+
443
+ build_options without: [:power_action]
444
+ end
445
+
425
446
  class SCParamsCommand < HammerCLIForeman::SmartClassParametersList
426
447
  build_options_for :hosts
427
448
 
@@ -474,11 +495,31 @@ module HammerCLIForeman
474
495
  build_options
475
496
  end
476
497
 
498
+ class BootCommand < HammerCLIForeman::SingleResourceCommand
499
+ action :boot
500
+
501
+ command_name 'boot'
502
+ success_message _('The host is booting.')
503
+ failure_message _('Failed to boot the host from device')
504
+
505
+ def execute
506
+ response = send_request
507
+ if response['result']
508
+ output.print_message(success_message)
509
+ HammerCLI::EX_OK
510
+ else
511
+ output.print_error(failure_message)
512
+ HammerCLI::EX_DATAERR
513
+ end
514
+ end
515
+
516
+ build_options
517
+ end
518
+
477
519
  autoload_subcommands
478
520
 
479
521
  subcommand 'interface', HammerCLIForeman::Interface.desc, HammerCLIForeman::Interface
480
522
  end
481
-
482
523
  end
483
524
 
484
525
  require 'hammer_cli_foreman/compute_resources/all'
@@ -72,10 +72,16 @@ module HammerCLIForeman
72
72
  end
73
73
  params['host']['overwrite'] = option_overwrite unless option_overwrite.nil?
74
74
 
75
- params['host']['host_parameters_attributes'] = parameter_attributes
75
+ params['host']['host_parameters_attributes'] = parameter_attributes unless option_parameters.nil?
76
76
  params['host']['compute_attributes'] = option_compute_attributes || {}
77
- params['host']['compute_attributes']['volumes_attributes'] = nested_attributes(option_volume_list)
78
- params['host']['interfaces_attributes'] = interfaces_attributes
77
+
78
+ if action == :update
79
+ params['host']['compute_attributes']['volumes_attributes'] = nested_attributes(option_volume_list) unless option_volume_list.empty?
80
+ params['host']['interfaces_attributes'] = interfaces_attributes unless option_interface_list.empty?
81
+ else
82
+ params['host']['compute_attributes']['volumes_attributes'] = nested_attributes(option_volume_list)
83
+ params['host']['interfaces_attributes'] = interfaces_attributes
84
+ end
79
85
 
80
86
  params['host']['root_pass'] = option_root_password unless option_root_password.nil?
81
87
 
@@ -2,25 +2,60 @@ require 'hammer_cli'
2
2
 
3
3
  module Fields
4
4
 
5
- class SingleReference < Field
5
+ class Reference < Field
6
+ def initialize(options={})
7
+ super
8
+ initialize_options
9
+ end
6
10
 
7
- def display?(value)
8
- id_key = "#{parameters[:key]}_id"
9
- display_field = parameters[:display_field] || 'name'
10
- display_key = "#{parameters[:key]}_#{display_field}"
11
+ def initialize_options
12
+ @options[:details] ||= []
13
+ @options[:details] = [@options[:details]] unless @options[:details].is_a?(Array)
14
+ @options[:details] = [id_detail] + @options[:details]
15
+ @options[:display_field_key] ||= @options[:name_key] || :name
16
+ end
11
17
 
12
- (value[display_key.to_sym] || value[display_key]) && (value[id_key.to_sym] || value[id_key])
18
+ protected
19
+
20
+ def id_detail
21
+ {
22
+ :label => _('id'),
23
+ :structured_label => _('Id'),
24
+ :key => @options[:id_key] || :id,
25
+ :id => true
26
+ }
13
27
  end
14
28
  end
15
29
 
16
- class Reference < Field
30
+ class SingleReference < Reference
31
+ def initialize_options
32
+ key = @options[:key]
33
+ display_field = @options[:display_field] || 'name'
34
+
35
+ @options[:id_key] ||= "#{key}_id"
36
+ @options[:display_field_key] ||= "#{key}_#{display_field}"
37
+ super
38
+ end
39
+
40
+ def display?(value)
41
+ id_key = @options[:id_key]
42
+ display_key = @options[:display_field_key]
43
+
44
+ (value[display_key.to_sym] || value[display_key]) && (value[id_key.to_sym] || value[id_key])
45
+ end
17
46
  end
18
47
 
19
48
  class Template < Reference
49
+ def initialize_options
50
+ super
51
+ @options[:details] << template_kind_detail
52
+ end
20
53
 
21
- def initialize(options={})
22
- options[:details] ||= [:template_kind_name]
23
- super(options)
54
+ def template_kind_detail
55
+ {
56
+ :structured_label => _('Kind'),
57
+ :key => :template_kind_name,
58
+ }
24
59
  end
25
60
  end
26
61
 
@@ -1,69 +1,106 @@
1
1
  module HammerCLIForeman::Output
2
2
  module Formatters
3
-
4
- class SingleReferenceFormatter < HammerCLI::Output::Formatters::FieldFormatter
5
-
3
+ class ReferenceFormatter < HammerCLI::Output::Formatters::FieldFormatter
6
4
  def tags
7
5
  [:flat]
8
6
  end
9
7
 
10
- def format(resource, field_params={})
11
- return "" if resource.nil?
12
-
13
- key = field_params[:key]
14
- display_field = field_params[:display_field] || 'name'
15
-
16
- id_key = "#{key}_id"
17
- display_key = "#{key}_#{display_field}"
18
-
19
- name = resource[display_key.to_sym] || resource[display_key]
20
- id = resource[id_key.to_sym] || resource[id_key]
21
-
8
+ # Parameters:
9
+ # :display_field_key - key where the formmatter will look for the main field to display, default is :name
10
+ # :details - detail fields to be displayed
11
+ # example format:
12
+ # :details => [
13
+ # { :label => _('Type'), :key => :provider_friendly_name, :structured_label => _('Type') },
14
+ # { :label => _('Id'), :key => :id }
15
+ # ]
16
+ def format(data, field_params={})
17
+ return "" if data.nil?
18
+
19
+ name = get_value(data, field_params[:display_field_key] || :name)
22
20
  context = field_params[:context] || {}
23
21
 
24
- out = "#{name}"
25
- out += " (id: #{id})" if context[:show_ids] && id
26
- out
22
+ details = format_details(data, field_params[:details] || [], context[:show_ids])
23
+ if details.empty?
24
+ "#{name}" if name
25
+ else
26
+ "#{name} (#{details.join(', ')})" if name
27
+ end
27
28
  end
28
29
 
29
- end
30
+ protected
31
+ def format_details(data, details, show_ids)
32
+ details = [details] unless details.is_a?(Array)
33
+
34
+ details.map do |detail|
35
+ if detail.is_a?(Hash)
36
+ next if detail[:id] && !show_ids
37
+ if detail[:label]
38
+ "#{detail[:label]}: #{get_value(data, detail[:key])}"
39
+ else
40
+ get_value(data, detail[:key])
41
+ end
42
+ else
43
+ get_value(data, detail)
44
+ end
45
+ end.compact
46
+ end
30
47
 
31
- class ReferenceFormatter < HammerCLI::Output::Formatters::FieldFormatter
48
+ def get_value(data, key)
49
+ data[key] || data[key.to_s]
50
+ end
51
+ end
32
52
 
53
+ class StructuredReferenceFormatter < HammerCLI::Output::Formatters::FieldFormatter
33
54
  def tags
34
- [:flat]
55
+ [:data]
35
56
  end
36
57
 
37
- def format(reference, field_params={})
38
- return "" if reference.nil? || reference == ""
39
-
40
- id_key = field_params[:id_key] || :id
41
- name_key = field_params[:name_key] || :name
42
-
43
- name = reference[name_key] || reference[name_key.to_s]
44
- id = reference[id_key] || reference[id_key.to_s]
45
-
46
- context = field_params[:context] || {}
47
-
48
- details = field_params[:details] || []
49
- details = [details] unless details.is_a? Array
50
- values = details.collect do |key|
51
- reference[key] || reference[key.to_s]
52
- end
53
- values << "id: #{id}" if context[:show_ids]
54
-
55
- if values.empty?
56
- "#{name}" if name
57
- else
58
- "#{name} (#{values.join(', ')})" if name && !values.empty?
58
+ # Parameters:
59
+ # :display_field_key - key where the formmatter will look for the main field to display, default is :name
60
+ # :details - detail fields to be displayed
61
+ # example format:
62
+ # :details => [
63
+ # { :label => _('Type'), :key => :provider_friendly_name, :structured_label => _('Type') },
64
+ # { :label => _('Id'), :key => :id }
65
+ # ]
66
+ def format(data, field_params={})
67
+ return {} if data.nil? || data == ""
68
+
69
+ display_field_key = field_params[:display_field_key] || :name
70
+
71
+ # TODO: hardcoded name
72
+ formatted = {
73
+ _('Name') => get_value(data, display_field_key)
74
+ }
75
+
76
+ details = field_params[:details]
77
+ details = [details] unless details.is_a?(Array)
78
+
79
+ details.map do |detail|
80
+ if detail.is_a?(Hash)
81
+ label = detail[:structured_label]
82
+ label = detail[:label].capitalize if !label && detail[:label]
83
+ if label
84
+ formatted[label] = get_value(data, detail[:key])
85
+ end
86
+ end
59
87
  end
88
+ formatted
60
89
  end
61
90
 
91
+ protected
92
+ def get_value(data, key)
93
+ data[key] || data[key.to_s]
94
+ end
62
95
  end
63
96
 
64
- HammerCLI::Output::Output.register_formatter(SingleReferenceFormatter.new, :SingleReference)
97
+ HammerCLI::Output::Output.register_formatter(ReferenceFormatter.new, :SingleReference)
98
+ HammerCLI::Output::Output.register_formatter(StructuredReferenceFormatter.new, :SingleReference)
99
+
65
100
  HammerCLI::Output::Output.register_formatter(ReferenceFormatter.new, :Reference)
101
+ HammerCLI::Output::Output.register_formatter(StructuredReferenceFormatter.new, :Reference)
66
102
  HammerCLI::Output::Output.register_formatter(ReferenceFormatter.new, :Template)
67
-
103
+ HammerCLI::Output::Output.register_formatter(StructuredReferenceFormatter.new, :Template)
68
104
  end
69
105
  end
106
+
@@ -1,5 +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
+
11
+ def request_params
12
+ 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
16
+ params
17
+ end
18
+
19
+ private
20
+
21
+ def proxy_feature_id(name)
22
+ resolver.smart_proxy_id('option_name' => name) if name
23
+ end
24
+ end
25
+
3
26
  class Subnet < HammerCLIForeman::Command
4
27
 
5
28
  resource :subnets
@@ -55,6 +78,7 @@ module HammerCLIForeman
55
78
 
56
79
 
57
80
  class CreateCommand < HammerCLIForeman::CreateCommand
81
+ include SubnetUpdateCreateCommons
58
82
 
59
83
  success_message _("Subnet created.")
60
84
  failure_message _("Could not create the subnet")
@@ -64,6 +88,7 @@ module HammerCLIForeman
64
88
 
65
89
 
66
90
  class UpdateCommand < HammerCLIForeman::UpdateCommand
91
+ include SubnetUpdateCreateCommons
67
92
 
68
93
  success_message _("Subnet updated.")
69
94
  failure_message _("Could not update the subnet")
@@ -1,5 +1,5 @@
1
1
  module HammerCLIForeman
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.14.0'
3
+ @version ||= Gem::Version.new '0.15.0'
4
4
  end
5
5
  end
@@ -1,6 +1,15 @@
1
1
  require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  describe 'compute-resource' do
4
+ let(:base_cmd) { ['compute-resource'] }
5
+ let(:base_params) { ['--id=1'] }
6
+ let(:compute_resource) do
7
+ {
8
+ :id => 1,
9
+ :name => 'resource'
10
+ }
11
+ end
12
+
4
13
  describe 'create' do
5
14
  before do
6
15
  @cmd = %w(compute-resource create)
@@ -114,4 +123,255 @@ describe 'compute-resource' do
114
123
  assert_cmd(success_result("Compute resource created.\n"), result)
115
124
  end
116
125
  end
126
+
127
+ describe 'clusters' do
128
+ let(:cmd) { base_cmd << 'clusters' }
129
+ let(:cluster1) { { id: 1, name: 'cluster1' } }
130
+ let(:cluster2) { { id: 2, name: 'cluster2' } }
131
+ let(:clusters) { [cluster1, cluster2] }
132
+
133
+ it 'lists available clusters for a compute resource' do
134
+ api_expects(:compute_resources, :available_clusters, 'clusters').with_params(
135
+ 'id' => '1'
136
+ ).returns(index_response(clusters))
137
+
138
+ output = IndexMatcher.new(
139
+ [
140
+ %w[ID NAME],
141
+ %w[1 cluster1],
142
+ %w[2 cluster2]
143
+ ]
144
+ )
145
+ expected_result = success_result(output)
146
+
147
+ result = run_cmd(cmd + base_params)
148
+ assert_cmd(expected_result, result)
149
+ end
150
+ end
151
+
152
+ describe 'networks' do
153
+ let(:cmd) { base_cmd << 'networks' }
154
+ let(:network1) { { id: 1, name: 'network1' } }
155
+ let(:network2) { { id: 2, name: 'network2' } }
156
+ let(:networks) { [network1, network2] }
157
+
158
+ it 'lists available networks for a compute resource' do
159
+ api_expects(:compute_resources, :available_networks, 'networks').with_params(
160
+ 'id' => '1'
161
+ ).returns(index_response(networks))
162
+
163
+ output = IndexMatcher.new(
164
+ [
165
+ %w[ID NAME],
166
+ %w[1 network1],
167
+ %w[2 network2]
168
+ ]
169
+ )
170
+ expected_result = success_result(output)
171
+
172
+ result = run_cmd(cmd + base_params)
173
+ assert_cmd(expected_result, result)
174
+ end
175
+ end
176
+
177
+ describe 'images' do
178
+ let(:cmd) { base_cmd << 'images' }
179
+ let(:image1) { { id: 1, name: 'image1' } }
180
+ let(:image2) { { id: 2, name: 'image2' } }
181
+ let(:images) { [image1, image2] }
182
+
183
+ it 'lists available images for a compute resource' do
184
+ api_expects(:compute_resources, :available_images, 'images').with_params(
185
+ 'id' => '1'
186
+ ).returns(index_response(images))
187
+
188
+ output = IndexMatcher.new(
189
+ [
190
+ %w[ID NAME],
191
+ %w[1 image1],
192
+ %w[2 image2]
193
+ ]
194
+ )
195
+ expected_result = success_result(output)
196
+
197
+ result = run_cmd(cmd + base_params)
198
+ assert_cmd(expected_result, result)
199
+ end
200
+ end
201
+
202
+ describe 'flavors' do
203
+ let(:cmd) { base_cmd << 'flavors' }
204
+ let(:flavor1) { { id: 1, name: 'flavor1' } }
205
+ let(:flavor2) { { id: 2, name: 'flavor2' } }
206
+ let(:flavors) { [flavor1, flavor2] }
207
+
208
+ it 'lists available flavors for a compute resource' do
209
+ api_expects(:compute_resources, :available_flavors, 'flavors').with_params(
210
+ 'id' => '1'
211
+ ).returns(index_response(flavors))
212
+
213
+ output = IndexMatcher.new(
214
+ [
215
+ %w[ID NAME],
216
+ %w[1 flavor1],
217
+ %w[2 flavor2]
218
+ ]
219
+ )
220
+ expected_result = success_result(output)
221
+
222
+ result = run_cmd(cmd + base_params)
223
+ assert_cmd(expected_result, result)
224
+ end
225
+ end
226
+
227
+ describe 'folders' do
228
+ let(:cmd) { base_cmd << 'folders' }
229
+ let(:folder1) { { id: 1, name: 'folder1' } }
230
+ let(:folder2) { { id: 2, name: 'folder2' } }
231
+ let(:folders) { [folder1, folder2] }
232
+
233
+ it 'lists available folders for a compute resource' do
234
+ api_expects(:compute_resources, :available_folders, 'folders').with_params(
235
+ 'id' => '1'
236
+ ).returns(index_response(folders))
237
+
238
+ output = IndexMatcher.new(
239
+ [
240
+ %w[ID NAME],
241
+ %w[1 folder1],
242
+ %w[2 folder2]
243
+ ]
244
+ )
245
+ expected_result = success_result(output)
246
+
247
+ result = run_cmd(cmd + base_params)
248
+ assert_cmd(expected_result, result)
249
+ end
250
+ end
251
+
252
+ describe 'zones' do
253
+ let(:cmd) { base_cmd << 'zones' }
254
+ let(:zone1) { { id: 1, name: 'zone1' } }
255
+ let(:zone2) { { id: 2, name: 'zone2' } }
256
+ let(:zones) { [zone1, zone2] }
257
+
258
+ it 'lists available zones for a compute resource' do
259
+ api_expects(:compute_resources, :available_zones, 'zones').with_params(
260
+ 'id' => '1'
261
+ ).returns(index_response(zones))
262
+
263
+ output = IndexMatcher.new(
264
+ [
265
+ %w[ID NAME],
266
+ %w[1 zone1],
267
+ %w[2 zone2]
268
+ ]
269
+ )
270
+ expected_result = success_result(output)
271
+
272
+ result = run_cmd(cmd + base_params)
273
+ assert_cmd(expected_result, result)
274
+ end
275
+ end
276
+
277
+ describe 'resource_pools' do
278
+ let(:cmd) { base_cmd << 'resource-pools' }
279
+ let(:params) { base_params + ['--cluster-id=1'] }
280
+ let(:resource_pool1) { { id: 1, name: 'resource_pool1' } }
281
+ let(:resource_pool2) { { id: 2, name: 'resource_pool2' } }
282
+ let(:resource_pools) { [resource_pool1, resource_pool2] }
283
+
284
+ it 'lists available resource_pools for a compute resource' do
285
+ api_expects(:compute_resources, :available_resource_pools, 'resource-pools').with_params(
286
+ 'id' => '1', 'cluster_id' => '1'
287
+ ).returns(index_response(resource_pools))
288
+
289
+ output = IndexMatcher.new(
290
+ [
291
+ %w[ID NAME],
292
+ %w[1 resource_pool1],
293
+ %w[2 resource_pool2]
294
+ ]
295
+ )
296
+ expected_result = success_result(output)
297
+
298
+ result = run_cmd(cmd + params)
299
+ assert_cmd(expected_result, result)
300
+ end
301
+ end
302
+
303
+ describe 'storage_domains' do
304
+ let(:cmd) { base_cmd << 'storage-domains' }
305
+ let(:storage_domain1) { { id: 1, name: 'storage_domain1' } }
306
+ let(:storage_domain2) { { id: 2, name: 'storage_domain2' } }
307
+ let(:storage_domains) { [storage_domain1, storage_domain2] }
308
+
309
+ it 'lists available storage_domains for a compute resource' do
310
+ api_expects(:compute_resources, :available_storage_domains, 'storage-domains').with_params(
311
+ 'id' => '1'
312
+ ).returns(index_response(storage_domains))
313
+
314
+ output = IndexMatcher.new(
315
+ [
316
+ %w[ID NAME],
317
+ %w[1 storage_domain1],
318
+ %w[2 storage_domain2]
319
+ ]
320
+ )
321
+ expected_result = success_result(output)
322
+
323
+ result = run_cmd(cmd + base_params)
324
+ assert_cmd(expected_result, result)
325
+ end
326
+ end
327
+
328
+ describe 'storage_pods' do
329
+ let(:cmd) { base_cmd << 'storage-pods' }
330
+ let(:storage_pod1) { { id: 1, name: 'storage_pod1' } }
331
+ let(:storage_pod2) { { id: 2, name: 'storage_pod2' } }
332
+ let(:storage_pods) { [storage_pod1, storage_pod2] }
333
+
334
+ it 'lists available storage_pods for a compute resource' do
335
+ api_expects(:compute_resources, :available_storage_pods, 'storage-pods').with_params(
336
+ 'id' => '1'
337
+ ).returns(index_response(storage_pods))
338
+
339
+ output = IndexMatcher.new(
340
+ [
341
+ %w[ID NAME],
342
+ %w[1 storage_pod1],
343
+ %w[2 storage_pod2]
344
+ ]
345
+ )
346
+ expected_result = success_result(output)
347
+
348
+ result = run_cmd(cmd + base_params)
349
+ assert_cmd(expected_result, result)
350
+ end
351
+ end
352
+
353
+ describe 'security_groups' do
354
+ let(:cmd) { base_cmd << 'security-groups' }
355
+ let(:security_group1) { { id: 1, name: 'security_group1' } }
356
+ let(:security_group2) { { id: 2, name: 'security_group2' } }
357
+ let(:security_groups) { [security_group1, security_group2] }
358
+
359
+ it 'lists available security_groups for a compute resource' do
360
+ api_expects(:compute_resources, :available_security_groups, 'security-groups').with_params(
361
+ 'id' => '1'
362
+ ).returns(index_response(security_groups))
363
+
364
+ output = IndexMatcher.new(
365
+ [
366
+ %w[ID NAME],
367
+ %w[1 security_group1],
368
+ %w[2 security_group2]
369
+ ]
370
+ )
371
+ expected_result = success_result(output)
372
+
373
+ result = run_cmd(cmd + base_params)
374
+ assert_cmd(expected_result, result)
375
+ end
376
+ end
117
377
  end