morpheus-cli 4.1.14 → 4.2
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.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/library_container_types_interface.rb +1 -1
- data/lib/morpheus/api/library_instance_types_interface.rb +7 -7
- data/lib/morpheus/api/library_layouts_interface.rb +1 -1
- data/lib/morpheus/api/network_routers_interface.rb +101 -0
- data/lib/morpheus/api/tasks_interface.rb +12 -14
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/cli/apps.rb +15 -12
- data/lib/morpheus/cli/cli_command.rb +40 -2
- data/lib/morpheus/cli/clusters.rb +13 -7
- data/lib/morpheus/cli/cypher_command.rb +5 -2
- data/lib/morpheus/cli/hosts.rb +1 -1
- data/lib/morpheus/cli/instances.rb +21 -5
- data/lib/morpheus/cli/jobs_command.rb +83 -27
- data/lib/morpheus/cli/library_cluster_layouts_command.rb +12 -12
- data/lib/morpheus/cli/library_container_scripts_command.rb +52 -40
- data/lib/morpheus/cli/library_container_types_command.rb +2 -60
- data/lib/morpheus/cli/library_instance_types_command.rb +22 -1
- data/lib/morpheus/cli/library_layouts_command.rb +65 -65
- data/lib/morpheus/cli/library_option_lists_command.rb +72 -59
- data/lib/morpheus/cli/library_option_types_command.rb +30 -186
- data/lib/morpheus/cli/library_spec_templates_command.rb +39 -64
- data/lib/morpheus/cli/mixins/library_helper.rb +213 -0
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +89 -37
- data/lib/morpheus/cli/mixins/whoami_helper.rb +16 -1
- data/lib/morpheus/cli/network_routers_command.rb +1281 -0
- data/lib/morpheus/cli/networks_command.rb +164 -72
- data/lib/morpheus/cli/option_types.rb +187 -73
- data/lib/morpheus/cli/price_sets_command.rb +4 -4
- data/lib/morpheus/cli/prices_command.rb +15 -15
- data/lib/morpheus/cli/remote.rb +3 -3
- data/lib/morpheus/cli/service_plans_command.rb +17 -8
- data/lib/morpheus/cli/tasks.rb +437 -169
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +8 -0
- metadata +6 -3
@@ -19,7 +19,7 @@ module Morpheus::Cli::WhoamiHelper
|
|
19
19
|
exit 1
|
20
20
|
end
|
21
21
|
@is_master_account = whoami_response["isMasterAccount"]
|
22
|
-
|
22
|
+
@user_permissions = whoami_response["permissions"]
|
23
23
|
if whoami_response["appliance"]
|
24
24
|
@appliance_build_verison = whoami_response["appliance"]["buildVersion"]
|
25
25
|
else
|
@@ -42,4 +42,19 @@ module Morpheus::Cli::WhoamiHelper
|
|
42
42
|
end
|
43
43
|
@is_master_account
|
44
44
|
end
|
45
|
+
|
46
|
+
def current_user
|
47
|
+
if @current_user.nil?
|
48
|
+
load_whoami
|
49
|
+
end
|
50
|
+
@current_user
|
51
|
+
end
|
52
|
+
|
53
|
+
def current_user_permissions
|
54
|
+
if @user_permissions.nil?
|
55
|
+
load_whoami
|
56
|
+
end
|
57
|
+
@user_permissions
|
58
|
+
end
|
59
|
+
|
45
60
|
end
|
@@ -0,0 +1,1281 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'optparse'
|
3
|
+
require 'filesize'
|
4
|
+
require 'morpheus/cli/cli_command'
|
5
|
+
require 'morpheus/cli/mixins/infrastructure_helper'
|
6
|
+
|
7
|
+
class Morpheus::Cli::NetworkRoutersCommand
|
8
|
+
include Morpheus::Cli::CliCommand
|
9
|
+
include Morpheus::Cli::InfrastructureHelper
|
10
|
+
include Morpheus::Cli::ProvisioningHelper
|
11
|
+
include Morpheus::Cli::WhoamiHelper
|
12
|
+
|
13
|
+
set_command_name :'network-routers'
|
14
|
+
register_subcommands :list, :get, :firewall, :dhcp, :routes, :types, :type, :add, :update, :remove
|
15
|
+
register_subcommands :add_firewall_rule, :remove_firewall_rule
|
16
|
+
register_subcommands :add_route, :remove_route
|
17
|
+
register_subcommands :update_permissions
|
18
|
+
|
19
|
+
def initialize()
|
20
|
+
end
|
21
|
+
|
22
|
+
def connect(opts)
|
23
|
+
@api_client = establish_remote_appliance_connection(opts)
|
24
|
+
@network_routers_interface = @api_client.network_routers
|
25
|
+
@clouds_interface = @api_client.clouds
|
26
|
+
@options_interface = @api_client.options
|
27
|
+
@accounts_interface = @api_client.accounts
|
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, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
40
|
+
opts.footer = "List network routers."
|
41
|
+
end
|
42
|
+
optparse.parse!(args)
|
43
|
+
connect(options)
|
44
|
+
begin
|
45
|
+
params.merge!(parse_list_options(options))
|
46
|
+
@network_routers_interface.setopts(options)
|
47
|
+
if options[:dry_run]
|
48
|
+
print_dry_run @network_routers_interface.dry.list(params)
|
49
|
+
return
|
50
|
+
end
|
51
|
+
json_response = @network_routers_interface.list(params)
|
52
|
+
routers = json_response["networkRouters"]
|
53
|
+
if options[:json]
|
54
|
+
puts as_json(json_response, options, "networkRouters")
|
55
|
+
return 0
|
56
|
+
elsif options[:yaml]
|
57
|
+
puts as_yaml(json_response, options, "networkRouters")
|
58
|
+
return 0
|
59
|
+
elsif options[:csv]
|
60
|
+
puts records_as_csv(routers, options)
|
61
|
+
return 0
|
62
|
+
end
|
63
|
+
title = "Morpheus Network Routers"
|
64
|
+
subtitles = []
|
65
|
+
subtitles += parse_list_subtitles(options)
|
66
|
+
print_h1 title, subtitles
|
67
|
+
if routers.empty?
|
68
|
+
print cyan,"No network routers found.",reset,"\n"
|
69
|
+
else
|
70
|
+
# STATUS NAME ROUTER TYPE SERVICE NETWORKS EXTERNAL IP
|
71
|
+
rows = routers.collect {|router|
|
72
|
+
row = {
|
73
|
+
id: router['id'],
|
74
|
+
name: router['name'],
|
75
|
+
status: format_router_status(router),
|
76
|
+
router_type: (router['type'] || {})['name'],
|
77
|
+
group: router['site'] ? router['site']['name'] : 'Shared',
|
78
|
+
service: (router['networkServer'] || {})['name'],
|
79
|
+
networks: (router['externalNetwork'] || {})['name'],
|
80
|
+
external_ip: router['externalIp']
|
81
|
+
}
|
82
|
+
row
|
83
|
+
}
|
84
|
+
columns = [:id, :name, :status, :router_type, :group, :service, :networks, :external_ip]
|
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
|
+
if json_response['meta']
|
92
|
+
print_results_pagination(json_response, {:label => "network routers", :n_label => "network routers"})
|
93
|
+
else
|
94
|
+
print_results_pagination({'meta'=>{'total'=>rows.size,'size'=>rows.size,'max'=>options[:max] || rows.size,'offset'=>0}}, {:label => "network routers", :n_label => "network routers"})
|
95
|
+
end
|
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("[router]")
|
109
|
+
opts.on('--details', "Display details: firewall, DHCP, and routing." ) do
|
110
|
+
options[:details] = true
|
111
|
+
end
|
112
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
113
|
+
opts.footer = "Display network router details." + "\n" +
|
114
|
+
"[router] is required. This is the name or id of a network router."
|
115
|
+
end
|
116
|
+
optparse.parse!(args)
|
117
|
+
if args.count < 1
|
118
|
+
puts optparse
|
119
|
+
return 1
|
120
|
+
end
|
121
|
+
connect(options)
|
122
|
+
id_list = parse_id_list(args)
|
123
|
+
return run_command_for_each_arg(id_list) do |arg|
|
124
|
+
_get(arg, options)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def _get(id, options)
|
129
|
+
begin
|
130
|
+
@network_routers_interface.setopts(options)
|
131
|
+
if options[:dry_run]
|
132
|
+
if arg.to_s =~ /\A\d{1,}\Z/
|
133
|
+
print_dry_run @network_routers_interface.dry.get(arg.to_i)
|
134
|
+
else
|
135
|
+
print_dry_run @network_routers_interface.dry.list({name:arg})
|
136
|
+
end
|
137
|
+
return
|
138
|
+
end
|
139
|
+
router = find_router(id)
|
140
|
+
if router.nil?
|
141
|
+
return 1
|
142
|
+
end
|
143
|
+
|
144
|
+
json_response = {'networkRouter' => router}
|
145
|
+
|
146
|
+
if options[:json]
|
147
|
+
puts as_json(json_response, options, "networkRouter")
|
148
|
+
return 0
|
149
|
+
elsif options[:yaml]
|
150
|
+
puts as_yaml(json_response, options, "networkRouter")
|
151
|
+
return 0
|
152
|
+
elsif options[:csv]
|
153
|
+
puts records_as_csv([json_response['networkRouter']], options)
|
154
|
+
return 0
|
155
|
+
end
|
156
|
+
|
157
|
+
print_h1 "Network Router Details"
|
158
|
+
print cyan
|
159
|
+
description_cols = {
|
160
|
+
"ID" => lambda {|it| it['id'] },
|
161
|
+
"Name" => lambda {|it| it['name'] },
|
162
|
+
"Status" => lambda {|it| format_router_status(it)},
|
163
|
+
"Type" => lambda {|it| it['type']['name']},
|
164
|
+
"Service" => lambda {|it| it['networkServer'] ? it['networkServer']['name'] : nil},
|
165
|
+
"Group" => lambda {|it| it['site'] ? it['site']['name'] : 'Shared'},
|
166
|
+
# "Integration" => lambda {|it| router_integration_label(it)},
|
167
|
+
"Provider ID" => lambda {|it| it['providerId'] || it['externalId']},
|
168
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
169
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
170
|
+
}
|
171
|
+
|
172
|
+
print_description_list(description_cols, router)
|
173
|
+
|
174
|
+
if (router['interfaces'] || []).count > 0
|
175
|
+
rows = router['interfaces'].sort_by{|it| it['networkPosition']}.collect do |it|
|
176
|
+
{
|
177
|
+
position: it['networkPosition'],
|
178
|
+
name: it['name'],
|
179
|
+
type: it['interfaceType'],
|
180
|
+
network: (it['network'] || {})['name'],
|
181
|
+
link: it['externalLink'],
|
182
|
+
ip_address: it['ipAddress'],
|
183
|
+
subnet: it['cidr'],
|
184
|
+
enabled: format_boolean(it['enabled'])
|
185
|
+
}
|
186
|
+
end
|
187
|
+
print_h2 "Interfaces"
|
188
|
+
puts as_pretty_table(rows, [:position, :name, :type, :link, :network, :ip_address, :subnet, :enabled])
|
189
|
+
end
|
190
|
+
|
191
|
+
if router['type']['hasFirewall']
|
192
|
+
print_h2 "Firewall"
|
193
|
+
print cyan
|
194
|
+
print_firewall(router, options[:details])
|
195
|
+
end
|
196
|
+
if router['type']['hasDhcp']
|
197
|
+
print_h2 "DHCP"
|
198
|
+
print cyan
|
199
|
+
print_dhcp(router, options[:details])
|
200
|
+
end
|
201
|
+
if router['type']['hasRouting'] && options[:details]
|
202
|
+
print_h2 "Routes"
|
203
|
+
print cyan
|
204
|
+
print_routes(router)
|
205
|
+
end
|
206
|
+
if router['permissions'] && options[:details]
|
207
|
+
print_h2 "Tenant Permissions"
|
208
|
+
print cyan
|
209
|
+
description_cols = {
|
210
|
+
"Visibility" => lambda{|it| it['permissions']['visibility']},
|
211
|
+
"Tenants" => lambda{|it|
|
212
|
+
accounts = (it['permissions']['tenantPermissions'] || {})['accounts'] || []
|
213
|
+
accounts.count > 0 ? accounts.join(', ') : ''
|
214
|
+
}
|
215
|
+
}
|
216
|
+
print_description_list(description_cols, router)
|
217
|
+
println
|
218
|
+
end
|
219
|
+
print reset
|
220
|
+
rescue RestClient::Exception => e
|
221
|
+
print_rest_exception(e, options)
|
222
|
+
return 1
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def add(args)
|
227
|
+
options = {:options=>{}}
|
228
|
+
params = {}
|
229
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
230
|
+
opts.banner = subcommand_usage("[type] [name] [options]")
|
231
|
+
opts.on( '-g', '--group GROUP', "Group Name or ID" ) do |val|
|
232
|
+
options[:group] = val
|
233
|
+
end
|
234
|
+
opts.on('-t', '--type VALUE', String, "Name or ID of router type") do |val|
|
235
|
+
options[:options]['routerType'] = val
|
236
|
+
end
|
237
|
+
opts.on('-n', '--name VALUE', String, "Name for this network router") do |val|
|
238
|
+
options[:options]['name'] = val
|
239
|
+
end
|
240
|
+
opts.on('-D', '--description VALUE', String, "Description") do |val|
|
241
|
+
options[:options]['description'] = val
|
242
|
+
end
|
243
|
+
opts.on('-s', '--server VALUE', String, "Network server") do |val|
|
244
|
+
options[:network_server] = val
|
245
|
+
end
|
246
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
|
247
|
+
options[:cloud] = val
|
248
|
+
end
|
249
|
+
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the network router. Default is on") do |val|
|
250
|
+
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
251
|
+
end
|
252
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
253
|
+
opts.footer = "Create a network router."
|
254
|
+
end
|
255
|
+
optparse.parse!(args)
|
256
|
+
connect(options)
|
257
|
+
if args.count > 2
|
258
|
+
print_error Morpheus::Terminal.angry_prompt
|
259
|
+
puts_error "wrong number of arguments, expected 0-2 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
260
|
+
return 1
|
261
|
+
end
|
262
|
+
if args.count > 0
|
263
|
+
options[:options]['routerType'] = args[0]
|
264
|
+
end
|
265
|
+
if args.count > 1
|
266
|
+
params['name'] = args[1]
|
267
|
+
end
|
268
|
+
begin
|
269
|
+
if options[:payload]
|
270
|
+
payload = options[:payload]
|
271
|
+
else
|
272
|
+
router_type = prompt_router_type(options)
|
273
|
+
router = {'type' => {'id' => router_type['id']}, 'enabled' => options[:enabled].nil? || options[:enabled] }
|
274
|
+
|
275
|
+
group_options = available_groups
|
276
|
+
|
277
|
+
if options[:group]
|
278
|
+
group = avail_groups.find {|it| it['name'] == options[:group] || "#{it['value']}" == "#{options[:group]}".downcase}
|
279
|
+
|
280
|
+
if group.nil?
|
281
|
+
print_red_alert "Group #{options[:group]} not found"
|
282
|
+
exit 1
|
283
|
+
end
|
284
|
+
router['site'] = {'id' => group['value']}
|
285
|
+
else
|
286
|
+
default_group = group_options.find {|it| it['value'] == 'shared'} ? 'shared' : nil
|
287
|
+
group_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'type' => 'select', 'fieldLabel' => 'Group', 'required' => true, 'selectOptions' => group_options, 'defaultValue' => default_group}], options[:options], @api_client, params, nil, true)['group']
|
288
|
+
router['site'] = {'id' => group_id}
|
289
|
+
end
|
290
|
+
|
291
|
+
# add router type to be used for option prompts
|
292
|
+
params = {'router' => {'site' => router['site']}, 'routerType' => {'id' => router_type['id']}}
|
293
|
+
|
294
|
+
if router_type['hasNetworkServer']
|
295
|
+
if options[:server]
|
296
|
+
server = find_network_server(options[:server])
|
297
|
+
if server.nil?
|
298
|
+
print_red_alert "Network server #{options[:server]} not found"
|
299
|
+
exit 1
|
300
|
+
end
|
301
|
+
else
|
302
|
+
server_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkServer', 'type' => 'select', 'fieldLabel' => 'Network Server', 'required' => true, 'optionSource' => 'networkServer'}], options[:options], @api_client, params, nil, true)['networkServer']
|
303
|
+
server = {'id' => server_id}
|
304
|
+
end
|
305
|
+
router['networkServer'] = {'id' => server['id']}
|
306
|
+
params['networkServerId'] = server['id']
|
307
|
+
else
|
308
|
+
# prompt cloud
|
309
|
+
if options[:cloud]
|
310
|
+
cloud = find_cloud_by_name_or_id(options[:cloud])
|
311
|
+
if cloud.nil?
|
312
|
+
print_red_alert "Cloud #{options[:cloud]} not found"
|
313
|
+
exit 1
|
314
|
+
end
|
315
|
+
else
|
316
|
+
cloud_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'zone', 'type' => 'select', 'fieldLabel' => 'Cloud', 'required' => true, 'optionSource' => 'routerTypeCloud'}], options[:options], @api_client, params, nil, true)['zone']
|
317
|
+
cloud = {'id' => cloud_id}
|
318
|
+
end
|
319
|
+
router['zone'] = params['zone'] = {'id' => cloud['id']}
|
320
|
+
end
|
321
|
+
|
322
|
+
# prompt for enabled
|
323
|
+
router['enabled'] = options[:enabled].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enable Router.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on' : options[:enabled]
|
324
|
+
|
325
|
+
option_types = router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
326
|
+
|
327
|
+
# prompt options
|
328
|
+
option_opts = options[:options].deep_merge!({'config' => options[:options].clone})
|
329
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, option_opts.merge({:context_map => {'networkRouter' => ''}}), @api_client, params)
|
330
|
+
payload = {'networkRouter' => router.deep_merge(option_result)}
|
331
|
+
payload['networkRouter']['config'] = option_result['config'] if option_result['config']
|
332
|
+
end
|
333
|
+
|
334
|
+
@network_routers_interface.setopts(options)
|
335
|
+
if options[:dry_run]
|
336
|
+
print_dry_run @network_routers_interface.dry.create(payload)
|
337
|
+
return
|
338
|
+
end
|
339
|
+
|
340
|
+
json_response = @network_routers_interface.create(payload)
|
341
|
+
|
342
|
+
if options[:json]
|
343
|
+
print JSON.pretty_generate(json_response), "\n"
|
344
|
+
return
|
345
|
+
end
|
346
|
+
print_green_success "Added Network Router #{payload['networkRouter']['name']}"
|
347
|
+
_get(json_response['id'], options)
|
348
|
+
rescue RestClient::Exception => e
|
349
|
+
print_rest_exception(e, options)
|
350
|
+
exit 1
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def update(args)
|
355
|
+
options = {:options=>{}}
|
356
|
+
params = {}
|
357
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
358
|
+
opts.banner = subcommand_usage("[router]")
|
359
|
+
opts.on('-D', '--description VALUE', String, "Description") do |val|
|
360
|
+
params['description'] = val
|
361
|
+
end
|
362
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
363
|
+
opts.footer = "Update a network router."
|
364
|
+
end
|
365
|
+
optparse.parse!(args)
|
366
|
+
connect(options)
|
367
|
+
if args.count != 1
|
368
|
+
print_error Morpheus::Terminal.angry_prompt
|
369
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
370
|
+
return 1
|
371
|
+
end
|
372
|
+
|
373
|
+
begin
|
374
|
+
router = find_router(args[0])
|
375
|
+
if router.nil?
|
376
|
+
return 1
|
377
|
+
end
|
378
|
+
|
379
|
+
payload = parse_payload(options)
|
380
|
+
|
381
|
+
if payload.nil?
|
382
|
+
if !options[:enabled].nil?
|
383
|
+
params['enabled'] = options[:enabled]
|
384
|
+
end
|
385
|
+
|
386
|
+
if options[:options]
|
387
|
+
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) || ['name', 'routerType'].include?(k)})
|
388
|
+
end
|
389
|
+
payload = {'networkRouter' => params}
|
390
|
+
end
|
391
|
+
|
392
|
+
if payload['networkRouter'].empty?
|
393
|
+
print_green_success "Nothing to update"
|
394
|
+
return
|
395
|
+
end
|
396
|
+
|
397
|
+
@network_routers_interface.setopts(options)
|
398
|
+
if options[:dry_run]
|
399
|
+
print_dry_run @network_routers_interface.dry.update(router['id'], payload)
|
400
|
+
return
|
401
|
+
end
|
402
|
+
|
403
|
+
json_response = @network_routers_interface.update(router['id'], payload)
|
404
|
+
|
405
|
+
if options[:json]
|
406
|
+
puts as_json(json_response, options)
|
407
|
+
elsif !options[:quiet]
|
408
|
+
if json_response['success']
|
409
|
+
print_green_success "Network router updated"
|
410
|
+
_get(router['id'], options)
|
411
|
+
else
|
412
|
+
print_red_alert "Error updating network router: #{json_response['msg'] || json_response['errors']}"
|
413
|
+
end
|
414
|
+
end
|
415
|
+
return 0
|
416
|
+
rescue RestClient::Exception => e
|
417
|
+
print_rest_exception(e, options)
|
418
|
+
exit 1
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def remove(args)
|
423
|
+
options = {}
|
424
|
+
query_params = {}
|
425
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
426
|
+
opts.banner = subcommand_usage("[router]")
|
427
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
428
|
+
opts.footer = "Delete a network router.\n" +
|
429
|
+
"[router] is required. This is the name or id of an existing network router."
|
430
|
+
end
|
431
|
+
optparse.parse!(args)
|
432
|
+
if args.count != 1
|
433
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
|
434
|
+
end
|
435
|
+
connect(options)
|
436
|
+
|
437
|
+
begin
|
438
|
+
router = find_router(args[0])
|
439
|
+
|
440
|
+
return if !router
|
441
|
+
|
442
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the network router '#{router['name']}'?", options)
|
443
|
+
return 9, "aborted command"
|
444
|
+
end
|
445
|
+
@network_routers_interface.setopts(options)
|
446
|
+
if options[:dry_run]
|
447
|
+
print_dry_run @network_routers_interface.dry.destroy(router['id'], query_params)
|
448
|
+
return
|
449
|
+
end
|
450
|
+
json_response = @network_routers_interface.destroy(router['id'], query_params)
|
451
|
+
if options[:json]
|
452
|
+
print JSON.pretty_generate(json_response)
|
453
|
+
print "\n"
|
454
|
+
elsif !options[:quiet]
|
455
|
+
print_green_success "Network router #{router['name']} is being removed..."
|
456
|
+
end
|
457
|
+
rescue RestClient::Exception => e
|
458
|
+
print_rest_exception(e, options)
|
459
|
+
exit 1
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
def firewall(args)
|
464
|
+
options = {}
|
465
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
466
|
+
opts.banner = subcommand_usage("[router]")
|
467
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
468
|
+
opts.footer = "Display network router firewall details." + "\n" +
|
469
|
+
"[router] is required. This is the name or id of a network router."
|
470
|
+
end
|
471
|
+
|
472
|
+
optparse.parse!(args)
|
473
|
+
connect(options)
|
474
|
+
|
475
|
+
if args.count < 1
|
476
|
+
puts optparse
|
477
|
+
return 1
|
478
|
+
end
|
479
|
+
_firewall(args[0], options)
|
480
|
+
end
|
481
|
+
|
482
|
+
def _firewall(router_id, options)
|
483
|
+
begin
|
484
|
+
@network_routers_interface.setopts(options)
|
485
|
+
if options[:dry_run]
|
486
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
487
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
488
|
+
else
|
489
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
490
|
+
end
|
491
|
+
return
|
492
|
+
end
|
493
|
+
router = find_router(router_id)
|
494
|
+
if router.nil?
|
495
|
+
return 1
|
496
|
+
end
|
497
|
+
|
498
|
+
json_response = {'networkRouter' => router}
|
499
|
+
|
500
|
+
if options[:json]
|
501
|
+
puts as_json(json_response, options, "networkRouter")
|
502
|
+
return 0
|
503
|
+
elsif options[:yaml]
|
504
|
+
puts as_yaml(json_response, options, "networkRouter")
|
505
|
+
return 0
|
506
|
+
elsif options[:csv]
|
507
|
+
puts records_as_csv([json_response['networkRouter']], options)
|
508
|
+
return 0
|
509
|
+
end
|
510
|
+
|
511
|
+
if !options[:rules_only]
|
512
|
+
print_h1 "Network Router Firewall Details for: #{router['name']}"
|
513
|
+
end
|
514
|
+
|
515
|
+
print cyan
|
516
|
+
|
517
|
+
if router['type']['hasFirewall']
|
518
|
+
print_firewall(router, true, options[:rules_only])
|
519
|
+
else
|
520
|
+
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
521
|
+
end
|
522
|
+
println reset
|
523
|
+
rescue RestClient::Exception => e
|
524
|
+
print_rest_exception(e, options)
|
525
|
+
return 1
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
def add_firewall_rule(args)
|
530
|
+
options = {:options=>{}}
|
531
|
+
params = {}
|
532
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
533
|
+
opts.banner = subcommand_usage("[router] [name]")
|
534
|
+
opts.on('-n', '--name VALUE', String, "Name for this firewall rule") do |val|
|
535
|
+
params['name'] = val
|
536
|
+
end
|
537
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
538
|
+
opts.footer = "Create a network router firewall rule."
|
539
|
+
end
|
540
|
+
optparse.parse!(args)
|
541
|
+
connect(options)
|
542
|
+
if args.count < 1 || args.count > 2
|
543
|
+
print_error Morpheus::Terminal.angry_prompt
|
544
|
+
puts_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
545
|
+
return 1
|
546
|
+
end
|
547
|
+
if args.count > 1
|
548
|
+
params['name'] = args[1]
|
549
|
+
end
|
550
|
+
begin
|
551
|
+
router = find_router(args[0])
|
552
|
+
|
553
|
+
if router.nil?
|
554
|
+
return 1
|
555
|
+
end
|
556
|
+
|
557
|
+
if !router['type']['hasFirewall']
|
558
|
+
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
559
|
+
return 1
|
560
|
+
end
|
561
|
+
|
562
|
+
if options[:payload]
|
563
|
+
payload = options[:payload]
|
564
|
+
else
|
565
|
+
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Rule Name', 'required' => true}], options[:options], @api_client, params)['name']
|
566
|
+
|
567
|
+
option_types = router['type']['ruleOptionTypes'].reject {|it| ['name'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
568
|
+
|
569
|
+
# prompt options
|
570
|
+
api_params = {}
|
571
|
+
api_params['networkServerId'] = router['networkServer']['id'] if router['networkServer']
|
572
|
+
api_params['zoneId'] = router['zone']['id'] if router['networkServer'].nil?
|
573
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'networkRouter' => ''}}), @api_client, api_params, nil, true)
|
574
|
+
payload = {'rule' => params.deep_merge(option_result)}
|
575
|
+
end
|
576
|
+
|
577
|
+
@network_routers_interface.setopts(options)
|
578
|
+
if options[:dry_run]
|
579
|
+
print_dry_run @network_routers_interface.dry.create_firewall_rule(router['id'], payload)
|
580
|
+
return
|
581
|
+
end
|
582
|
+
|
583
|
+
json_response = @network_routers_interface.create_firewall_rule(router['id'], payload)
|
584
|
+
|
585
|
+
if options[:json]
|
586
|
+
print JSON.pretty_generate(json_response), "\n"
|
587
|
+
return
|
588
|
+
end
|
589
|
+
print_green_success "\nAdded Network Router Firewall Rule #{payload['rule']['name']}\n"
|
590
|
+
_firewall(router['id'], options.merge({:rules_only => true}))
|
591
|
+
rescue RestClient::Exception => e
|
592
|
+
print_rest_exception(e, options)
|
593
|
+
exit 1
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
def remove_firewall_rule(args)
|
598
|
+
options = {}
|
599
|
+
query_params = {}
|
600
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
601
|
+
opts.banner = subcommand_usage("[router] [rule]")
|
602
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
603
|
+
opts.footer = "Delete a network router firewall rule.\n" +
|
604
|
+
"[router] is required. This is the name or id of an existing network router."
|
605
|
+
"[rule] is required. This is the name or id of an existing network router firewall rule."
|
606
|
+
end
|
607
|
+
optparse.parse!(args)
|
608
|
+
if args.count != 2
|
609
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
610
|
+
end
|
611
|
+
connect(options)
|
612
|
+
|
613
|
+
begin
|
614
|
+
router = find_router(args[0])
|
615
|
+
return if !router
|
616
|
+
|
617
|
+
rule = router['firewall'] && router['firewall']['rules'] ? router['firewall']['rules'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
618
|
+
|
619
|
+
if !rule
|
620
|
+
print_red_alert "Firewall rule #{args[1]} not found for router #{router['name']}"
|
621
|
+
exit 1
|
622
|
+
end
|
623
|
+
|
624
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the firewall rule '#{rule['name']}' from router '#{router['name']}'?", options)
|
625
|
+
return 9, "aborted command"
|
626
|
+
end
|
627
|
+
@network_routers_interface.setopts(options)
|
628
|
+
if options[:dry_run]
|
629
|
+
print_dry_run @network_routers_interface.dry.destroy_firewall_rule(router['id'], rule['id'])
|
630
|
+
return
|
631
|
+
end
|
632
|
+
json_response = @network_routers_interface.destroy_firewall_rule(router['id'], rule['id'])
|
633
|
+
if options[:json]
|
634
|
+
print JSON.pretty_generate(json_response)
|
635
|
+
print "\n"
|
636
|
+
elsif !options[:quiet]
|
637
|
+
print_green_success "\nFirewall rule #{rule['name']} for router #{router['name']} is being removed...\n"
|
638
|
+
_firewall(router['id'], options.merge({:rules_only => true}))
|
639
|
+
end
|
640
|
+
rescue RestClient::Exception => e
|
641
|
+
print_rest_exception(e, options)
|
642
|
+
exit 1
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
def dhcp(args)
|
647
|
+
options = {}
|
648
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
649
|
+
opts.banner = subcommand_usage("[router]")
|
650
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
651
|
+
opts.footer = "Display network router DHCP details." + "\n" +
|
652
|
+
"[router] is required. This is the name or id of a network router."
|
653
|
+
end
|
654
|
+
|
655
|
+
optparse.parse!(args)
|
656
|
+
connect(options)
|
657
|
+
|
658
|
+
if args.count < 1
|
659
|
+
puts optparse
|
660
|
+
return 1
|
661
|
+
end
|
662
|
+
|
663
|
+
begin
|
664
|
+
@network_routers_interface.setopts(options)
|
665
|
+
if options[:dry_run]
|
666
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
667
|
+
print_dry_run @network_routers_interface.dry.get(args[0].to_i)
|
668
|
+
else
|
669
|
+
print_dry_run @network_routers_interface.dry.list({name:args[0]})
|
670
|
+
end
|
671
|
+
return
|
672
|
+
end
|
673
|
+
router = find_router(args[0])
|
674
|
+
if router.nil?
|
675
|
+
return 1
|
676
|
+
end
|
677
|
+
|
678
|
+
json_response = {'networkRouter' => router}
|
679
|
+
|
680
|
+
if options[:json]
|
681
|
+
puts as_json(json_response, options, "networkRouter")
|
682
|
+
return 0
|
683
|
+
elsif options[:yaml]
|
684
|
+
puts as_yaml(json_response, options, "networkRouter")
|
685
|
+
return 0
|
686
|
+
elsif options[:csv]
|
687
|
+
puts records_as_csv([json_response['networkRouter']], options)
|
688
|
+
return 0
|
689
|
+
end
|
690
|
+
|
691
|
+
print_h1 "Network Router DHCP Details for: #{router['name']}"
|
692
|
+
print cyan
|
693
|
+
|
694
|
+
if router['type']['hasDhcp']
|
695
|
+
print_dhcp(router, true)
|
696
|
+
else
|
697
|
+
print_red_alert "DHCP not supported for #{router['type']['name']}"
|
698
|
+
end
|
699
|
+
println reset
|
700
|
+
rescue RestClient::Exception => e
|
701
|
+
print_rest_exception(e, options)
|
702
|
+
return 1
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
706
|
+
def routes(args)
|
707
|
+
options = {}
|
708
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
709
|
+
opts.banner = subcommand_usage("[router]")
|
710
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
711
|
+
opts.footer = "List network router routes." + "\n" +
|
712
|
+
"[router] is required. This is the name or id of a network router."
|
713
|
+
end
|
714
|
+
|
715
|
+
optparse.parse!(args)
|
716
|
+
connect(options)
|
717
|
+
|
718
|
+
if args.count < 1
|
719
|
+
puts optparse
|
720
|
+
return 1
|
721
|
+
end
|
722
|
+
_routes(args[0], options)
|
723
|
+
end
|
724
|
+
|
725
|
+
def _routes(router_id, options)
|
726
|
+
begin
|
727
|
+
@network_routers_interface.setopts(options)
|
728
|
+
if options[:dry_run]
|
729
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
730
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
731
|
+
else
|
732
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
733
|
+
end
|
734
|
+
return
|
735
|
+
end
|
736
|
+
router = find_router(router_id)
|
737
|
+
if router.nil?
|
738
|
+
return 1
|
739
|
+
end
|
740
|
+
|
741
|
+
json_response = {'networkRouter' => router}
|
742
|
+
|
743
|
+
if options[:json]
|
744
|
+
puts as_json(json_response, options, "networkRouter")
|
745
|
+
return 0
|
746
|
+
elsif options[:yaml]
|
747
|
+
puts as_yaml(json_response, options, "networkRouter")
|
748
|
+
return 0
|
749
|
+
elsif options[:csv]
|
750
|
+
puts records_as_csv([json_response['networkRouter']], options)
|
751
|
+
return 0
|
752
|
+
end
|
753
|
+
|
754
|
+
print_h1 "Network Router Routes for: #{router['name']}"
|
755
|
+
print cyan
|
756
|
+
|
757
|
+
if router['type']['hasRouting']
|
758
|
+
print_routes(router)
|
759
|
+
else
|
760
|
+
print_red_alert "Routes not supported for #{router['type']['name']}"
|
761
|
+
end
|
762
|
+
print reset
|
763
|
+
rescue RestClient::Exception => e
|
764
|
+
print_rest_exception(e, options)
|
765
|
+
return 1
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
def add_route(args)
|
770
|
+
options = {:options=>{}}
|
771
|
+
params = {}
|
772
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
773
|
+
opts.banner = subcommand_usage("[router] [name]")
|
774
|
+
opts.on('-n', '--name VALUE', String, "Name for this route") do |val|
|
775
|
+
params['name'] = val
|
776
|
+
end
|
777
|
+
opts.on('-D', '--description VALUE', String, "Description") do |val|
|
778
|
+
params['description'] = val
|
779
|
+
end
|
780
|
+
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the route. Default is on") do |val|
|
781
|
+
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
782
|
+
end
|
783
|
+
opts.on('--default [on|off]', String, "Can be used to enable / disable as default route. Default is off") do |val|
|
784
|
+
options[:defaultRoute] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
785
|
+
end
|
786
|
+
opts.on('--source VALUE', String, "Network for this route") do |val|
|
787
|
+
params['source'] = val
|
788
|
+
end
|
789
|
+
opts.on('--destination VALUE', String, "Next hop for this route") do |val|
|
790
|
+
params['destination'] = val
|
791
|
+
end
|
792
|
+
opts.on('--mtu VALUE', String, "MTU for this route") do |val|
|
793
|
+
params['networkMtu'] = val
|
794
|
+
end
|
795
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
796
|
+
opts.footer = "Create a network router route."
|
797
|
+
end
|
798
|
+
optparse.parse!(args)
|
799
|
+
connect(options)
|
800
|
+
if args.count < 1 || args.count > 2
|
801
|
+
print_error Morpheus::Terminal.angry_prompt
|
802
|
+
puts_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
803
|
+
return 1
|
804
|
+
end
|
805
|
+
if args.count > 1
|
806
|
+
params['name'] = args[1]
|
807
|
+
end
|
808
|
+
begin
|
809
|
+
router = find_router(args[0])
|
810
|
+
|
811
|
+
if router.nil?
|
812
|
+
return 1
|
813
|
+
end
|
814
|
+
|
815
|
+
if !router['type']['hasRouting']
|
816
|
+
print_red_alert "Routes not supported for #{router['type']['name']}"
|
817
|
+
return 1
|
818
|
+
end
|
819
|
+
|
820
|
+
if options[:payload]
|
821
|
+
payload = options[:payload]
|
822
|
+
else
|
823
|
+
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Name', 'required' => true}], options[:options], @api_client, params)['name']
|
824
|
+
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => true}], options[:options], @api_client, params)['description']
|
825
|
+
|
826
|
+
# prompt for enabled if not set
|
827
|
+
params['enabled'] = options[:enabled].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enabling Route.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on' : options[:enabled]
|
828
|
+
|
829
|
+
# default ruote
|
830
|
+
params['defaultRoute'] = options[:defaultRoute].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultRoute', 'fieldLabel' => 'Default Route', 'type' => 'checkbox', 'description' => 'Default Route.', 'defaultValue' => false, 'required' => false}], options, @api_client, {})['defaultRoute'] == 'on' : options[:defaultRoute]
|
831
|
+
|
832
|
+
params['source'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'type' => 'text', 'fieldLabel' => 'Network', 'required' => true}], options[:options], @api_client, params)['source']
|
833
|
+
params['destination'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'destination', 'type' => 'text', 'fieldLabel' => 'Next Hop', 'required' => true}], options[:options], @api_client, params)['destination']
|
834
|
+
params['networkMtu'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkMtu', 'type' => 'text', 'fieldLabel' => 'MTU', 'required' => true}], options[:options], @api_client, params)['networkMtu']
|
835
|
+
|
836
|
+
payload = {'route' => params}
|
837
|
+
end
|
838
|
+
|
839
|
+
@network_routers_interface.setopts(options)
|
840
|
+
if options[:dry_run]
|
841
|
+
print_dry_run @network_routers_interface.dry.create_route(router['id'], payload)
|
842
|
+
return
|
843
|
+
end
|
844
|
+
|
845
|
+
json_response = @network_routers_interface.create_route(router['id'], payload)
|
846
|
+
|
847
|
+
if options[:json]
|
848
|
+
print JSON.pretty_generate(json_response), "\n"
|
849
|
+
return
|
850
|
+
end
|
851
|
+
print_green_success "\nAdded Network Router Route #{payload['route']['name']}"
|
852
|
+
_routes(router['id'], options)
|
853
|
+
rescue RestClient::Exception => e
|
854
|
+
print_rest_exception(e, options)
|
855
|
+
exit 1
|
856
|
+
end
|
857
|
+
end
|
858
|
+
|
859
|
+
def remove_route(args)
|
860
|
+
options = {}
|
861
|
+
query_params = {}
|
862
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
863
|
+
opts.banner = subcommand_usage("[router] [rule]")
|
864
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
865
|
+
opts.footer = "Delete a network router route.\n" +
|
866
|
+
"[router] is required. This is the name or id of an existing network router."
|
867
|
+
"[route] is required. This is the name or id of an existing network router route."
|
868
|
+
end
|
869
|
+
optparse.parse!(args)
|
870
|
+
if args.count != 2
|
871
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
872
|
+
end
|
873
|
+
connect(options)
|
874
|
+
|
875
|
+
begin
|
876
|
+
router = find_router(args[0])
|
877
|
+
return if !router
|
878
|
+
|
879
|
+
route = router['routes'] ? router['routes'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
880
|
+
|
881
|
+
if !route
|
882
|
+
print_red_alert "Route #{args[1]} not found for router #{router['name']}"
|
883
|
+
exit 1
|
884
|
+
end
|
885
|
+
|
886
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the route '#{route['name']}' from router '#{router['name']}'?", options)
|
887
|
+
return 9, "aborted command"
|
888
|
+
end
|
889
|
+
@network_routers_interface.setopts(options)
|
890
|
+
if options[:dry_run]
|
891
|
+
print_dry_run @network_routers_interface.dry.destroy_route(router['id'], route['id'])
|
892
|
+
return
|
893
|
+
end
|
894
|
+
json_response = @network_routers_interface.destroy_route(router['id'], route['id'])
|
895
|
+
if options[:json]
|
896
|
+
print JSON.pretty_generate(json_response)
|
897
|
+
print "\n"
|
898
|
+
elsif !options[:quiet]
|
899
|
+
print_green_success "\nRoute #{route['name']} for router #{router['name']} is being removed..."
|
900
|
+
_routes(router['id'], options)
|
901
|
+
end
|
902
|
+
rescue RestClient::Exception => e
|
903
|
+
print_rest_exception(e, options)
|
904
|
+
exit 1
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
def types(args)
|
909
|
+
options = {}
|
910
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
911
|
+
opts.banner = subcommand_usage()
|
912
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
913
|
+
opts.footer = "List network router types."
|
914
|
+
end
|
915
|
+
optparse.parse!(args)
|
916
|
+
connect(options)
|
917
|
+
begin
|
918
|
+
params = {}
|
919
|
+
params.merge!(parse_list_options(options))
|
920
|
+
|
921
|
+
@network_routers_interface.setopts(options)
|
922
|
+
if options[:dry_run]
|
923
|
+
print_dry_run @network_routers_interface.dry.types(params)
|
924
|
+
return
|
925
|
+
end
|
926
|
+
|
927
|
+
json_response = @network_routers_interface.types(params)
|
928
|
+
|
929
|
+
if options[:json]
|
930
|
+
print JSON.pretty_generate(json_response)
|
931
|
+
print "\n"
|
932
|
+
return
|
933
|
+
end
|
934
|
+
|
935
|
+
title = "Morpheus Network Router Types"
|
936
|
+
subtitles = []
|
937
|
+
subtitles += parse_list_subtitles(options)
|
938
|
+
print_h1 title, subtitles
|
939
|
+
|
940
|
+
router_types = json_response['networkRouterTypes']
|
941
|
+
|
942
|
+
if router_types.empty?
|
943
|
+
println yellow,"No network router types found.",reset
|
944
|
+
else
|
945
|
+
print as_pretty_table(router_types, {'ID' => 'id', 'NAME' => 'name'}, options)
|
946
|
+
end
|
947
|
+
println reset
|
948
|
+
return 0
|
949
|
+
rescue RestClient::Exception => e
|
950
|
+
print_rest_exception(e, options)
|
951
|
+
exit 1
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
def type(args)
|
956
|
+
options = {}
|
957
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
958
|
+
opts.banner = subcommand_usage("[type]")
|
959
|
+
opts.on('-t', '--type VALUE', String, "Name or ID of router type") do |val|
|
960
|
+
options[:options]['routerType'] = val
|
961
|
+
end
|
962
|
+
build_common_options(opts, options, [:list, :json, :dry_run, :remote])
|
963
|
+
opts.footer = "Display network router type details."
|
964
|
+
end
|
965
|
+
optparse.parse!(args)
|
966
|
+
|
967
|
+
if args.count > 1
|
968
|
+
print_error Morpheus::Terminal.angry_prompt
|
969
|
+
puts_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
970
|
+
return 1
|
971
|
+
end
|
972
|
+
|
973
|
+
if args.count > 0
|
974
|
+
options[:options]['routerType'] = args[0]
|
975
|
+
end
|
976
|
+
|
977
|
+
begin
|
978
|
+
connect(options)
|
979
|
+
@network_routers_interface.setopts(options)
|
980
|
+
if options[:dry_run]
|
981
|
+
print_dry_run @network_routers_interface.dry.types(params)
|
982
|
+
return
|
983
|
+
end
|
984
|
+
|
985
|
+
router_type = prompt_router_type(options)
|
986
|
+
|
987
|
+
if options[:json]
|
988
|
+
print JSON.pretty_generate({'networkRouterType' => router_type})
|
989
|
+
print "\n"
|
990
|
+
return
|
991
|
+
end
|
992
|
+
|
993
|
+
print_h1 "Network Router Type Details for: #{router_type['name']}"
|
994
|
+
print cyan
|
995
|
+
|
996
|
+
description_cols = {
|
997
|
+
"ID" => lambda {|it| it['id'] },
|
998
|
+
"Name" => lambda {|it| it['name'] },
|
999
|
+
"Code" => lambda {|it| it['code'] },
|
1000
|
+
"Enabled" => lambda {|it| format_boolean(it['enabled'])},
|
1001
|
+
"Creatable" => lambda {|it| format_boolean(it['creatable'])},
|
1002
|
+
"Selectable" => lambda {|it| format_boolean(it['selectable'])},
|
1003
|
+
"Firewall" => lambda {|it| format_boolean(it['hasFirewall'])},
|
1004
|
+
"DHCP" => lambda {|it| format_boolean(it['hasDhcp'])},
|
1005
|
+
"Routing" => lambda {|it| format_boolean(it['hasRouting'])},
|
1006
|
+
"Network Server" => lambda {|it| format_boolean(it['hasNetworkServer'])}
|
1007
|
+
}
|
1008
|
+
print_description_list(description_cols, router_type)
|
1009
|
+
|
1010
|
+
if router_type['optionTypes'].count > 0
|
1011
|
+
println cyan
|
1012
|
+
print Morpheus::Cli::OptionTypes.display_option_types_help(
|
1013
|
+
router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName'])},
|
1014
|
+
{:include_context => true, :context_map => {'networkRouter' => ''}, :color => cyan, :title => "Available Router Options"}
|
1015
|
+
)
|
1016
|
+
end
|
1017
|
+
print reset
|
1018
|
+
return 0
|
1019
|
+
rescue RestClient::Exception => e
|
1020
|
+
print_rest_exception(e, options)
|
1021
|
+
exit 1
|
1022
|
+
end
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def update_permissions(args)
|
1026
|
+
options = {}
|
1027
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1028
|
+
opts.banner = subcommand_usage( "[router]")
|
1029
|
+
add_perms_options(opts, options, ['plans', 'groups'])
|
1030
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
1031
|
+
opts.footer = "Update a network router permissions.\n" +
|
1032
|
+
"[router] is required. This is the name or id of an existing network router."
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
optparse.parse!(args)
|
1036
|
+
if args.count != 1
|
1037
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
|
1038
|
+
end
|
1039
|
+
connect(options)
|
1040
|
+
|
1041
|
+
begin
|
1042
|
+
if !is_master_account
|
1043
|
+
print_red_alert "Permissions only available for master account"
|
1044
|
+
return 1
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
router = find_router(args[0])
|
1048
|
+
return 1 if router.nil?
|
1049
|
+
|
1050
|
+
if options[:payload]
|
1051
|
+
payload = options[:payload]
|
1052
|
+
# support -O OPTION switch on top of --payload
|
1053
|
+
if options[:options]
|
1054
|
+
payload['permissions'] ||= {}
|
1055
|
+
payload['permissions'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) })
|
1056
|
+
end
|
1057
|
+
else
|
1058
|
+
perms = {}
|
1059
|
+
if !options[:visibility].nil?
|
1060
|
+
perms['visibility'] = options[:visibility]
|
1061
|
+
end
|
1062
|
+
if !options[:tenants].nil?
|
1063
|
+
perms['tenantPermissions'] = {'accounts' => options[:tenants].collect {|id| id.to_i}}
|
1064
|
+
end
|
1065
|
+
payload = {'permissions' => perms}
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
@network_routers_interface.setopts(options)
|
1069
|
+
if options[:dry_run]
|
1070
|
+
print_dry_run @network_routers_interface.dry.update_permissions(router['id'], payload)
|
1071
|
+
return
|
1072
|
+
end
|
1073
|
+
json_response = @network_routers_interface.update_permissions(router['id'], payload)
|
1074
|
+
if options[:json]
|
1075
|
+
print JSON.pretty_generate(json_response)
|
1076
|
+
print "\n"
|
1077
|
+
elsif json_response['success']
|
1078
|
+
print_green_success "\nUpdated Network Router Permissions\n"
|
1079
|
+
else
|
1080
|
+
print_rest_errors(json_response, options)
|
1081
|
+
end
|
1082
|
+
end
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
private
|
1086
|
+
|
1087
|
+
def print_firewall(router, details=false, rules_only=false)
|
1088
|
+
if router['type']['hasFirewall']
|
1089
|
+
if router['firewall']
|
1090
|
+
if details
|
1091
|
+
description_cols = {
|
1092
|
+
"Network Router" => lambda {|it| it['name'] },
|
1093
|
+
"Enabled" => lambda {|it| format_boolean(it['firewall']['enabled'])},
|
1094
|
+
"Version" => lambda {|it| it['firewall']['version']},
|
1095
|
+
"Default Policy" => lambda {|it| (router['firewall']['defaultPolicy'] || {})['action']}
|
1096
|
+
}
|
1097
|
+
(router['firewall']['global'] || {}).each do |k,v|
|
1098
|
+
description_cols[k.gsub(/[A-Z]/, ' \0').downcase] = lambda {|it| it['firewall']['global'][k]}
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
if !rules_only
|
1102
|
+
print_description_list(description_cols, router)
|
1103
|
+
print_h2 "Firewall Rules"
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
if (router['firewall']['rules'] || []).count > 0
|
1107
|
+
rows = router['firewall']['rules'].collect do |it|
|
1108
|
+
{
|
1109
|
+
id: it['id'],
|
1110
|
+
name: it['name'],
|
1111
|
+
type: it['ruleType'],
|
1112
|
+
policy: it['policy'],
|
1113
|
+
direction: it['direction'] || 'any',
|
1114
|
+
source: it['source'] || 'any',
|
1115
|
+
destination: it['destination'] || 'any',
|
1116
|
+
application: it['applications'].count > 0 ? it['applications'][0]['name'] : "#{(it['protocol'] || 'any')} #{it['portRange'] || ''}"
|
1117
|
+
}
|
1118
|
+
end
|
1119
|
+
puts as_pretty_table(rows, [:id, :name, :type, :policy, :direction, :source, :destination, :application])
|
1120
|
+
else
|
1121
|
+
println "No firewall rules"
|
1122
|
+
end
|
1123
|
+
else
|
1124
|
+
print "Enabled: #{format_boolean(router['firewall']['enabled'])}".center(20)
|
1125
|
+
print "Version: #{router['firewall']['version']}".center(20)
|
1126
|
+
print "Default Policy: #{(router['firewall']['defaultPolicy'] || {})['action']}".center(20)
|
1127
|
+
println
|
1128
|
+
end
|
1129
|
+
else
|
1130
|
+
println "Enabled: #{format_boolean(false)}".center(20)
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
def print_dhcp(router, details=false)
|
1136
|
+
if router['type']['hasDhcp']
|
1137
|
+
if router['dhcp']
|
1138
|
+
if details
|
1139
|
+
description_cols = {
|
1140
|
+
"Network Router" => lambda {|it| it['name'] },
|
1141
|
+
"Enabled" => lambda {|it| format_boolean(it['dhcp']['enabled'])},
|
1142
|
+
"Version" => lambda {|it| it['dhcp']['version']},
|
1143
|
+
"Feature" => lambda {|it| it['dhcp']['featureType']},
|
1144
|
+
"Logs Enabled" => lambda {|it| format_boolean((it['dhcp']['logging'] || {})['enable'])},
|
1145
|
+
"Log Level" => lambda {|it| (it['dhcp']['logging'] || {})['logLevel']}
|
1146
|
+
}
|
1147
|
+
|
1148
|
+
print_description_list(description_cols, router)
|
1149
|
+
|
1150
|
+
print_h2 "IP Pools"
|
1151
|
+
print cyan
|
1152
|
+
|
1153
|
+
if (router['dhcp']['ipPools'] || []).count > 0
|
1154
|
+
rows = router['dhcp']['ipPools'].collect do |it|
|
1155
|
+
{
|
1156
|
+
ip_range: it['ipRange'],
|
1157
|
+
gateway: it['defaultGateway'],
|
1158
|
+
subnet: it['subnetMask'],
|
1159
|
+
dns: it['primaryNameServer'],
|
1160
|
+
domain: it['domainName']
|
1161
|
+
}
|
1162
|
+
end
|
1163
|
+
puts as_pretty_table(rows, [:ip_range, :gateway, :subnet, :dns, :domain])
|
1164
|
+
else
|
1165
|
+
println "No IP pools"
|
1166
|
+
end
|
1167
|
+
else
|
1168
|
+
print "Enabled: #{format_boolean(router['dhcp']['enabled'])}".center(20)
|
1169
|
+
print "Version: #{router['dhcp']['version']}".center(20)
|
1170
|
+
print "Feature: #{router['dhcp']['version']}".center(20)
|
1171
|
+
print "Logs Enabled: #{(format_boolean((router['dhcp']['logging'] || {})['enable']))}".center(20)
|
1172
|
+
print "Log Level: #{(router['dhcp']['logging'] || {})['logLevel']}".center(20)
|
1173
|
+
println
|
1174
|
+
end
|
1175
|
+
else
|
1176
|
+
print "Enabled: #{format_boolean(false)}".center(20)
|
1177
|
+
print "Logs Enabled: #{format_boolean(false)}".center(20)
|
1178
|
+
println
|
1179
|
+
end
|
1180
|
+
end
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def print_routes(router)
|
1184
|
+
if router['type']['hasRouting']
|
1185
|
+
if router['routes'].count > 0
|
1186
|
+
rows = router['routes'].collect do |it|
|
1187
|
+
{
|
1188
|
+
id: it['id'],
|
1189
|
+
name: it['name'],
|
1190
|
+
network: it['source'],
|
1191
|
+
next_hop: it['destination'],
|
1192
|
+
interface: it['externalInterface'],
|
1193
|
+
default_route: format_boolean(it['defaultRoute']),
|
1194
|
+
mtu: it['networkMtu']
|
1195
|
+
}
|
1196
|
+
end
|
1197
|
+
puts as_pretty_table(rows, [:id, :name, :network, :next_hop, :interface, :default_route, :mtu])
|
1198
|
+
else
|
1199
|
+
println "No routes\n"
|
1200
|
+
end
|
1201
|
+
end
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
def format_router_status(router, return_color = cyan)
|
1205
|
+
status = router['status']
|
1206
|
+
color = white
|
1207
|
+
color = green if status == 'ok'
|
1208
|
+
color = yellow if status == 'warning'
|
1209
|
+
color = red if status == 'error'
|
1210
|
+
"#{color}#{status.upcase}#{return_color}"
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
def router_integration_label(router)
|
1214
|
+
integration = router['networkServer']['integration'] || {}
|
1215
|
+
integration['integrationType'] ? integration['integrationType']['name'] : router['zone']['name']
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
def find_router(val)
|
1219
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
1220
|
+
return find_router_by_id(val)
|
1221
|
+
else
|
1222
|
+
return find_router_by_name(val)
|
1223
|
+
end
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
def find_router_by_id(id)
|
1227
|
+
begin
|
1228
|
+
json_response = @network_routers_interface.get(id.to_i)
|
1229
|
+
return json_response['networkRouter']
|
1230
|
+
rescue RestClient::Exception => e
|
1231
|
+
if e.response && e.response.code == 404
|
1232
|
+
print_red_alert "Network Router not found by id #{id}"
|
1233
|
+
return nil
|
1234
|
+
else
|
1235
|
+
raise e
|
1236
|
+
end
|
1237
|
+
end
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
def find_router_by_name(name)
|
1241
|
+
json_response = @network_routers_interface.list({phrase: name.to_s})
|
1242
|
+
routers = json_response['networkRouters']
|
1243
|
+
if routers.empty?
|
1244
|
+
print_red_alert "Network Router not found by name #{name}"
|
1245
|
+
return nil
|
1246
|
+
elsif routers.size > 1
|
1247
|
+
print_red_alert "#{routers.size} network routers found by name #{name}"
|
1248
|
+
rows = routers.collect do |it|
|
1249
|
+
{id: it['id'], name: it['name']}
|
1250
|
+
end
|
1251
|
+
puts as_pretty_table(rows, [:id, :name], {color:red})
|
1252
|
+
return nil
|
1253
|
+
else
|
1254
|
+
return routers[0]
|
1255
|
+
end
|
1256
|
+
end
|
1257
|
+
|
1258
|
+
def find_router_type(val)
|
1259
|
+
types = @network_routers_interface.types()['networkRouterTypes']
|
1260
|
+
(val.to_s =~ /\A\d{1,}\Z/) ? types.find {|it| it['id'].to_i == val.to_i} : types.find {|it| it['name'] == val}
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
def prompt_router_type(options)
|
1264
|
+
if options[:options]['routerType']
|
1265
|
+
router_type = find_router_type(options[:options]['routerType'])
|
1266
|
+
if router_type.nil?
|
1267
|
+
print_red_alert "Network router type #{options[:options]['routerType']} not found"
|
1268
|
+
exit 1
|
1269
|
+
end
|
1270
|
+
else
|
1271
|
+
router_types = @network_routers_interface.types()['networkRouterTypes']
|
1272
|
+
router_type_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'routerType', 'type' => 'select', 'fieldLabel' => 'Network Router Type', 'required' => true, 'selectOptions' => router_types.collect {|it| {'name' => it['name'], 'value' => it['id']}}}], options[:options], @api_client,{}, nil, true)['routerType']
|
1273
|
+
router_type = router_types.find {|type| type['id'] == router_type_id}
|
1274
|
+
end
|
1275
|
+
router_type
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
def available_groups()
|
1279
|
+
@network_routers_interface.groups
|
1280
|
+
end
|
1281
|
+
end
|