morpheus-cli 3.1.1 → 3.1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,430 @@
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
@@ -0,0 +1,495 @@
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