morpheus-cli 2.12.5 → 3.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +5 -0
  3. data/lib/morpheus/api/api_client.rb +15 -30
  4. data/lib/morpheus/api/app_templates_interface.rb +34 -7
  5. data/lib/morpheus/api/apps_interface.rb +20 -1
  6. data/lib/morpheus/api/archive_buckets_interface.rb +124 -0
  7. data/lib/morpheus/api/archive_files_interface.rb +182 -0
  8. data/lib/morpheus/api/{network_pools_interface.rb → image_builder_boot_scripts_interface.rb} +6 -6
  9. data/lib/morpheus/api/{policies_interface.rb → image_builder_image_builds_interface.rb} +20 -15
  10. data/lib/morpheus/api/image_builder_interface.rb +26 -0
  11. data/lib/morpheus/api/{network_proxies_interface.rb → image_builder_preseed_scripts_interface.rb} +6 -6
  12. data/lib/morpheus/cli.rb +10 -9
  13. data/lib/morpheus/cli/alias_command.rb +10 -9
  14. data/lib/morpheus/cli/app_templates.rb +1566 -457
  15. data/lib/morpheus/cli/apps.rb +284 -108
  16. data/lib/morpheus/cli/archives_command.rb +2184 -0
  17. data/lib/morpheus/cli/boot_scripts_command.rb +382 -0
  18. data/lib/morpheus/cli/cli_command.rb +9 -35
  19. data/lib/morpheus/cli/error_handler.rb +2 -0
  20. data/lib/morpheus/cli/hosts.rb +15 -3
  21. data/lib/morpheus/cli/image_builder_command.rb +1208 -0
  22. data/lib/morpheus/cli/instances.rb +118 -47
  23. data/lib/morpheus/cli/man_command.rb +27 -24
  24. data/lib/morpheus/cli/mixins/print_helper.rb +19 -5
  25. data/lib/morpheus/cli/mixins/provisioning_helper.rb +20 -20
  26. data/lib/morpheus/cli/option_types.rb +45 -14
  27. data/lib/morpheus/cli/preseed_scripts_command.rb +381 -0
  28. data/lib/morpheus/cli/remote.rb +1 -0
  29. data/lib/morpheus/cli/roles.rb +2 -2
  30. data/lib/morpheus/cli/shell.rb +3 -2
  31. data/lib/morpheus/cli/version.rb +1 -1
  32. data/lib/morpheus/ext/hash.rb +22 -0
  33. data/lib/morpheus/formatters.rb +33 -0
  34. data/lib/morpheus/terminal.rb +1 -1
  35. metadata +13 -21
  36. data/lib/morpheus/api/cloud_policies_interface.rb +0 -47
  37. data/lib/morpheus/api/group_policies_interface.rb +0 -47
  38. data/lib/morpheus/api/network_domains_interface.rb +0 -47
  39. data/lib/morpheus/api/network_groups_interface.rb +0 -47
  40. data/lib/morpheus/api/network_pool_servers_interface.rb +0 -47
  41. data/lib/morpheus/api/network_services_interface.rb +0 -47
  42. data/lib/morpheus/api/networks_interface.rb +0 -54
  43. data/lib/morpheus/cli/network_domains_command.rb +0 -571
  44. data/lib/morpheus/cli/network_groups_command.rb +0 -602
  45. data/lib/morpheus/cli/network_pool_servers_command.rb +0 -430
  46. data/lib/morpheus/cli/network_pools_command.rb +0 -495
  47. data/lib/morpheus/cli/network_proxies_command.rb +0 -594
  48. data/lib/morpheus/cli/network_services_command.rb +0 -148
  49. data/lib/morpheus/cli/networks_command.rb +0 -855
  50. data/lib/morpheus/cli/policies_command.rb +0 -847
  51. data/scripts/generate_morpheus_commands_help.morpheus +0 -1313
@@ -1,430 +0,0 @@
1
- require 'rest_client'
2
- require 'optparse'
3
- require 'filesize'
4
- require 'table_print'
5
- require 'morpheus/cli/cli_command'
6
- require 'morpheus/cli/mixins/infrastructure_helper'
7
-
8
- class Morpheus::Cli::NetworkPoolServersCommand
9
- include Morpheus::Cli::CliCommand
10
- include Morpheus::Cli::InfrastructureHelper
11
-
12
- set_command_name :'network-pool-servers'
13
-
14
- register_subcommands :list, :get, :add, :update, :remove
15
-
16
- # set_default_subcommand :list
17
-
18
- def initialize()
19
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
20
- end
21
-
22
- def connect(opts)
23
- @api_client = establish_remote_appliance_connection(opts)
24
- @network_pool_servers_interface = @api_client.network_pool_servers
25
- @clouds_interface = @api_client.clouds
26
- @options_interface = @api_client.options
27
- end
28
-
29
- def handle(args)
30
- handle_subcommand(args)
31
- end
32
-
33
- def list(args)
34
- options = {}
35
- params = {}
36
- optparse = Morpheus::Cli::OptionParser.new do |opts|
37
- opts.banner = subcommand_usage()
38
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
39
- opts.footer = "List network pool servers."
40
- end
41
- optparse.parse!(args)
42
- connect(options)
43
- begin
44
- [:phrase, :offset, :max, :sort, :direction].each do |k|
45
- params[k] = options[k] unless options[k].nil?
46
- end
47
- if options[:dry_run]
48
- print_dry_run @network_pool_servers_interface.dry.list(params)
49
- return
50
- end
51
- json_response = @network_pool_servers_interface.list(params)
52
- network_pool_servers = json_response["networkPoolServers"]
53
- if options[:include_fields]
54
- json_response = {"networkPoolServers" => filter_data(network_pool_servers, options[:include_fields]) }
55
- end
56
- if options[:json]
57
- puts as_json(json_response, options)
58
- return 0
59
- elsif options[:yaml]
60
- puts as_yaml(json_response, options)
61
- return 0
62
- elsif options[:csv]
63
- puts records_as_csv(network_pool_servers, options)
64
- return 0
65
- end
66
- title = "Morpheus Network Pool Servers"
67
- subtitles = []
68
- if params[:phrase]
69
- subtitles << "Search: #{params[:phrase]}".strip
70
- end
71
- print_h1 title, subtitles
72
- if network_pool_servers.empty?
73
- print cyan,"No network pool servers found.",reset,"\n"
74
- else
75
- rows = network_pool_servers.collect {|network_pool_server|
76
- row = {
77
- id: network_pool_server['id'],
78
- name: network_pool_server['name'],
79
- # description: network_pool_server['description'],
80
- type: network_pool_server['type'] ? network_pool_server['type']['name'] : '',
81
- pools: network_pool_server['pools'] ? network_pool_server['pools'].collect {|it| it['name'] }.uniq.join(', ') : '',
82
- }
83
- row
84
- }
85
- columns = [:id, :name, :type, :pools]
86
- if options[:include_fields]
87
- columns = options[:include_fields]
88
- end
89
- print cyan
90
- print as_pretty_table(rows, columns, options)
91
- print reset
92
- print_results_pagination(json_response, {:label => "network pool server", :n_label => "network pool servers"})
93
- end
94
- print reset,"\n"
95
- return 0
96
- rescue RestClient::Exception => e
97
- print_rest_exception(e, options)
98
- exit 1
99
- end
100
- end
101
-
102
- def get(args)
103
- options = {}
104
- optparse = Morpheus::Cli::OptionParser.new do |opts|
105
- opts.banner = subcommand_usage("[network-pool-server]")
106
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
107
- opts.footer = "Get details about a network pool server." + "\n" +
108
- "[network-pool-server] is required. This is the name or id of a network pool server."
109
- end
110
- optparse.parse!(args)
111
- if args.count != 1
112
- print_error Morpheus::Terminal.angry_prompt
113
- puts_error "#{command_name} missing argument: [network-pool-server]\n#{optparse}"
114
- return 1
115
- end
116
- connect(options)
117
- begin
118
- if options[:dry_run]
119
- if args[0].to_s =~ /\A\d{1,}\Z/
120
- print_dry_run @network_pool_servers_interface.dry.get(args[0].to_i)
121
- else
122
- print_dry_run @network_pool_servers_interface.dry.list({name:args[0]})
123
- end
124
- return
125
- end
126
- network_pool_server = find_network_pool_server_by_name_or_id(args[0])
127
- return 1 if network_pool_server.nil?
128
- json_response = {'networkPoolServer' => network_pool_server} # skip redundant request
129
- # json_response = @network_pool_servers_interface.get(network_pool_server['id'])
130
- network_pool_server = json_response['networkPoolServer']
131
- if options[:include_fields]
132
- json_response = {'networkPoolServer' => filter_data(network_pool_server, options[:include_fields]) }
133
- end
134
- if options[:json]
135
- puts as_json(json_response, options)
136
- return 0
137
- elsif options[:yaml]
138
- puts as_yaml(json_response, options)
139
- return 0
140
- elsif options[:csv]
141
- puts records_as_csv([network_pool_server], options)
142
- return 0
143
- end
144
- print_h1 "Network Pool Server Details"
145
- print cyan
146
- description_cols = {
147
- "ID" => 'id',
148
- "Name" => lambda {|it| it['name'] },
149
- "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
150
- # "Service URL" => lambda {|it| it['serviceUrl'] : '' },
151
- "Pools" => lambda {|it| it['pools'] ? it['pools'].collect {|p| p['name'] }.uniq.join(', ') : '' },
152
- }
153
- print_description_list(description_cols, network_pool_server)
154
- print reset,"\n"
155
- return 0
156
- rescue RestClient::Exception => e
157
- print_rest_exception(e, options)
158
- return 1
159
- end
160
- end
161
-
162
- def add(args)
163
- options = {}
164
- ip_range_list = nil
165
- optparse = Morpheus::Cli::OptionParser.new do |opts|
166
- opts.banner = subcommand_usage()
167
- opts.on('--name VALUE', String, "Name for this network pool server") do |val|
168
- options['name'] = val
169
- end
170
- opts.on('--type VALUE', String, "Type of network pool server") do |val|
171
- options['type'] = val
172
- end
173
- # ['name', 'serviceUsername', 'servicePassword', 'servicePort', 'serviceHost', 'serviceUrl', 'serviceMode', 'networkFilter', 'tenantMatch']
174
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
175
- opts.footer = "Create a new network pool server." + "\n" +
176
- "[name] is required and can be passed as --name instead."
177
- end
178
- optparse.parse!(args)
179
- if args.count > 1
180
- print_error Morpheus::Terminal.angry_prompt
181
- puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
182
- return 1
183
- end
184
- connect(options)
185
- begin
186
- # merge -O options into normally parsed options
187
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
188
-
189
- # support [name] as first argument
190
- if args[0]
191
- options['name'] = args[0]
192
- end
193
-
194
- # construct payload
195
- payload = nil
196
- if options[:payload]
197
- payload = options[:payload]
198
- else
199
- # prompt for network options
200
- payload = {
201
- 'networkPoolServer' => {
202
- # 'config' => {}
203
- }
204
- }
205
-
206
- # allow arbitrary -O options
207
- payload['networkPoolServer'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
208
-
209
- # Name
210
- if options['name']
211
- payload['networkPoolServer']['name'] = options['name']
212
- else
213
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network pool server.'}], options)
214
- payload['networkPoolServer']['name'] = v_prompt['name']
215
- end
216
-
217
- # Network Pool Server Type
218
- network_type_id = nil
219
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Pool Server Type', 'type' => 'select', 'optionSource' => 'networkPoolServerTypes', 'required' => true, 'description' => 'Choose a network pool server type.'}], options, @api_client, {})
220
- network_type_id = v_prompt['type']
221
- if network_type_id.nil? || network_type_id.to_s.empty?
222
- print_red_alert "Pool Server Type not found by id '#{options['type']}'"
223
- return 1
224
- end
225
- payload['networkPoolServer']['type'] = {'id' => network_type_id.to_i }
226
-
227
- # ['name', 'serviceUsername', 'servicePassword', 'servicePort', 'serviceHost', 'serviceUrl', 'serviceMode', 'networkFilter', 'tenantMatch']
228
-
229
- end
230
-
231
-
232
- if options[:dry_run]
233
- print_dry_run @network_pool_servers_interface.dry.create(payload)
234
- return
235
- end
236
- json_response = @network_pool_servers_interface.create(payload)
237
- if options[:json]
238
- print JSON.pretty_generate(json_response)
239
- print "\n"
240
- elsif !options[:quiet]
241
- network_pool_server = json_response['networkPoolServer']
242
- print_green_success "Added network pool server #{network_pool_server['name']}"
243
- get([network_pool_server['id']])
244
- end
245
- return 0
246
- rescue RestClient::Exception => e
247
- print_rest_exception(e, options)
248
- exit 1
249
- end
250
- end
251
-
252
- def update(args)
253
- options = {}
254
- ip_range_list = nil
255
- optparse = Morpheus::Cli::OptionParser.new do |opts|
256
- opts.banner = subcommand_usage("[network-pool-server] [options]")
257
- opts.on('--name VALUE', String, "Name for this network pool server") do |val|
258
- options['name'] = val
259
- end
260
- opts.on('--type VALUE', String, "Type of network pool server") do |val|
261
- options['description'] = val
262
- end
263
- # ['name', 'serviceUsername', 'servicePassword', 'servicePort', 'serviceHost', 'serviceUrl', 'serviceMode', 'networkFilter', 'tenantMatch']
264
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
265
- opts.footer = "Update a network pool server." + "\n" +
266
- "[network-pool-server] is required. This is the id of a network pool server."
267
- end
268
- optparse.parse!(args)
269
- if args.count != 1
270
- print_error Morpheus::Terminal.angry_prompt
271
- puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
272
- return 1
273
- end
274
- connect(options)
275
-
276
- begin
277
- network_pool_server = find_network_pool_server_by_name_or_id(args[0])
278
- return 1 if network_pool_server.nil?
279
-
280
- # merge -O options into normally parsed options
281
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
282
-
283
- # construct payload
284
- payload = nil
285
- if options[:payload]
286
- payload = options[:payload]
287
- else
288
- # prompt for network options
289
- payload = {
290
- 'networkPoolServer' => {
291
- }
292
- }
293
-
294
- # allow arbitrary -O options
295
- payload['networkPoolServer'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
296
-
297
- # Name
298
- if options['name']
299
- payload['networkPoolServer']['name'] = options['name']
300
- else
301
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network pool server.'}], options)
302
- # payload['networkPoolServer']['name'] = v_prompt['name']
303
- end
304
-
305
- # Network Pool Server Type
306
- # network_type_id = nil
307
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Pool Server Type', 'type' => 'select', 'optionSource' => 'networkPoolServerTypes', 'required' => true, 'description' => 'Choose a network pool server type.'}], options, @api_client, {})
308
- # network_type_id = v_prompt['type']
309
- # if network_type_id.nil? || network_type_id.to_s.empty?
310
- # print_red_alert "Pool Server Type not found by id '#{options['type']}'"
311
- # return 1
312
- # end
313
- # payload['networkPoolServer']['type'] = {'id' => network_type_id.to_i }
314
- if options['type']
315
- payload['networkPoolServer']['type'] = {'id' => options['type'].to_i }
316
- end
317
-
318
- # ['name', 'serviceUsername', 'servicePassword', 'servicePort', 'serviceHost', 'serviceUrl', 'serviceMode', 'networkFilter', 'tenantMatch']
319
-
320
- end
321
-
322
- if options[:dry_run]
323
- print_dry_run @network_pool_servers_interface.dry.update(network_pool_server["id"], payload)
324
- return
325
- end
326
- json_response = @network_pool_servers_interface.update(network_pool_server["id"], payload)
327
- if options[:json]
328
- puts as_json(json_response)
329
- else
330
- network_pool_server = json_response['networkPoolServer']
331
- print_green_success "Updated network pool server #{network_pool_server['name']}"
332
- get([network_pool_server['id']])
333
- end
334
- return 0
335
- rescue RestClient::Exception => e
336
- print_rest_exception(e, options)
337
- return 1
338
- end
339
- end
340
-
341
- def remove(args)
342
- options = {}
343
- optparse = Morpheus::Cli::OptionParser.new do |opts|
344
- opts.banner = subcommand_usage("[network-pool-server]")
345
- build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
346
- opts.footer = "Delete a network pool server." + "\n" +
347
- "[network-pool-server] is required. This is the name or id of a network pool server."
348
- end
349
- optparse.parse!(args)
350
-
351
- if args.count < 1
352
- print_error Morpheus::Terminal.angry_prompt
353
- puts_error "#{command_name} missing argument: [network-pool-server]\n#{optparse}"
354
- return 1
355
- end
356
-
357
- connect(options)
358
- begin
359
- network_pool_server = find_network_pool_server_by_name_or_id(args[0])
360
- return 1 if network_pool_server.nil?
361
-
362
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the network pool server: #{network_pool_server['name']}?")
363
- return 9, "aborted command"
364
- end
365
- if options[:dry_run]
366
- print_dry_run @network_pool_servers_interface.dry.destroy(network_pool_server['id'])
367
- return 0
368
- end
369
- json_response = @network_pool_servers_interface.destroy(network_pool_server['id'])
370
- if options[:json]
371
- print JSON.pretty_generate(json_response)
372
- print "\n"
373
- else
374
- print_green_success "Removed network pool server #{network_pool_server['name']}"
375
- # list([])
376
- end
377
- return 0
378
- rescue RestClient::Exception => e
379
- print_rest_exception(e, options)
380
- return 1
381
- end
382
- end
383
-
384
- private
385
-
386
-
387
- def find_network_pool_server_by_name_or_id(val)
388
- if val.to_s =~ /\A\d{1,}\Z/
389
- return find_network_pool_server_by_id(val)
390
- else
391
- return find_network_pool_server_by_name(val)
392
- end
393
- end
394
-
395
- def find_network_pool_server_by_id(id)
396
- begin
397
- json_response = @network_pool_servers_interface.get(id.to_i)
398
- return json_response['networkPoolServer']
399
- rescue RestClient::Exception => e
400
- if e.response && e.response.code == 404
401
- print_red_alert "Network Pool Server not found by id #{id}"
402
- return nil
403
- else
404
- raise e
405
- end
406
- end
407
- end
408
-
409
- def find_network_pool_server_by_name(name)
410
- json_response = @network_pool_servers_interface.list({name: name.to_s})
411
- network_pool_servers = json_response['networkPoolServers']
412
- if network_pool_servers.empty?
413
- print_red_alert "Network Pool Server not found by name #{name}"
414
- return nil
415
- elsif network_pool_servers.size > 1
416
- print_red_alert "#{network_pool_servers.size} network pool servers found by name #{name}"
417
- # print_networks_table(networks, {color: red})
418
- rows = network_pool_servers.collect do |network_pool_server|
419
- {id: it['id'], name: it['name']}
420
- end
421
- print red
422
- tp rows, [:id, :name]
423
- print reset,"\n"
424
- return nil
425
- else
426
- return network_pool_servers[0]
427
- end
428
- end
429
-
430
- end
@@ -1,495 +0,0 @@
1
- require 'rest_client'
2
- require 'optparse'
3
- require 'filesize'
4
- require 'table_print'
5
- require 'morpheus/cli/cli_command'
6
- require 'morpheus/cli/mixins/infrastructure_helper'
7
-
8
- class Morpheus::Cli::NetworkPoolsCommand
9
- include Morpheus::Cli::CliCommand
10
- include Morpheus::Cli::InfrastructureHelper
11
-
12
- set_command_name :'network-pools'
13
-
14
- register_subcommands :list, :get, :add, :update, :remove #, :generate_pool
15
-
16
- # set_default_subcommand :list
17
-
18
- def initialize()
19
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
20
- end
21
-
22
- def connect(opts)
23
- @api_client = establish_remote_appliance_connection(opts)
24
- @network_pools_interface = @api_client.network_pools
25
- @clouds_interface = @api_client.clouds
26
- @options_interface = @api_client.options
27
- end
28
-
29
- def handle(args)
30
- handle_subcommand(args)
31
- end
32
-
33
- def list(args)
34
- options = {}
35
- params = {}
36
- optparse = Morpheus::Cli::OptionParser.new do |opts|
37
- opts.banner = subcommand_usage()
38
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
39
- opts.footer = "List network pools."
40
- end
41
- optparse.parse!(args)
42
- connect(options)
43
- begin
44
- [:phrase, :offset, :max, :sort, :direction].each do |k|
45
- params[k] = options[k] unless options[k].nil?
46
- end
47
- if options[:dry_run]
48
- print_dry_run @network_pools_interface.dry.list(params)
49
- return
50
- end
51
- json_response = @network_pools_interface.list(params)
52
- network_pools = json_response["networkPools"]
53
- if options[:include_fields]
54
- json_response = {"networkPools" => filter_data(network_pools, options[:include_fields]) }
55
- end
56
- if options[:json]
57
- puts as_json(json_response, options)
58
- return 0
59
- elsif options[:yaml]
60
- puts as_yaml(json_response, options)
61
- return 0
62
- elsif options[:csv]
63
- puts records_as_csv(network_pools, options)
64
- return 0
65
- end
66
- title = "Morpheus Network Pools"
67
- subtitles = []
68
- if params[:phrase]
69
- subtitles << "Search: #{params[:phrase]}".strip
70
- end
71
- print_h1 title, subtitles
72
- if network_pools.empty?
73
- print cyan,"No network pools found.",reset,"\n"
74
- else
75
- rows = network_pools.collect {|network_pool|
76
- row = {
77
- id: network_pool['id'],
78
- # matching UI, but huh??
79
- name: !network_pool['displayName'].to_s.empty? ? network_pool['displayName'] : network_pool['name'],
80
- network: network_pool['name'],
81
- # network: network_pool['network'] ? network_pool['network']['name'] : '',
82
- type: network_pool['type'] ? network_pool['type']['name'] : '',
83
- ipRanges: network_pool['ipRanges'] ? network_pool['ipRanges'].collect {|it| it['startAddress'].to_s + " - " + it['endAddress'].to_s }.uniq.join(', ') : '',
84
- total: ("#{network_pool['ipCount']}/#{network_pool['freeCount']}")
85
- }
86
- row
87
- }
88
- columns = [:id, :name, :network, :type, {:ipRanges => {:display_name => "IP RANGES"} }, {:total => {:display_name => "TOTAL/FREE IPs"} }]
89
- if options[:include_fields]
90
- columns = options[:include_fields]
91
- end
92
- print cyan
93
- print as_pretty_table(rows, columns, options)
94
- print reset
95
- print_results_pagination(json_response, {:label => "network pool", :n_label => "network pools"})
96
- end
97
- print reset,"\n"
98
- return 0
99
- rescue RestClient::Exception => e
100
- print_rest_exception(e, options)
101
- exit 1
102
- end
103
- end
104
-
105
- def get(args)
106
- options = {}
107
- optparse = Morpheus::Cli::OptionParser.new do |opts|
108
- opts.banner = subcommand_usage("[network-pool]")
109
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
110
- opts.footer = "Get details about a network pool." + "\n" +
111
- "[network-pool] is required. This is the name or id of a network pool."
112
- end
113
- optparse.parse!(args)
114
- if args.count != 1
115
- print_error Morpheus::Terminal.angry_prompt
116
- puts_error "#{command_name} missing argument: [network-pool]\n#{optparse}"
117
- return 1
118
- end
119
- connect(options)
120
- begin
121
- if options[:dry_run]
122
- if args[0].to_s =~ /\A\d{1,}\Z/
123
- print_dry_run @network_pools_interface.dry.get(args[0].to_i)
124
- else
125
- print_dry_run @network_pools_interface.dry.list({name:args[0]})
126
- end
127
- return
128
- end
129
- network_pool = find_network_pool_by_name_or_id(args[0])
130
- return 1 if network_pool.nil?
131
- json_response = {'networkPool' => network_pool} # skip redundant request
132
- # json_response = @network_pools_interface.get(network_pool['id'])
133
- network_pool = json_response['networkPool']
134
- if options[:include_fields]
135
- json_response = {'networkPool' => filter_data(network_pool, options[:include_fields]) }
136
- end
137
- if options[:json]
138
- puts as_json(json_response, options)
139
- return 0
140
- elsif options[:yaml]
141
- puts as_yaml(json_response, options)
142
- return 0
143
- elsif options[:csv]
144
- puts records_as_csv([network_pool], options)
145
- return 0
146
- end
147
- print_h1 "Network Pool Details"
148
- print cyan
149
- description_cols = {
150
- "ID" => 'id',
151
- "Name" => lambda {|it| !it['displayName'].to_s.empty? ? it['displayName'] : it['name'] },
152
- "Network" => lambda {|it| it['name'] },
153
- "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
154
- # "IP Ranges" => lambda {|it| it['ipRanges'] ? it['ipRanges'].collect {|r| r['startAddress'].to_s + " - " + r['endAddress'].to_s }.uniq.join(', ') : '' },
155
- "Total IPs" => lambda {|it| it['ipCount'] },
156
- "Free IPs" => lambda {|it| it['freeCount'] },
157
- }
158
- print_description_list(description_cols, network_pool)
159
-
160
- print_h2 "IP Ranges"
161
- print cyan
162
- if network_pool['ipRanges']
163
- network_pool['ipRanges'].each do |r|
164
- puts " * #{r['startAddress']} - #{r['endAddress']}"
165
- end
166
- end
167
- print reset,"\n"
168
- return 0
169
- rescue RestClient::Exception => e
170
- print_rest_exception(e, options)
171
- return 1
172
- end
173
- end
174
-
175
- def add(args)
176
- options = {}
177
- ip_range_list = nil
178
- optparse = Morpheus::Cli::OptionParser.new do |opts|
179
- opts.banner = subcommand_usage()
180
- opts.on('--name VALUE', String, "Name for this network pool") do |val|
181
- options['name'] = val
182
- end
183
- opts.on('--type VALUE', String, "Type of network pool") do |val|
184
- options['type'] = val
185
- end
186
- opts.on('--ip-ranges LIST', Array, "IP Ranges, comma separated list IP ranges in the format start-end.") do |list|
187
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
188
- ip_range_list = []
189
- else
190
- ip_range_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
191
- ip_range_list = ip_range_list.collect {|it|
192
- range_parts = it.split("-")
193
- {startAddress: range_parts[0].to_s.strip, endAddress: range_parts[1].to_s.strip}
194
- }
195
- end
196
- end
197
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
198
- opts.footer = "Create a new network pool." + "\n" +
199
- "[name] is required and can be passed as --name instead."
200
- end
201
- optparse.parse!(args)
202
- if args.count > 1
203
- print_error Morpheus::Terminal.angry_prompt
204
- puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
205
- return 1
206
- end
207
- connect(options)
208
- begin
209
- # merge -O options into normally parsed options
210
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
211
-
212
- # support [name] as first argument
213
- if args[0]
214
- options['name'] = args[0]
215
- end
216
-
217
- # construct payload
218
- payload = nil
219
- if options[:payload]
220
- payload = options[:payload]
221
- else
222
- # prompt for network options
223
- payload = {
224
- 'networkPool' => {
225
- # 'config' => {}
226
- }
227
- }
228
-
229
- # allow arbitrary -O options
230
- payload['networkPool'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
231
-
232
- # Name
233
- if options['name']
234
- payload['networkPool']['name'] = options['name']
235
- else
236
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network pool.'}], options)
237
- payload['networkPool']['name'] = v_prompt['name']
238
- end
239
-
240
- # Network Pool Type
241
- network_type_id = nil
242
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Pool Type', 'type' => 'select', 'optionSource' => 'networkPoolTypes', 'required' => true, 'description' => 'Choose a network pool type.'}], options, @api_client, {})
243
- network_type_id = v_prompt['type']
244
- if network_type_id.nil? || network_type_id.to_s.empty?
245
- print_red_alert "Pool Type not found by id '#{options['type']}'"
246
- return 1
247
- end
248
- payload['networkPool']['type'] = {'id' => network_type_id.to_i }
249
-
250
- # IP Ranges
251
- if ip_range_list
252
- payload['networkPool']['ipRanges'] = ip_range_list
253
- else
254
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ipRanges', 'fieldLabel' => 'IP Ranges', 'type' => 'text', 'required' => true, 'description' => 'IP Ranges in the pool, comma separated list of ranges in the format start-end.'}], options)
255
- ip_range_list = v_prompt['ipRanges'].to_s.split(",").collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
256
- ip_range_list = ip_range_list.collect {|it|
257
- range_parts = it.split("-")
258
- range = {startAddress: range_parts[0].to_s.strip, endAddress: range_parts[1].to_s.strip}
259
- range
260
- }
261
- payload['networkPool']['ipRanges'] = ip_range_list
262
- end
263
-
264
- end
265
-
266
-
267
- if options[:dry_run]
268
- print_dry_run @network_pools_interface.dry.create(payload)
269
- return
270
- end
271
- json_response = @network_pools_interface.create(payload)
272
- if options[:json]
273
- print JSON.pretty_generate(json_response)
274
- print "\n"
275
- elsif !options[:quiet]
276
- network_pool = json_response['networkPool']
277
- print_green_success "Added network pool #{network_pool['name']}"
278
- get([network_pool['id']])
279
- end
280
- return 0
281
- rescue RestClient::Exception => e
282
- print_rest_exception(e, options)
283
- exit 1
284
- end
285
- end
286
-
287
- def update(args)
288
- options = {}
289
- ip_range_list = nil
290
- optparse = Morpheus::Cli::OptionParser.new do |opts|
291
- opts.banner = subcommand_usage("[network-pool] [options]")
292
- opts.on('--name VALUE', String, "Name for this network pool") do |val|
293
- options['name'] = val
294
- end
295
- opts.on('--type VALUE', String, "Type of network pool") do |val|
296
- options['description'] = val
297
- end
298
- opts.on('--ip-ranges LIST', Array, "IP Ranges, comma separated list IP ranges in the format start-end.") do |list|
299
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
300
- ip_range_list = []
301
- else
302
- ip_range_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
303
- ip_range_list = ip_range_list.collect {|it|
304
- range_parts = it.split("-")
305
- {startAddress: range_parts[0].to_s.strip, endAddress: range_parts[1].to_s.strip}
306
- }
307
- end
308
- end
309
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
310
- opts.footer = "Update a network pool." + "\n" +
311
- "[network-pool] is required. This is the id of a network pool."
312
- end
313
- optparse.parse!(args)
314
- if args.count != 1
315
- print_error Morpheus::Terminal.angry_prompt
316
- puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
317
- return 1
318
- end
319
- connect(options)
320
-
321
- begin
322
- network_pool = find_network_pool_by_name_or_id(args[0])
323
- return 1 if network_pool.nil?
324
-
325
- # merge -O options into normally parsed options
326
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
327
-
328
- # construct payload
329
- payload = nil
330
- if options[:payload]
331
- payload = options[:payload]
332
- else
333
- # prompt for network options
334
- payload = {
335
- 'networkPool' => {
336
- }
337
- }
338
-
339
- # allow arbitrary -O options
340
- payload['networkPool'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
341
-
342
- # Name
343
- if options['name']
344
- payload['networkPool']['name'] = options['name']
345
- else
346
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network pool.'}], options)
347
- # payload['networkPool']['name'] = v_prompt['name']
348
- end
349
-
350
- # Network Pool Type
351
- # network_type_id = nil
352
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Pool Type', 'type' => 'select', 'optionSource' => 'networkPoolTypes', 'required' => true, 'description' => 'Choose a network pool type.'}], options, @api_client, {})
353
- # network_type_id = v_prompt['type']
354
- # if network_type_id.nil? || network_type_id.to_s.empty?
355
- # print_red_alert "Pool Type not found by id '#{options['type']}'"
356
- # return 1
357
- # end
358
- # payload['networkPool']['type'] = {'id' => network_type_id.to_i }
359
- if options['type']
360
- payload['networkPool']['type'] = {'id' => options['type'].to_i }
361
- end
362
-
363
- # IP Ranges
364
- if ip_range_list
365
- ip_range_list = ip_range_list.collect {|range|
366
- # ugh, need to allow changing an existing range by id too
367
- if network_pool['ipRanges']
368
- existing_range = network_pool['ipRanges'].find {|r|
369
- range[:startAddress] == r['startAddress'] && range[:endAddress] == r['endAddress']
370
- }
371
- if existing_range
372
- range[:id] = existing_range['id']
373
- end
374
- end
375
- range
376
- }
377
- payload['networkPool']['ipRanges'] = ip_range_list
378
- else
379
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ipRanges', 'fieldLabel' => 'IP Ranges', 'type' => 'text', 'required' => true, 'description' => 'IP Ranges in the pool, comma separated list of ranges in the format start-end.'}], options)
380
- # payload['networkPool']['ipRanges'] = v_prompt['ipRanges'].to_s.split(",").collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq.collect {|it|
381
- # it
382
- # }
383
- end
384
-
385
- end
386
-
387
- if options[:dry_run]
388
- print_dry_run @network_pools_interface.dry.update(network_pool["id"], payload)
389
- return
390
- end
391
- json_response = @network_pools_interface.update(network_pool["id"], payload)
392
- if options[:json]
393
- puts as_json(json_response)
394
- else
395
- network_pool = json_response['networkPool']
396
- print_green_success "Updated network pool #{network_pool['name']}"
397
- get([network_pool['id']])
398
- end
399
- return 0
400
- rescue RestClient::Exception => e
401
- print_rest_exception(e, options)
402
- return 1
403
- end
404
- end
405
-
406
- def remove(args)
407
- options = {}
408
- optparse = Morpheus::Cli::OptionParser.new do |opts|
409
- opts.banner = subcommand_usage("[network-pool]")
410
- build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
411
- opts.footer = "Delete a network pool." + "\n" +
412
- "[network-pool] is required. This is the name or id of a network pool."
413
- end
414
- optparse.parse!(args)
415
-
416
- if args.count < 1
417
- print_error Morpheus::Terminal.angry_prompt
418
- puts_error "#{command_name} missing argument: [network-pool]\n#{optparse}"
419
- return 1
420
- end
421
-
422
- connect(options)
423
- begin
424
- network_pool = find_network_pool_by_name_or_id(args[0])
425
- return 1 if network_pool.nil?
426
-
427
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the network pool: #{network_pool['name']}?")
428
- return 9, "aborted command"
429
- end
430
- if options[:dry_run]
431
- print_dry_run @network_pools_interface.dry.destroy(network_pool['id'])
432
- return 0
433
- end
434
- json_response = @network_pools_interface.destroy(network_pool['id'])
435
- if options[:json]
436
- print JSON.pretty_generate(json_response)
437
- print "\n"
438
- else
439
- print_green_success "Removed network pool #{network_pool['name']}"
440
- # list([])
441
- end
442
- return 0
443
- rescue RestClient::Exception => e
444
- print_rest_exception(e, options)
445
- return 1
446
- end
447
- end
448
-
449
- private
450
-
451
-
452
- def find_network_pool_by_name_or_id(val)
453
- if val.to_s =~ /\A\d{1,}\Z/
454
- return find_network_pool_by_id(val)
455
- else
456
- return find_network_pool_by_name(val)
457
- end
458
- end
459
-
460
- def find_network_pool_by_id(id)
461
- begin
462
- json_response = @network_pools_interface.get(id.to_i)
463
- return json_response['networkPool']
464
- rescue RestClient::Exception => e
465
- if e.response && e.response.code == 404
466
- print_red_alert "Network Pool not found by id #{id}"
467
- return nil
468
- else
469
- raise e
470
- end
471
- end
472
- end
473
-
474
- def find_network_pool_by_name(name)
475
- json_response = @network_pools_interface.list({name: name.to_s})
476
- network_pools = json_response['networkPools']
477
- if network_pools.empty?
478
- print_red_alert "Network Pool not found by name #{name}"
479
- return nil
480
- elsif network_pools.size > 1
481
- print_red_alert "#{network_pools.size} network pools found by name #{name}"
482
- # print_networks_table(networks, {color: red})
483
- rows = network_pools.collect do |network_pool|
484
- {id: it['id'], name: it['name']}
485
- end
486
- print red
487
- tp rows, [:id, :name]
488
- print reset,"\n"
489
- return nil
490
- else
491
- return network_pools[0]
492
- end
493
- end
494
-
495
- end