morpheus-cli 4.1.5 → 4.1.6

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.
@@ -0,0 +1,708 @@
1
+ require 'rest_client'
2
+ require 'optparse'
3
+ require 'filesize'
4
+ require 'morpheus/cli/cli_command'
5
+ require 'morpheus/cli/mixins/infrastructure_helper'
6
+
7
+ class Morpheus::Cli::SubnetsCommand
8
+ include Morpheus::Cli::CliCommand
9
+ include Morpheus::Cli::InfrastructureHelper
10
+
11
+ set_command_name :subnets
12
+
13
+ register_subcommands :list, :get, :add, :update, :remove
14
+ # register_subcommands :'types' => :list_subnet_types
15
+ register_subcommands :'types' => :list_subnet_types
16
+ register_subcommands :'get-type' => :get_subnet_type
17
+
18
+ # set_default_subcommand :list
19
+
20
+ def initialize()
21
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
22
+ end
23
+
24
+ def connect(opts)
25
+ @api_client = establish_remote_appliance_connection(opts)
26
+ @networks_interface = @api_client.networks
27
+ @network_types_interface = @api_client.network_types
28
+ @subnets_interface = @api_client.subnets
29
+ @subnet_types_interface = @api_client.subnet_types
30
+ @clouds_interface = @api_client.clouds
31
+ @options_interface = @api_client.options
32
+ end
33
+
34
+ def handle(args)
35
+ handle_subcommand(args)
36
+ end
37
+
38
+ def list(args)
39
+ options = {}
40
+ params = {}
41
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
42
+ opts.banner = subcommand_usage("")
43
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
44
+ opts.on( '--network NETWORK', '--network NETWORK', "Filter results to a specific network" ) do |val|
45
+ options[:network] = val
46
+ end
47
+ opts.footer = "List subnets."
48
+ end
49
+ optparse.parse!(args)
50
+ if args.count > 0
51
+ raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args}\n#{optparse}"
52
+ end
53
+ connect(options)
54
+
55
+ params.merge!(parse_list_options(options))
56
+ network = nil
57
+ if options[:network]
58
+ network = find_network_by_name_or_id(options[:network])
59
+ if network
60
+ params['networkId'] = network['id']
61
+ else
62
+ return 1, "Network not found"
63
+ end
64
+ # params['networksId'] = params.delete('networkId')
65
+ end
66
+
67
+ exit_code, err = 0, nil
68
+
69
+ @subnets_interface.setopts(options)
70
+ if options[:dry_run]
71
+ print_dry_run @subnets_interface.dry.list(params)
72
+ return exit_code, err
73
+ end
74
+ json_response = @subnets_interface.list(params)
75
+ subnets = json_response["subnets"]
76
+
77
+ render_result = render_with_format(json_response, options, 'subnets')
78
+ return exit_code, err if render_result
79
+
80
+ title = "Morpheus Subnets"
81
+ subtitles = []
82
+ if network
83
+ subtitles << "Network: #{network['name']}"
84
+ end
85
+ subtitles += parse_list_subtitles(options)
86
+ print_h1 title, subtitles
87
+
88
+ if subnets.empty?
89
+ print cyan,"No subnets found.",reset,"\n"
90
+ else
91
+ subnet_columns = {
92
+ "ID" => 'id',
93
+ "Name" => 'name',
94
+ #"Description" => 'description',
95
+ "Network" => lambda {|it| it['network']['name'] rescue it['network'] },
96
+ "Type" => lambda {|it| it['type']['name'] rescue it['type'] },
97
+ "Cloud" => lambda {|it| it['zone']['name'] rescue it['zone'] },
98
+ "CIDR" => lambda {|it| it['cidr'] },
99
+ "DHCP" => lambda {|it| format_boolean(it['dhcpServer']) },
100
+ "Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
101
+ "Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' }
102
+ }
103
+ print cyan
104
+ print as_pretty_table(subnets, subnet_columns)
105
+ print_results_pagination(json_response, {:label => "subnet", :n_label => "subnets"})
106
+ end
107
+ print reset,"\n"
108
+ return exit_code, err
109
+
110
+ end
111
+
112
+
113
+ def get(args)
114
+ options = {}
115
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
116
+ opts.banner = subcommand_usage("[network] [subnet]")
117
+ build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
118
+ opts.footer = "Get details about a subnet." + "\n" +
119
+ "[subnet] is required. This is the name or id of a subnet."
120
+ end
121
+ optparse.parse!(args)
122
+ if args.count != 1
123
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
124
+ end
125
+ connect(options)
126
+ begin
127
+ subnet_id = nil
128
+ if args[0].to_s =~ /\A\d{1,}\Z/
129
+ subnet_id = args[0].to_i
130
+ else
131
+ subnet = find_subnet_by_name(args[0])
132
+ return 1, "Security Group not found" if subnet.nil?
133
+ subnet_id = subnet['id']
134
+ end
135
+ @subnets_interface.setopts(options)
136
+ if options[:dry_run]
137
+ print_dry_run @subnets_interface.dry.get(subnet_id)
138
+ return exit_code, err
139
+ end
140
+ json_response = @subnets_interface.get(subnet_id)
141
+ render_result = render_with_format(json_response, options, 'subnet')
142
+ return exit_code, err if render_result
143
+
144
+ subnet = json_response['subnet']
145
+ if options[:json]
146
+ puts as_json(json_response, options, "subnet")
147
+ return 0
148
+ elsif options[:yaml]
149
+ puts as_yaml(json_response, options, "subnet")
150
+ return 0
151
+ elsif options[:csv]
152
+ puts records_as_csv([subnet], options)
153
+ return 0
154
+ end
155
+ print_h1 "Subnet Details", [], options
156
+ print cyan
157
+ description_cols = {
158
+ "ID" => 'id',
159
+ "Name" => 'name',
160
+ "Description" => 'description',
161
+ "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
162
+ "Network" => lambda {|it| subnet['network']['name'] rescue subnet['network'] },
163
+ "Cloud" => lambda {|it| subnet['zone']['name'] rescue subnet['zone'] },
164
+ "CIDR" => 'cidr',
165
+ "Gateway" => 'gateway',
166
+ "Netmask" => 'netmask',
167
+ "Subnet" => 'subnetAddress',
168
+ "Primary DNS" => 'dnsPrimary',
169
+ "Secondary DNS" => 'dnsSecondary',
170
+ "Pool" => lambda {|it| it['pool'] ? it['pool']['name'] : '' },
171
+ "DHCP" => lambda {|it| format_boolean it['dhcpServer'] },
172
+ #"Allow IP Override" => lambda {|it| it['allowStaticOverride'] ? 'Yes' : 'No' },
173
+ "Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
174
+ "Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' },
175
+ # "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
176
+ }
177
+ print_description_list(description_cols, subnet)
178
+
179
+ if subnet['resourcePermission'].nil?
180
+ print "\n", "No group access found", "\n"
181
+ else
182
+ print_h2 "Group Access"
183
+ rows = []
184
+ if subnet['resourcePermission']['all']
185
+ rows.push({"name" => 'All'})
186
+ end
187
+ if subnet['resourcePermission']['sites']
188
+ subnet['resourcePermission']['sites'].each do |site|
189
+ rows.push(site)
190
+ end
191
+ end
192
+ rows = rows.collect do |site|
193
+ {group: site['name'], default: site['default'] ? 'Yes' : ''}
194
+ end
195
+ columns = [:group, :default]
196
+ print cyan
197
+ print as_pretty_table(rows, columns)
198
+ end
199
+
200
+ print reset,"\n"
201
+ return 0
202
+ rescue RestClient::Exception => e
203
+ print_rest_exception(e, options)
204
+ return 1
205
+ end
206
+ end
207
+
208
+ def add(args)
209
+ options = {}
210
+ network_id = nil
211
+ subnet_type_id = nil
212
+ tenants = nil
213
+ group_access_all = nil
214
+ group_access_list = nil
215
+ group_defaults_list = nil
216
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
217
+ opts.banner = subcommand_usage("[name] --network NETWORK")
218
+ opts.on('--network NETWORK', String, "Network name or ID that this subnet will be a part of.") do |val|
219
+ network_id = val
220
+ end
221
+ opts.on('-t', '--type ID', "Subnet Type Name or ID") do |val|
222
+ subnet_type_id = val
223
+ end
224
+ opts.on('--name VALUE', String, "Name for this subnet") do |val|
225
+ options[:options]['name'] = val
226
+ # fill in silly names that vary by type
227
+ options[:options].deep_merge!({'config' => {'subnetName' => val}})
228
+ end
229
+ opts.on('--cidr VALUE', String, "Name for this subnet") do |val|
230
+ options[:options]['cidr'] = val
231
+ # fill in silly names that vary by type
232
+ options[:options].deep_merge!({'config' => {'subnetCidr' => val}})
233
+ end
234
+ opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
235
+ group_access_all = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
236
+ end
237
+ opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
238
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
239
+ group_access_list = []
240
+ else
241
+ group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
242
+ end
243
+ end
244
+ opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
245
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
246
+ group_defaults_list = []
247
+ else
248
+ group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
249
+ end
250
+ end
251
+ opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
252
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
253
+ options['tenants'] = []
254
+ else
255
+ options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
256
+ end
257
+ end
258
+ opts.on('--accounts LIST', Array, "alias for --tenants") do |list|
259
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
260
+ options['tenants'] = []
261
+ else
262
+ options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
263
+ end
264
+ end
265
+ opts.on('--visibility [private|public]', String, "Visibility") do |val|
266
+ options['visibility'] = val
267
+ end
268
+ # opts.on('--active [on|off]', String, "Can be used to disable a subnet") do |val|
269
+ # options['active'] = val.to_s == 'on' || val.to_s == 'true'
270
+ # end
271
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
272
+ opts.footer = "Create a new subnet." + "\n" +
273
+ "--network is required. This is the name or id of a network." #+ "\n" +
274
+ #"[name] is required and can be passed as --name instead."
275
+ end
276
+ optparse.parse!(args)
277
+ # if args.count < 1 || args.count > 2
278
+ if args.count > 1
279
+ raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args}\n#{optparse}"
280
+ end
281
+ if args[1]
282
+ options[:options]['name'] = args[1]
283
+ end
284
+ connect(options)
285
+ begin
286
+ passed_options = (options[:options] || {}).reject {|k,v| k.is_a?(Symbol) }
287
+ payload = nil
288
+ if options[:payload]
289
+ payload = options[:payload]
290
+ payload.deep_merge!({'subnet' => passed_options}) unless passed_options.empty?
291
+
292
+ else
293
+ payload = {'subnet' => {}}
294
+ payload.deep_merge!({'subnet' => passed_options}) unless passed_options.empty?
295
+
296
+ # Network
297
+ prompt_results = prompt_for_network(network_id, options)
298
+ if prompt_results[:success]
299
+ network = prompt_results[:network]
300
+ else
301
+ return 1, "Network prompt failed."
302
+ end
303
+
304
+ # Name
305
+ # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this subnet.'}], options[:options])
306
+ # payload['subnet']['name'] = v_prompt['name']
307
+
308
+ # Subnet Type
309
+ if !subnet_type_id
310
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Subnet Type', 'type' => 'select', 'optionSource' => 'subnetTypes', 'required' => true, 'description' => 'Choose a subnet type.'}], options[:options], @api_client, {networkId: network['id']})
311
+ subnet_type_id = v_prompt['type']
312
+ end
313
+ subnet_type = find_subnet_type_by_name_or_id(subnet_type_id)
314
+ return 1 if subnet_type.nil?
315
+ payload['subnet']['type'] = {'id' => subnet_type['id'] }
316
+ #payload['subnet']['type'] = {'code' => subnet_type['code'] }
317
+
318
+ subnet_type_option_types = subnet_type['optionTypes']
319
+ if subnet_type_option_types && subnet_type_option_types.size > 0
320
+ # prompt for option types
321
+ subnet_type_params = Morpheus::Cli::OptionTypes.prompt(subnet_type_option_types,options[:options],@api_client, {networkId: network['id']})
322
+ payload['subnet'].deep_merge!(subnet_type_params)
323
+
324
+ else
325
+ # DEFAULT INPUTS
326
+
327
+ # CIDR
328
+ # if options['cidr']
329
+ # payload['subnet']['cidr'] = options['cidr']
330
+ # else
331
+ # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cidr', 'fieldLabel' => 'CIDR', 'type' => 'text', 'required' => false, 'description' => ''}], options)
332
+ # payload['subnet']['cidr'] = v_prompt['cidr']
333
+ # end
334
+
335
+ end
336
+
337
+ # Group Access
338
+ # Group Access (default is All)
339
+ if group_access_all.nil?
340
+ if payload['resourcePermissions'].nil?
341
+ payload['resourcePermissions'] ||= {}
342
+ payload['resourcePermissions']['all'] = true
343
+ end
344
+ else
345
+ payload['resourcePermissions'] ||= {}
346
+ payload['resourcePermissions']['all'] = group_access_all
347
+ end
348
+ if group_access_list != nil
349
+ payload['resourcePermissions'] ||= {}
350
+ payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
351
+ site = {"id" => site_id.to_i}
352
+ if group_defaults_list && group_defaults_list.include?(site_id)
353
+ site["default"] = true
354
+ end
355
+ site
356
+ end
357
+ end
358
+
359
+ # Tenants
360
+ if options['tenants']
361
+ payload['tenantPermissions'] = {}
362
+ payload['tenantPermissions']['accounts'] = options['tenants']
363
+ end
364
+
365
+ # Active
366
+ if options['active'] != nil
367
+ payload['subnet']['active'] = options['active']
368
+ end
369
+
370
+ # Visibility
371
+ if options['visibility'] != nil
372
+ payload['subnet']['visibility'] = options['visibility']
373
+ end
374
+
375
+ end
376
+
377
+ @subnets_interface.setopts(options)
378
+ if options[:dry_run]
379
+ print_dry_run @subnets_interface.dry.create(network['id'], payload)
380
+ return
381
+ end
382
+ json_response = @subnets_interface.create(network['id'], payload)
383
+ if options[:json]
384
+ puts as_json(json_response, options)
385
+ elsif !options[:quiet]
386
+ subnet = json_response['subnet']
387
+ print_green_success "Added subnet #{subnet['name']}"
388
+ get_args = [network['id'], subnet['id']] + (options[:remote] ? ["-r",options[:remote]] : [])
389
+ get(get_args)
390
+ end
391
+ return 0
392
+ rescue RestClient::Exception => e
393
+ print_rest_exception(e, options)
394
+ return 1
395
+ end
396
+ end
397
+
398
+
399
+ def update(args)
400
+ options = {}
401
+ tenants = nil
402
+ group_access_all = nil
403
+ group_access_list = nil
404
+ group_defaults_list = nil
405
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
406
+ opts.banner = subcommand_usage("[subnet]")
407
+ opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
408
+ group_access_all = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
409
+ end
410
+ opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
411
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
412
+ group_access_list = []
413
+ else
414
+ group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
415
+ end
416
+ end
417
+ opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
418
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
419
+ group_defaults_list = []
420
+ else
421
+ group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
422
+ end
423
+ end
424
+ opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
425
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
426
+ options['tenants'] = []
427
+ else
428
+ options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
429
+ end
430
+ end
431
+ opts.on('--accounts LIST', Array, "alias for --tenants") do |list|
432
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
433
+ options['tenants'] = []
434
+ else
435
+ options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
436
+ end
437
+ end
438
+ opts.on('--visibility [private|public]', String, "Visibility") do |val|
439
+ options['visibility'] = val
440
+ end
441
+ # opts.on('--active [on|off]', String, "Can be used to disable a network") do |val|
442
+ # options['active'] = val.to_s == 'on' || val.to_s == 'true'
443
+ # end
444
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
445
+ opts.footer = "Update a subnet." + "\n" +
446
+ "[subnet] is required. This is the name or id of a subnet."
447
+ end
448
+ optparse.parse!(args)
449
+ if args.count != 1
450
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
451
+ end
452
+ connect(options)
453
+ begin
454
+ network = find_network_by_name_or_id(args[0])
455
+ return 1 if network.nil?
456
+
457
+ subnet = find_subnet_by_name_or_id(network['id'], args[1])
458
+ return 1 if subnet.nil?
459
+
460
+ # merge -O options into normally parsed options
461
+ options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
462
+
463
+ # construct payload
464
+ payload = nil
465
+ if options[:payload]
466
+ payload = options[:payload]
467
+ else
468
+ # prompt for network options
469
+ payload = {
470
+ 'subnet' => {
471
+ }
472
+ }
473
+
474
+ # allow arbitrary -O options
475
+ payload['subnet'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
476
+
477
+ # Group Access
478
+ if group_access_all != nil
479
+ payload['resourcePermissions'] ||= {}
480
+ payload['resourcePermissions']['all'] = group_access_all
481
+ end
482
+ if group_access_list != nil
483
+ payload['resourcePermissions'] ||= {}
484
+ payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
485
+ site = {"id" => site_id.to_i}
486
+ if group_defaults_list && group_defaults_list.include?(site_id)
487
+ site["default"] = true
488
+ end
489
+ site
490
+ end
491
+ end
492
+
493
+ # Tenants
494
+ if options['tenants']
495
+ payload['tenantPermissions'] = {}
496
+ payload['tenantPermissions']['accounts'] = options['tenants']
497
+ end
498
+
499
+ # Active
500
+ if options['active'] != nil
501
+ payload['subnet']['active'] = options['active']
502
+ end
503
+
504
+ # Visibility
505
+ if options['visibility'] != nil
506
+ payload['subnet']['visibility'] = options['visibility']
507
+ end
508
+
509
+ end
510
+
511
+ @subnets_interface.setopts(options)
512
+ if options[:dry_run]
513
+ print_dry_run @subnets_interface.dry.update(network['id'], subnet['id'], payload)
514
+ return
515
+ end
516
+ json_response = @subnets_interface.update(network['id'], subnet['id'], payload)
517
+ if options[:json]
518
+ puts as_json(json_response, options)
519
+ elsif !options[:quiet]
520
+ subnet = json_response['subnet']
521
+ print_green_success "Updated subnet #{subnet['name']}"
522
+ get_args = [network['id'], subnet['id']] + (options[:remote] ? ["-r",options[:remote]] : [])
523
+ get(get_args)
524
+ end
525
+ return 0
526
+ rescue RestClient::Exception => e
527
+ print_rest_exception(e, options)
528
+ return 1
529
+ end
530
+ end
531
+
532
+ def remove(args)
533
+ options = {}
534
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
535
+ opts.banner = subcommand_usage("[subnet]")
536
+ build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
537
+ opts.footer = "Delete a subnet." + "\n" +
538
+ "[subnet] is required. This is the name or id of a subnet."
539
+ end
540
+ optparse.parse!(args)
541
+ if args.count != 1
542
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
543
+ end
544
+ connect(options)
545
+ begin
546
+ subnet = find_subnet_by_name_or_id(args[0])
547
+ return 1 if subnet.nil?
548
+
549
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the subnet: #{subnet['name']}?")
550
+ return 9, "aborted command"
551
+ end
552
+ @subnets_interface.setopts(options)
553
+ if options[:dry_run]
554
+ print_dry_run @subnets_interface.dry.destroy(subnet['id'])
555
+ return 0
556
+ end
557
+ json_response = @subnets_interface.destroy(subnet['id'])
558
+ if options[:json]
559
+ puts as_json(json_response, options)
560
+ else
561
+ print_green_success "Removed subnet #{subnet['name']}"
562
+ end
563
+ return 0
564
+ rescue RestClient::Exception => e
565
+ print_rest_exception(e, options)
566
+ return 1
567
+ end
568
+ end
569
+
570
+ def get_subnet_type(args)
571
+ options = {}
572
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
573
+ opts.banner = subcommand_usage("[type]")
574
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
575
+ opts.footer = "Get details about a subnet type.\n" +
576
+ "[type] is required. This is the id or name of a subnet type."
577
+ end
578
+ optparse.parse!(args)
579
+ connect(options)
580
+ begin
581
+ params = {}
582
+ @subnet_types_interface.setopts(options)
583
+ if options[:dry_run]
584
+ if args[0].to_s =~ /\A\d{1,}\Z/
585
+ print_dry_run @subnet_types_interface.dry.get(args[0].to_i)
586
+ else
587
+ print_dry_run @subnet_types_interface.dry.list({name:args[0]})
588
+ end
589
+ return
590
+ end
591
+
592
+ subnet_type = find_subnet_type_by_name_or_id(args[0])
593
+ return 1 if subnet_type.nil?
594
+ json_response = {'subnetType' => subnet_type} # skip redundant request
595
+ # json_response = @networks_interface.get(subnet_type['id'])
596
+
597
+ render_result = render_with_format(json_response, options, 'subnetType')
598
+ return 0 if render_result
599
+
600
+ subnet_type = json_response['subnetType']
601
+
602
+ title = "Morpheus Subnet Type"
603
+
604
+ print_h1 "Morpheus Subnet Type", [], options
605
+
606
+ print cyan
607
+ description_cols = {
608
+ "ID" => 'id',
609
+ "Name" => 'name',
610
+ "Code" => 'name',
611
+ "Description" => 'description',
612
+ "Createable" => lambda {|it| format_boolean(it['creatable']) },
613
+ "Deletable" => lambda {|it| format_boolean(it['deleteable']) },
614
+ }
615
+ print_description_list(description_cols, subnet_type)
616
+
617
+
618
+
619
+ option_types = subnet_type['optionTypes'] || []
620
+ option_types = option_types.sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
621
+ if !option_types.empty?
622
+ print_h2 "Config Option Types", [], options
623
+ option_type_cols = {
624
+ "Name" => lambda {|it| it['fieldContext'].to_s != '' ? "#{it['fieldContext']}.#{it['fieldName']}" : it['fieldName'] },
625
+ "Label" => lambda {|it| it['fieldLabel'] },
626
+ "Type" => lambda {|it| it['type'] },
627
+ }
628
+ print cyan
629
+ print as_pretty_table(option_types, option_type_cols)
630
+ end
631
+
632
+ print reset,"\n"
633
+ return 0
634
+ rescue RestClient::Exception => e
635
+ print_rest_exception(e, options)
636
+ exit 1
637
+ end
638
+ end
639
+
640
+ def list_subnet_types(args)
641
+ options = {}
642
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
643
+ opts.banner = subcommand_usage()
644
+ opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
645
+ options[:cloud] = val
646
+ end
647
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
648
+ opts.footer = "List subnet types."
649
+ end
650
+ optparse.parse!(args)
651
+ connect(options)
652
+ begin
653
+ params = {}
654
+ params.merge!(parse_list_options(options))
655
+ if options[:cloud]
656
+ #return network_types_for_cloud(options[:cloud], options)
657
+ zone = find_zone_by_name_or_id(nil, options[:cloud])
658
+ #params["zoneTypeId"] = zone['zoneTypeId']
659
+ params["zoneId"] = zone['id']
660
+ params["creatable"] = true
661
+ end
662
+ @subnet_types_interface.setopts(options)
663
+ if options[:dry_run]
664
+ print_dry_run @subnet_types_interface.dry.list(params)
665
+ return
666
+ end
667
+ json_response = @subnet_types_interface.list(params)
668
+
669
+ render_result = render_with_format(json_response, options, 'subnetTypes')
670
+ return 0 if render_result
671
+
672
+ subnet_types = json_response['subnetTypes']
673
+
674
+ title = "Morpheus Subnet Types"
675
+ subtitles = []
676
+ subtitles += parse_list_subtitles(options)
677
+ if options[:cloud]
678
+ subtitles << "Cloud: #{options[:cloud]}"
679
+ end
680
+ print_h1 title, subtitles
681
+ if subnet_types.empty?
682
+ print cyan,"No subnet types found.",reset,"\n"
683
+ else
684
+ rows = subnet_types.collect do |subnet_type|
685
+ {
686
+ id: subnet_type['id'],
687
+ code: subnet_type['code'],
688
+ name: subnet_type['name']
689
+ }
690
+ end
691
+ columns = [:id, :name, :code]
692
+ print cyan
693
+ print as_pretty_table(rows, columns, options)
694
+ print reset
695
+ print_results_pagination(json_response)
696
+ end
697
+ print reset,"\n"
698
+ return 0
699
+
700
+ rescue RestClient::Exception => e
701
+ print_rest_exception(e, options)
702
+ exit 1
703
+ end
704
+ end
705
+
706
+ private
707
+
708
+ end