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,148 +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::NetworkServicesCommand
9
- include Morpheus::Cli::CliCommand
10
- include Morpheus::Cli::InfrastructureHelper
11
-
12
- set_command_name :'network-services'
13
-
14
- # register_subcommands :list, :get, :add, :update, :remove
15
- register_subcommands :list
16
-
17
- # set_default_subcommand :list
18
-
19
- def initialize()
20
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
21
- end
22
-
23
- def connect(opts)
24
- @api_client = establish_remote_appliance_connection(opts)
25
- @network_services_interface = @api_client.network_services
26
- @clouds_interface = @api_client.clouds
27
- @options_interface = @api_client.options
28
- end
29
-
30
- def handle(args)
31
- handle_subcommand(args)
32
- end
33
-
34
- def list(args)
35
- options = {}
36
- params = {}
37
- optparse = Morpheus::Cli::OptionParser.new do |opts|
38
- opts.banner = subcommand_usage()
39
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
40
- opts.footer = "List network services."
41
- end
42
- optparse.parse!(args)
43
- connect(options)
44
- begin
45
- [:phrase, :offset, :max, :sort, :direction].each do |k|
46
- params[k] = options[k] unless options[k].nil?
47
- end
48
- if options[:dry_run]
49
- print_dry_run @network_services_interface.dry.list(params)
50
- return
51
- end
52
- json_response = @network_services_interface.list(params)
53
- network_services = json_response["networkServices"]
54
- if options[:include_fields]
55
- json_response = {"networkServices" => filter_data(network_services, options[:include_fields]) }
56
- end
57
- if options[:json]
58
- puts as_json(json_response, options)
59
- return 0
60
- elsif options[:yaml]
61
- puts as_yaml(json_response, options)
62
- return 0
63
- elsif options[:csv]
64
- puts records_as_csv(network_services, options)
65
- return 0
66
- end
67
- title = "Morpheus Network Services"
68
- subtitles = []
69
- if params[:phrase]
70
- subtitles << "Search: #{params[:phrase]}".strip
71
- end
72
- print_h1 title, subtitles
73
- if network_services.empty?
74
- print cyan,"No network services found.",reset,"\n"
75
- else
76
- rows = network_services.collect {|network_service|
77
- row = {
78
- id: network_service['id'],
79
- name: network_service['name'],
80
- type: network_service['type'] ? network_service['type']['name'] : '',
81
- }
82
- row
83
- }
84
- columns = [:id, :name, :type]
85
- if options[:include_fields]
86
- columns = options[:include_fields]
87
- end
88
- print cyan
89
- print as_pretty_table(rows, columns, options)
90
- print reset
91
- print_results_pagination(json_response, {:label => "network service", :n_label => "network services"})
92
- end
93
- print reset,"\n"
94
- return 0
95
- rescue RestClient::Exception => e
96
- print_rest_exception(e, options)
97
- exit 1
98
- end
99
- end
100
-
101
-
102
- private
103
-
104
-
105
- def find_network_service_by_name_or_id(val)
106
- if val.to_s =~ /\A\d{1,}\Z/
107
- return find_network_service_by_id(val)
108
- else
109
- return find_network_service_by_name(val)
110
- end
111
- end
112
-
113
- def find_network_service_by_id(id)
114
- begin
115
- json_response = @network_services_interface.get(id.to_i)
116
- return json_response['networkService']
117
- rescue RestClient::Exception => e
118
- if e.response && e.response.code == 404
119
- print_red_alert "Network Service not found by id #{id}"
120
- return nil
121
- else
122
- raise e
123
- end
124
- end
125
- end
126
-
127
- def find_network_service_by_name(name)
128
- json_response = @network_services_interface.list({name: name.to_s})
129
- network_services = json_response['networkServices']
130
- if network_services.empty?
131
- print_red_alert "Network Service not found by name #{name}"
132
- return nil
133
- elsif network_services.size > 1
134
- print_red_alert "#{network_services.size} network services found by name #{name}"
135
- # print_networks_table(networks, {color: red})
136
- rows = network_services.collect do |network_service|
137
- {id: it['id'], name: it['name']}
138
- end
139
- print red
140
- tp rows, [:id, :name]
141
- print reset,"\n"
142
- return nil
143
- else
144
- return network_services[0]
145
- end
146
- end
147
-
148
- end
@@ -1,855 +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::NetworksCommand
9
- include Morpheus::Cli::CliCommand
10
- include Morpheus::Cli::InfrastructureHelper
11
-
12
- set_command_name :networks
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
- @networks_interface = @api_client.networks
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
- opts.on('--cidr VALUE', String, "Filter by cidr, matches beginning of value.") do |val|
39
- params['cidr'] = val
40
- end
41
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
42
- opts.footer = "List networks."
43
- end
44
- optparse.parse!(args)
45
- connect(options)
46
- begin
47
- [:phrase, :offset, :max, :sort, :direction].each do |k|
48
- params[k] = options[k] unless options[k].nil?
49
- end
50
- if options[:dry_run]
51
- print_dry_run @networks_interface.dry.list(params)
52
- return
53
- end
54
- json_response = @networks_interface.list(params)
55
- networks = json_response["networks"]
56
- if options[:include_fields]
57
- json_response = {"networks" => filter_data(networks, options[:include_fields]) }
58
- end
59
- if options[:json]
60
- puts as_json(json_response, options)
61
- return 0
62
- elsif options[:yaml]
63
- puts as_yaml(json_response, options)
64
- return 0
65
- elsif options[:csv]
66
- puts records_as_csv(networks, options)
67
- return 0
68
- end
69
- title = "Morpheus Networks"
70
- subtitles = []
71
- if params[:phrase]
72
- subtitles << "Search: #{params[:phrase]}".strip
73
- end
74
- print_h1 title, subtitles
75
- if networks.empty?
76
- print cyan,"No networks found.",reset,"\n"
77
- else
78
- rows = networks.collect {|network|
79
- row = {
80
- id: network['id'],
81
- name: network['name'],
82
- type: network['type'] ? network['type']['name'] : '',
83
- cloud: network['zone'] ? network['zone']['name'] : '',
84
- cidr: network['cidr'],
85
- pool: network['pool'] ? network['pool']['name'] : '',
86
- dhcp: network['dhcpServer'] ? 'Yes' : 'No',
87
- visibility: network['visibility'].to_s.capitalize,
88
- tenants: network['tenants'] ? network['tenants'].collect {|it| it['name'] }.uniq.join(', ') : ''
89
- }
90
- row
91
- }
92
- columns = [:id, :name, :type, :cloud, :cidr, :pool, :dhcp, :visibility, :tenants]
93
- if options[:include_fields]
94
- columns = options[:include_fields]
95
- end
96
- print cyan
97
- print as_pretty_table(rows, columns, options)
98
- print reset
99
- print_results_pagination(json_response, {:label => "network", :n_label => "networks"})
100
- end
101
- print reset,"\n"
102
- return 0
103
- rescue RestClient::Exception => e
104
- print_rest_exception(e, options)
105
- exit 1
106
- end
107
- end
108
-
109
- def get(args)
110
- options = {}
111
- optparse = Morpheus::Cli::OptionParser.new do |opts|
112
- opts.banner = subcommand_usage("[network]")
113
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
114
- opts.footer = "Get details about a network." + "\n" +
115
- "[network] is required. This is the name or id of a network."
116
- end
117
- optparse.parse!(args)
118
- if args.count != 1
119
- print_error Morpheus::Terminal.angry_prompt
120
- puts_error "#{command_name} missing argument: [network]\n#{optparse}"
121
- return 1
122
- end
123
- connect(options)
124
- begin
125
- if options[:dry_run]
126
- if args[0].to_s =~ /\A\d{1,}\Z/
127
- print_dry_run @networks_interface.dry.get(args[0].to_i)
128
- else
129
- print_dry_run @networks_interface.dry.list({name:args[0]})
130
- end
131
- return
132
- end
133
- network = find_network_by_name_or_id(args[0])
134
- return 1 if network.nil?
135
- json_response = {'network' => network} # skip redundant request
136
- # json_response = @networks_interface.get(network['id'])
137
- network = json_response['network']
138
- if options[:include_fields]
139
- json_response = {'network' => filter_data(network, options[:include_fields]) }
140
- end
141
- if options[:json]
142
- puts as_json(json_response, options)
143
- return 0
144
- elsif options[:yaml]
145
- puts as_yaml(json_response, options)
146
- return 0
147
- elsif options[:csv]
148
- puts records_as_csv([network], options)
149
- return 0
150
- end
151
- print_h1 "Network Details"
152
- print cyan
153
- description_cols = {
154
- "ID" => 'id',
155
- "Name" => 'name',
156
- "Description" => 'description',
157
- "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
158
- "Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
159
- "CIDR" => 'cidr',
160
- "Gateway" => 'gateway',
161
- "Netmask" => 'netmask',
162
- "Subnet" => 'subnetAddress',
163
- "Primary DNS" => 'dnsPrimary',
164
- "Secondary DNS" => 'dnsSecondary',
165
- "Pool" => lambda {|it| it['pool'] ? it['pool']['name'] : '' },
166
- "DHCP" => lambda {|it| it['dhcpServer'] ? 'Yes' : 'No' },
167
- "Allow IP Override" => lambda {|it| it['allowStaticOverride'] ? 'Yes' : 'No' },
168
- "Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
169
- "Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' },
170
- # "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
171
- }
172
- print_description_list(description_cols, network)
173
-
174
- if network['resourcePermission'].nil?
175
- print "\n", "No group access found", "\n"
176
- else
177
- print_h2 "Group Access"
178
- rows = []
179
- if network['resourcePermission']['all']
180
- rows.push({"name" => 'All'})
181
- end
182
- if network['resourcePermission']['sites']
183
- network['resourcePermission']['sites'].each do |site|
184
- rows.push(site)
185
- end
186
- end
187
- rows = rows.collect do |site|
188
- {group: site['name'], default: site['default'] ? 'Yes' : ''}
189
- end
190
- columns = [:group, :default]
191
- print cyan
192
- print as_pretty_table(rows, columns)
193
- end
194
-
195
- print reset,"\n"
196
- return 0
197
- rescue RestClient::Exception => e
198
- print_rest_exception(e, options)
199
- return 1
200
- end
201
- end
202
-
203
- def add(args)
204
- options = {}
205
- network_type_id = nil
206
- tenants = nil
207
- group_access_all = nil
208
- group_access_list = nil
209
- group_defaults_list = nil
210
- optparse = Morpheus::Cli::OptionParser.new do |opts|
211
- opts.banner = subcommand_usage("-t TYPE")
212
- opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
213
- options[:cloud] = val
214
- end
215
- opts.on('-t', '--type ID', "Network Type Name or ID") do |val|
216
- options['type'] = val
217
- end
218
- opts.on('--name VALUE', String, "Name for this network") do |val|
219
- options['name'] = val
220
- end
221
- opts.on('--description VALUE', String, "Description of network") do |val|
222
- options['description'] = val
223
- end
224
- opts.on('--gateway VALUE', String, "Gateway") do |val|
225
- options['gateway'] = val
226
- end
227
- opts.on('--dns-primary VALUE', String, "DNS Primary") do |val|
228
- options['dnsPrimary'] = val
229
- end
230
- opts.on('--dns-secondary VALUE', String, "DNS Secondary") do |val|
231
- options['dnsSecondary'] = val
232
- end
233
- opts.on('--cidr VALUE', String, "CIDR") do |val|
234
- options['cidr'] = val
235
- end
236
- opts.on('--vlan-id VALUE', String, "VLAN ID") do |val|
237
- options['vlanId'] = val.to_i
238
- end
239
- opts.on('--pool ID', String, "Network Pool") do |val|
240
- options['pool'] = val.to_i
241
- end
242
- opts.on('--dhcp-server [on|off]', String, "DHCP Server") do |val|
243
- options['dhcpServer'] = val.to_s == 'on' || val.to_s == 'true'
244
- end
245
- opts.on('--allow-ip-override [on|off]', String, "Allow IP Override") do |val|
246
- options['allowStaticOverride'] = val.to_s == 'on' || val.to_s == 'true'
247
- end
248
- opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
249
- group_access_all = val.to_s == 'on' || val.to_s == 'true'
250
- end
251
- opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
252
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
253
- group_access_list = []
254
- else
255
- group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
256
- end
257
- end
258
- opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
259
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
260
- group_defaults_list = []
261
- else
262
- group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
263
- end
264
- end
265
- opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
266
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
267
- options['tenants'] = []
268
- else
269
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
270
- end
271
- end
272
- opts.on('--accounts LIST', Array, "alias for --tenants") do |list|
273
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
274
- options['tenants'] = []
275
- else
276
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
277
- end
278
- end
279
- opts.on('--visibility [private|public]', String, "Visibility") do |val|
280
- options['visibility'] = val
281
- end
282
- opts.on('--active [on|off]', String, "Can be used to disable a network") do |val|
283
- options['active'] = val.to_s == 'on' || val.to_s == 'true'
284
- end
285
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
286
- opts.footer = "Create a new network." + "\n" +
287
- "[name] is required and can be passed as --name instead."
288
- end
289
- optparse.parse!(args)
290
- if args.count > 1
291
- print_error Morpheus::Terminal.angry_prompt
292
- puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
293
- return 1
294
- end
295
- connect(options)
296
- begin
297
- # merge -O options into normally parsed options
298
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
299
-
300
- # support [name] as first argument
301
- if args[0]
302
- options['name'] = args[0]
303
- end
304
-
305
- # construct payload
306
- payload = nil
307
- if options[:payload]
308
- payload = options[:payload]
309
- else
310
- # prompt for network options
311
- payload = {
312
- 'network' => {
313
- # 'config' => {}
314
- }
315
- }
316
-
317
- # allow arbitrary -O options
318
- payload['network'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
319
-
320
- # Cloud
321
- cloud = nil
322
- if options[:cloud]
323
- cloud = find_cloud_by_name_or_id(options[:cloud])
324
- # meh, should validate cloud is in the cloudsForNetworks dropdown..
325
- return 1 if cloud.nil?
326
- else
327
- # print_red_alert "Cloud not specified!"
328
- # exit 1
329
- cloud_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'type' => 'select', 'fieldLabel' => 'Cloud', 'optionSource' => 'cloudsForNetworks', 'required' => true, 'description' => 'Select Cloud.'}],options,@api_client,{})
330
- cloud_id = cloud_prompt['cloud']
331
- cloud = find_cloud_by_name_or_id(cloud_id) if cloud_id
332
- return 1 if cloud.nil?
333
- end
334
- payload['network']['zone'] = {'id' => cloud['id']}
335
-
336
- # Network Type
337
- network_type_id = nil
338
- api_params = {"network.zone.id" => cloud['id']} #{network:{zone:{id: cloud['id']}}}
339
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Network Type', 'type' => 'select', 'optionSource' => 'networkTypesForCloud', 'required' => true, 'description' => 'Choose a network type.'}], options, @api_client, api_params)
340
- network_type_id = v_prompt['type']
341
- if network_type_id.nil? || network_type_id.to_s.empty?
342
- print_red_alert "Network Type not found by id '#{options['type']}'"
343
- return 1
344
- end
345
- payload['network']['type'] = {'id' => network_type_id.to_i }
346
-
347
- # Name
348
- if options['name']
349
- payload['network']['name'] = options['name']
350
- else
351
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network.'}], options)
352
- payload['network']['name'] = v_prompt['name']
353
- end
354
-
355
- # Description
356
- if options['description']
357
- payload['network']['description'] = options['description']
358
- else
359
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false, 'description' => 'Description of network.'}], options)
360
- payload['network']['description'] = v_prompt['description']
361
- end
362
-
363
- # Gateway
364
- if options['gateway']
365
- payload['network']['gateway'] = options['gateway']
366
- else
367
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'gateway', 'fieldLabel' => 'Gateway', 'type' => 'text', 'required' => false, 'description' => ''}], options)
368
- payload['network']['gateway'] = v_prompt['gateway']
369
- end
370
-
371
- # DNS Primary
372
- if options['dnsPrimary']
373
- payload['network']['dnsPrimary'] = options['dnsPrimary']
374
- else
375
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'dnsPrimary', 'fieldLabel' => 'DNS Primary', 'type' => 'text', 'required' => false, 'description' => ''}], options)
376
- payload['network']['dnsPrimary'] = v_prompt['dnsPrimary']
377
- end
378
-
379
- # DNS Secondary
380
- if options['dnsSecondary']
381
- payload['network']['dnsSecondary'] = options['dnsSecondary']
382
- else
383
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'dnsSecondary', 'fieldLabel' => 'DNS Secondary', 'type' => 'text', 'required' => false, 'description' => ''}], options)
384
- payload['network']['dnsSecondary'] = v_prompt['dnsSecondary']
385
- end
386
-
387
- # CIDR
388
- if options['cidr']
389
- payload['network']['cidr'] = options['cidr']
390
- else
391
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cidr', 'fieldLabel' => 'CIDR', 'type' => 'text', 'required' => false, 'description' => ''}], options)
392
- payload['network']['cidr'] = v_prompt['cidr']
393
- end
394
-
395
- # VLAN ID
396
- if options['vlanId']
397
- payload['network']['vlanId'] = options['vlanId']
398
- else
399
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'vlanId', 'fieldLabel' => 'VLAN ID', 'type' => 'number', 'required' => false, 'description' => ''}], options)
400
- payload['network']['vlanId'] = v_prompt['vlanId']
401
- end
402
-
403
- # Network Pool
404
- if options['pool']
405
- payload['network']['pool'] = options['pool'].to_i
406
- else
407
- # todo: select dropdown
408
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'select', 'optionSource' => 'networkPools', 'required' => false, 'description' => ''}], options, @api_client, {zoneId: cloud['id']})
409
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'text', 'required' => false, 'description' => ''}], options)
410
- payload['network']['pool'] = v_prompt['pool'].to_i if v_prompt['pool']
411
- end
412
-
413
- # DHCP Server
414
- if options['dhcpServer'] != nil
415
- payload['network']['dhcpServer'] = options['dhcpServer']
416
- else
417
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'dhcpServer', 'fieldLabel' => 'DHCP Server', 'type' => 'checkbox', 'required' => false, 'description' => ''}], options)
418
- payload['network']['dhcpServer'] = v_prompt['dhcpServer']
419
- end
420
-
421
- # Allow IP Override
422
- if options['allowStaticOverride'] != nil
423
- payload['network']['allowStaticOverride'] = options['allowStaticOverride']
424
- else
425
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'allowStaticOverride', 'fieldLabel' => 'Allow IP Override', 'type' => 'checkbox', 'required' => false, 'description' => ''}], options)
426
- payload['network']['allowStaticOverride'] = v_prompt['allowStaticOverride']
427
- end
428
-
429
- # Group Access
430
- if group_access_all != nil
431
- payload['resourcePermissions'] ||= {}
432
- payload['resourcePermissions']['all'] = group_access_all
433
- end
434
- if group_access_list != nil
435
- payload['resourcePermissions'] ||= {}
436
- payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
437
- site = {"id" => site_id.to_i}
438
- if group_defaults_list && group_defaults_list.include?(site_id)
439
- site["default"] = true
440
- end
441
- site
442
- end
443
- end
444
-
445
- # Tenants
446
- if options['tenants']
447
- payload['tenantPermissions'] = {}
448
- payload['tenantPermissions']['accounts'] = options['tenants']
449
- end
450
-
451
- # Active
452
- if options['active'] != nil
453
- payload['network']['active'] = options['active']
454
- end
455
-
456
- # Visibility
457
- if options['visibility'] != nil
458
- payload['network']['visibility'] = options['visibility']
459
- end
460
-
461
- end
462
-
463
-
464
- if options[:dry_run]
465
- print_dry_run @networks_interface.dry.create(payload)
466
- return
467
- end
468
- json_response = @networks_interface.create(payload)
469
- if options[:json]
470
- print JSON.pretty_generate(json_response)
471
- print "\n"
472
- elsif !options[:quiet]
473
- network = json_response['network']
474
- print_green_success "Added network #{network['name']}"
475
- get([network['id']])
476
- end
477
- return 0
478
- rescue RestClient::Exception => e
479
- print_rest_exception(e, options)
480
- exit 1
481
- end
482
- end
483
-
484
- def update(args)
485
- options = {}
486
- # network_type_id = nil
487
- tenants = nil
488
- group_access_all = nil
489
- group_access_list = nil
490
- group_defaults_list = nil
491
- optparse = Morpheus::Cli::OptionParser.new do |opts|
492
- opts.banner = subcommand_usage("[network] [options]")
493
- # opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
494
- # options[:cloud] = val
495
- # end
496
- # opts.on('-t', '--type ID', "Network Type Name or ID") do |val|
497
- # options['type'] = val
498
- # end
499
- opts.on('--name VALUE', String, "Name for this network") do |val|
500
- options['name'] = val
501
- end
502
- opts.on('--description VALUE', String, "Description of network") do |val|
503
- options['description'] = val
504
- end
505
- opts.on('--gateway VALUE', String, "Gateway") do |val|
506
- options['gateway'] = val
507
- end
508
- opts.on('--dns-primary VALUE', String, "DNS Primary") do |val|
509
- options['dnsPrimary'] = val
510
- end
511
- opts.on('--dns-secondary VALUE', String, "DNS Secondary") do |val|
512
- options['dnsSecondary'] = val
513
- end
514
- opts.on('--cidr VALUE', String, "CIDR") do |val|
515
- options['cidr'] = val
516
- end
517
- opts.on('--vlan-id VALUE', String, "VLAN ID") do |val|
518
- options['vlanId'] = val.to_i
519
- end
520
- opts.on('--pool ID', String, "Network Pool") do |val|
521
- options['pool'] = val.to_i
522
- end
523
- opts.on('--dhcp-server [on|off]', String, "DHCP Server") do |val|
524
- options['dhcpServer'] = val.to_s == 'on' || val.to_s == 'true'
525
- end
526
- opts.on('--allow-ip-override [on|off]', String, "Allow IP Override") do |val|
527
- options['allowStaticOverride'] = val.to_s == 'on' || val.to_s == 'true'
528
- end
529
- opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
530
- group_access_all = val.to_s == 'on' || val.to_s == 'true'
531
- end
532
- opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
533
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
534
- group_access_list = []
535
- else
536
- group_access_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
537
- end
538
- end
539
- opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
540
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
541
- group_defaults_list = []
542
- else
543
- group_defaults_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
544
- end
545
- end
546
- opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
547
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
548
- options['tenants'] = []
549
- else
550
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
551
- end
552
- end
553
- opts.on('--accounts LIST', Array, "alias for --tenants") do |list|
554
- if list.size == 1 && list[0] == 'null' # hacky way to clear it
555
- options['tenants'] = []
556
- else
557
- options['tenants'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
558
- end
559
- end
560
- opts.on('--visibility [private|public]', String, "Visibility") do |val|
561
- options['visibility'] = val
562
- end
563
- opts.on('--active [on|off]', String, "Can be used to disable a network") do |val|
564
- options['active'] = val.to_s == 'on' || val.to_s == 'true'
565
- end
566
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
567
- opts.footer = "Update a network." + "\n" +
568
- "[network] is required. This is the id of a network."
569
- end
570
- optparse.parse!(args)
571
- if args.count != 1
572
- print_error Morpheus::Terminal.angry_prompt
573
- puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
574
- return 1
575
- end
576
- connect(options)
577
-
578
- begin
579
- network = find_network_by_name_or_id(args[0])
580
- return 1 if network.nil?
581
-
582
- # merge -O options into normally parsed options
583
- options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
584
-
585
- # construct payload
586
- payload = nil
587
- if options[:payload]
588
- payload = options[:payload]
589
- else
590
- # prompt for network options
591
- payload = {
592
- 'network' => {
593
- # 'config' => {}
594
- }
595
- }
596
-
597
- # allow arbitrary -O options
598
- payload['network'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
599
-
600
- # # Cloud
601
- # cloud = nil
602
- # if options[:cloud]
603
- # cloud = find_cloud_by_name_or_id(options[:cloud])
604
- # # meh, should validate cloud is in the cloudsForNetworks dropdown..
605
- # return 1 if cloud.nil?
606
- # else
607
- # # print_red_alert "Cloud not specified!"
608
- # # exit 1
609
- # cloud_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'type' => 'select', 'fieldLabel' => 'Cloud', 'optionSource' => 'cloudsForNetworks', 'required' => true, 'description' => 'Select Cloud.'}],options,@api_client,{})
610
- # cloud_id = cloud_prompt['cloud']
611
- # cloud = find_cloud_by_name_or_id(cloud_id) if cloud_id
612
- # return 1 if cloud.nil?
613
- # end
614
-
615
- # # Network Type
616
- # network_type_id = nil
617
- # api_params = {"network.zone.id" => cloud['id']} #{network:{zone:{id: cloud['id']}}}
618
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Network Type', 'type' => 'select', 'optionSource' => 'networkTypesForCloud', 'required' => true, 'description' => 'Choose a network type.'}], options, @api_client, api_params)
619
- # network_type_id = v_prompt['type']
620
- # if network_type_id.nil? || network_type_id.to_s.empty?
621
- # print_red_alert "Network Type not found by id '#{options['type']}'"
622
- # return 1
623
- # end
624
- # payload['network']['type'] = {'id' => network_type_id.to_i }
625
-
626
- # Name
627
- if options['name']
628
- payload['network']['name'] = options['name']
629
- else
630
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network.'}], options)
631
- # payload['network']['name'] = v_prompt['name']
632
- end
633
-
634
- # Description
635
- if options['description']
636
- payload['network']['description'] = options['description']
637
- else
638
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false, 'description' => 'Description of network.'}], options)
639
- # payload['network']['description'] = v_prompt['description']
640
- end
641
-
642
- # Gateway
643
- if options['gateway']
644
- payload['network']['gateway'] = options['gateway']
645
- else
646
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'gateway', 'fieldLabel' => 'Gateway', 'type' => 'text', 'required' => false, 'description' => ''}], options)
647
- # payload['network']['gateway'] = v_prompt['gateway']
648
- end
649
-
650
- # DNS Primary
651
- if options['dnsPrimary']
652
- payload['network']['dnsPrimary'] = options['dnsPrimary']
653
- else
654
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'dnsPrimary', 'fieldLabel' => 'DNS Primary', 'type' => 'text', 'required' => false, 'description' => ''}], options)
655
- # payload['network']['dnsPrimary'] = v_prompt['dnsPrimary']
656
- end
657
-
658
- # DNS Secondary
659
- if options['dnsSecondary']
660
- payload['network']['dnsSecondary'] = options['dnsSecondary']
661
- else
662
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'dnsSecondary', 'fieldLabel' => 'DNS Secondary', 'type' => 'text', 'required' => false, 'description' => ''}], options)
663
- # payload['network']['dnsSecondary'] = v_prompt['dnsSecondary']
664
- end
665
-
666
- # CIDR
667
- if options['cidr']
668
- payload['network']['cidr'] = options['cidr']
669
- else
670
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cidr', 'fieldLabel' => 'CIDR', 'type' => 'text', 'required' => false, 'description' => ''}], options)
671
- # payload['network']['cidr'] = v_prompt['cidr']
672
- end
673
-
674
- # VLAN ID
675
- if options['vlanId']
676
- payload['network']['vlanId'] = options['vlanId']
677
- else
678
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'vlanId', 'fieldLabel' => 'VLAN ID', 'type' => 'number', 'required' => false, 'description' => ''}], options)
679
- # payload['network']['vlanId'] = v_prompt['vlanId']
680
- end
681
-
682
- # Network Pool
683
- if options['pool']
684
- payload['network']['pool'] = options['pool'].to_i
685
- else
686
- # todo: select dropdown
687
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'select', 'optionSource' => 'networkPools', 'required' => false, 'description' => ''}], options, @api_client, {zoneId: cloud['id']})
688
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'text', 'required' => false, 'description' => ''}], options)
689
- # payload['network']['pool'] = v_prompt['pool'].to_i if v_prompt['pool']
690
- end
691
-
692
- # DHCP Server
693
- if options['dhcpServer'] != nil
694
- payload['network']['dhcpServer'] = options['dhcpServer']
695
- else
696
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'dhcpServer', 'fieldLabel' => 'DHCP Server', 'type' => 'checkbox', 'required' => false, 'description' => ''}], options)
697
- # payload['network']['dhcpServer'] = v_prompt['dhcpServer']
698
- end
699
-
700
- # Allow IP Override
701
- if options['allowStaticOverride'] != nil
702
- payload['network']['allowStaticOverride'] = options['allowStaticOverride']
703
- else
704
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'allowStaticOverride', 'fieldLabel' => 'Allow IP Override', 'type' => 'checkbox', 'required' => false, 'description' => ''}], options)
705
- # payload['network']['allowStaticOverride'] = v_prompt['allowStaticOverride']
706
- end
707
-
708
- # Group Access
709
- if group_access_all != nil
710
- payload['resourcePermissions'] ||= {}
711
- payload['resourcePermissions']['all'] = group_access_all
712
- end
713
- if group_access_list != nil
714
- payload['resourcePermissions'] ||= {}
715
- payload['resourcePermissions']['sites'] = group_access_list.collect do |site_id|
716
- site = {"id" => site_id.to_i}
717
- if group_defaults_list && group_defaults_list.include?(site_id)
718
- site["default"] = true
719
- end
720
- site
721
- end
722
- end
723
-
724
- # Tenants
725
- if options['tenants']
726
- payload['tenantPermissions'] = {}
727
- payload['tenantPermissions']['accounts'] = options['tenants']
728
- end
729
-
730
- # Active
731
- if options['active'] != nil
732
- payload['network']['active'] = options['active']
733
- end
734
-
735
- # Visibility
736
- if options['visibility'] != nil
737
- payload['network']['visibility'] = options['visibility']
738
- end
739
-
740
- end
741
-
742
- if options[:dry_run]
743
- print_dry_run @networks_interface.dry.update(network["id"], payload)
744
- return
745
- end
746
- json_response = @networks_interface.update(network["id"], payload)
747
- if options[:json]
748
- puts as_json(json_response)
749
- else
750
- network = json_response['network']
751
- print_green_success "Updated network #{network['name']}"
752
- get([network['id']])
753
- end
754
- return 0
755
- rescue RestClient::Exception => e
756
- print_rest_exception(e, options)
757
- return 1
758
- end
759
- end
760
-
761
- def remove(args)
762
- options = {}
763
- optparse = Morpheus::Cli::OptionParser.new do |opts|
764
- opts.banner = subcommand_usage("[network]")
765
- build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
766
- opts.footer = "Delete a network." + "\n" +
767
- "[network] is required. This is the name or id of a network."
768
- end
769
- optparse.parse!(args)
770
-
771
- if args.count < 1
772
- print_error Morpheus::Terminal.angry_prompt
773
- puts_error "#{command_name} missing argument: [network]\n#{optparse}"
774
- return 1
775
- end
776
-
777
- connect(options)
778
- begin
779
- network = find_network_by_name_or_id(args[0])
780
- return 1 if network.nil?
781
-
782
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the network: #{network['name']}?")
783
- return 9, "aborted command"
784
- end
785
- if options[:dry_run]
786
- print_dry_run @networks_interface.dry.destroy(network['id'])
787
- return 0
788
- end
789
- json_response = @networks_interface.destroy(network['id'])
790
- if options[:json]
791
- print JSON.pretty_generate(json_response)
792
- print "\n"
793
- else
794
- print_green_success "Removed network #{network['name']}"
795
- # list([])
796
- end
797
- return 0
798
- rescue RestClient::Exception => e
799
- print_rest_exception(e, options)
800
- return 1
801
- end
802
- end
803
-
804
- private
805
-
806
-
807
- def find_network_by_name_or_id(val)
808
- if val.to_s =~ /\A\d{1,}\Z/
809
- return find_network_by_id(val)
810
- else
811
- return find_network_by_name(val)
812
- end
813
- end
814
-
815
- def find_network_by_id(id)
816
- begin
817
- json_response = @networks_interface.get(id.to_i)
818
- return json_response['network']
819
- rescue RestClient::Exception => e
820
- if e.response && e.response.code == 404
821
- print_red_alert "Network not found by id #{id}"
822
- return nil
823
- else
824
- raise e
825
- end
826
- end
827
- end
828
-
829
- def find_network_by_name(name)
830
- json_response = @networks_interface.list({name: name.to_s})
831
- networks = json_response['networks']
832
- if networks.empty?
833
- print_red_alert "Network not found by name #{name}"
834
- return nil
835
- elsif networks.size > 1
836
- print_red_alert "#{networks.size} networks found by name #{name}"
837
- # print_networks_table(networks, {color: red})
838
- rows = networks.collect do |network|
839
- {id: it['id'], name: it['name']}
840
- end
841
- print red
842
- tp rows, [:id, :name]
843
- print reset,"\n"
844
- return nil
845
- else
846
- network = networks[0]
847
- # merge in tenants map
848
- if json_response['tenants'] && json_response['tenants'][network['id']]
849
- network['tenants'] = json_response['tenants'][network['id']]
850
- end
851
- return network
852
- end
853
- end
854
-
855
- end