morpheus-cli 2.12.5 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +5 -0
  3. data/lib/morpheus/api/api_client.rb +15 -30
  4. data/lib/morpheus/api/app_templates_interface.rb +34 -7
  5. data/lib/morpheus/api/apps_interface.rb +20 -1
  6. data/lib/morpheus/api/archive_buckets_interface.rb +124 -0
  7. data/lib/morpheus/api/archive_files_interface.rb +182 -0
  8. data/lib/morpheus/api/{network_pools_interface.rb → image_builder_boot_scripts_interface.rb} +6 -6
  9. data/lib/morpheus/api/{policies_interface.rb → image_builder_image_builds_interface.rb} +20 -15
  10. data/lib/morpheus/api/image_builder_interface.rb +26 -0
  11. data/lib/morpheus/api/{network_proxies_interface.rb → image_builder_preseed_scripts_interface.rb} +6 -6
  12. data/lib/morpheus/cli.rb +10 -9
  13. data/lib/morpheus/cli/alias_command.rb +10 -9
  14. data/lib/morpheus/cli/app_templates.rb +1566 -457
  15. data/lib/morpheus/cli/apps.rb +284 -108
  16. data/lib/morpheus/cli/archives_command.rb +2184 -0
  17. data/lib/morpheus/cli/boot_scripts_command.rb +382 -0
  18. data/lib/morpheus/cli/cli_command.rb +9 -35
  19. data/lib/morpheus/cli/error_handler.rb +2 -0
  20. data/lib/morpheus/cli/hosts.rb +15 -3
  21. data/lib/morpheus/cli/image_builder_command.rb +1208 -0
  22. data/lib/morpheus/cli/instances.rb +118 -47
  23. data/lib/morpheus/cli/man_command.rb +27 -24
  24. data/lib/morpheus/cli/mixins/print_helper.rb +19 -5
  25. data/lib/morpheus/cli/mixins/provisioning_helper.rb +20 -20
  26. data/lib/morpheus/cli/option_types.rb +45 -14
  27. data/lib/morpheus/cli/preseed_scripts_command.rb +381 -0
  28. data/lib/morpheus/cli/remote.rb +1 -0
  29. data/lib/morpheus/cli/roles.rb +2 -2
  30. data/lib/morpheus/cli/shell.rb +3 -2
  31. data/lib/morpheus/cli/version.rb +1 -1
  32. data/lib/morpheus/ext/hash.rb +22 -0
  33. data/lib/morpheus/formatters.rb +33 -0
  34. data/lib/morpheus/terminal.rb +1 -1
  35. metadata +13 -21
  36. data/lib/morpheus/api/cloud_policies_interface.rb +0 -47
  37. data/lib/morpheus/api/group_policies_interface.rb +0 -47
  38. data/lib/morpheus/api/network_domains_interface.rb +0 -47
  39. data/lib/morpheus/api/network_groups_interface.rb +0 -47
  40. data/lib/morpheus/api/network_pool_servers_interface.rb +0 -47
  41. data/lib/morpheus/api/network_services_interface.rb +0 -47
  42. data/lib/morpheus/api/networks_interface.rb +0 -54
  43. data/lib/morpheus/cli/network_domains_command.rb +0 -571
  44. data/lib/morpheus/cli/network_groups_command.rb +0 -602
  45. data/lib/morpheus/cli/network_pool_servers_command.rb +0 -430
  46. data/lib/morpheus/cli/network_pools_command.rb +0 -495
  47. data/lib/morpheus/cli/network_proxies_command.rb +0 -594
  48. data/lib/morpheus/cli/network_services_command.rb +0 -148
  49. data/lib/morpheus/cli/networks_command.rb +0 -855
  50. data/lib/morpheus/cli/policies_command.rb +0 -847
  51. data/scripts/generate_morpheus_commands_help.morpheus +0 -1313
@@ -1,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