morpheus-cli 2.12.5 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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