morpheus-cli 5.3.0.3 → 5.3.1
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/README.md +1 -3
- data/lib/morpheus/api/api_client.rb +48 -14
- data/lib/morpheus/api/certificate_types_interface.rb +14 -0
- data/lib/morpheus/api/certificates_interface.rb +9 -0
- data/lib/morpheus/api/integration_types_interface.rb +14 -0
- data/lib/morpheus/api/integrations_interface.rb +7 -22
- data/lib/morpheus/api/network_services_interface.rb +14 -0
- data/lib/morpheus/api/read_interface.rb +23 -0
- data/lib/morpheus/api/rest_interface.rb +12 -10
- data/lib/morpheus/api/roles_interface.rb +7 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/user_settings_interface.rb +38 -18
- data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
- data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
- data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
- data/lib/morpheus/api/vdi_interface.rb +28 -0
- data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
- data/lib/morpheus/cli.rb +9 -2
- data/lib/morpheus/cli/apps.rb +59 -75
- data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
- data/lib/morpheus/cli/certificates_command.rb +575 -0
- data/lib/morpheus/cli/cli_command.rb +61 -6
- data/lib/morpheus/cli/clouds.rb +1 -0
- data/lib/morpheus/cli/clusters.rb +1 -1
- data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
- data/lib/morpheus/cli/hosts.rb +245 -224
- data/lib/morpheus/cli/instances.rb +150 -167
- data/lib/morpheus/cli/integrations_command.rb +588 -41
- data/lib/morpheus/cli/login.rb +7 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +33 -18
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
- data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
- data/lib/morpheus/cli/network_routers_command.rb +22 -9
- data/lib/morpheus/cli/networks_command.rb +2 -2
- data/lib/morpheus/cli/option_types.rb +34 -33
- data/lib/morpheus/cli/remote.rb +1 -1
- data/lib/morpheus/cli/reports_command.rb +4 -1
- data/lib/morpheus/cli/roles.rb +215 -55
- data/lib/morpheus/cli/subnets_command.rb +11 -2
- data/lib/morpheus/cli/user_settings_command.rb +268 -57
- data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
- data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
- data/lib/morpheus/cli/vdi_command.rb +359 -0
- data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
- data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/rest_client.rb +30 -0
- data/lib/morpheus/terminal.rb +15 -7
- metadata +18 -2
data/lib/morpheus/cli/login.rb
CHANGED
@@ -36,6 +36,13 @@ class Morpheus::Cli::Login
|
|
36
36
|
opts.on( '-p', '--password PASSWORD', "Password" ) do |val|
|
37
37
|
password = val
|
38
38
|
end
|
39
|
+
opts.on( '--password-file FILE', String, "Password File, read a file containing the password." ) do |val|
|
40
|
+
password_file = File.expand_path(val)
|
41
|
+
if !File.exists?(password_file) || !File.file?(password_file) # check readable too
|
42
|
+
raise ::OptionParser::InvalidOption.new("File not found: #{password_file}")
|
43
|
+
end
|
44
|
+
password = File.read(password_file) #.to_s.split("\n").first.strip
|
45
|
+
end
|
39
46
|
opts.on( '-t', '--test', "Test credentials only, does not update stored credentials for the appliance." ) do
|
40
47
|
options[:test_only] = true
|
41
48
|
end
|
@@ -228,7 +228,8 @@ module Morpheus::Cli::PrintHelper
|
|
228
228
|
out << cyan
|
229
229
|
if payload
|
230
230
|
out << "\n"
|
231
|
-
|
231
|
+
is_multipart = (payload.is_a?(Hash) && payload[:multipart] == true)
|
232
|
+
content_type = (headers && headers['Content-Type']) ? headers['Content-Type'] : (is_multipart ? 'multipart/form-data' : 'application/x-www-form-urlencoded')
|
232
233
|
if content_type == 'application/json'
|
233
234
|
if payload.is_a?(String)
|
234
235
|
begin
|
@@ -257,12 +258,21 @@ module Morpheus::Cli::PrintHelper
|
|
257
258
|
out << payload
|
258
259
|
end
|
259
260
|
else
|
260
|
-
if content_type == 'application/x-www-form-urlencoded'
|
261
|
+
if content_type == 'application/x-www-form-urlencoded' || content_type.to_s.include?('multipart')
|
261
262
|
body_str = payload.to_s
|
262
263
|
begin
|
264
|
+
payload.delete(:multipart) if payload.is_a?(Hash)
|
265
|
+
# puts "grailsifying it!"
|
266
|
+
payload = Morpheus::RestClient.grails_params(payload)
|
267
|
+
payload.each do |k,v|
|
268
|
+
if v.is_a?(File)
|
269
|
+
payload[k] = "@#{v.path}"
|
270
|
+
payload[k] = v.path
|
271
|
+
end
|
272
|
+
end
|
263
273
|
body_str = URI.encode_www_form(payload)
|
264
274
|
rescue => ex
|
265
|
-
|
275
|
+
raise ex
|
266
276
|
end
|
267
277
|
if options[:scrub]
|
268
278
|
out << Morpheus::Logging.scrub_message(body_str)
|
@@ -273,7 +283,7 @@ module Morpheus::Cli::PrintHelper
|
|
273
283
|
if options[:scrub]
|
274
284
|
out << Morpheus::Logging.scrub_message(payload)
|
275
285
|
else
|
276
|
-
out << payload
|
286
|
+
out << payload.to_s
|
277
287
|
end
|
278
288
|
end
|
279
289
|
end
|
@@ -327,7 +337,9 @@ module Morpheus::Cli::PrintHelper
|
|
327
337
|
else
|
328
338
|
out << " -d '#{payload}'"
|
329
339
|
end
|
340
|
+
out << "\n"
|
330
341
|
else
|
342
|
+
is_multipart = (payload.is_a?(Hash) && payload[:multipart] == true)
|
331
343
|
content_type = headers['Content-Type'] || 'application/x-www-form-urlencoded'
|
332
344
|
|
333
345
|
if payload.is_a?(File)
|
@@ -337,21 +349,22 @@ module Morpheus::Cli::PrintHelper
|
|
337
349
|
out << " -d @#{payload.path}"
|
338
350
|
elsif payload.is_a?(String)
|
339
351
|
out << " -d '#{payload}'"
|
340
|
-
|
341
|
-
if
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
352
|
+
elsif payload.respond_to?(:map)
|
353
|
+
payload.delete(:multipart) if payload.is_a?(Hash)
|
354
|
+
# puts "grailsifying it!"
|
355
|
+
payload = Morpheus::RestClient.grails_params(payload)
|
356
|
+
payload.each do |k,v|
|
357
|
+
if v.is_a?(File)
|
358
|
+
out << " -F '#{k}=@#{v.path}"
|
359
|
+
else
|
360
|
+
out << " -d '#{URI.encode_www_form({(k) => v})}'"
|
347
361
|
end
|
348
|
-
out << "
|
349
|
-
else
|
350
|
-
out << " -d '#{payload}'"
|
362
|
+
out << "\n"
|
351
363
|
end
|
364
|
+
#body_str = URI.encode_www_form(payload)
|
365
|
+
# out << " -d '#{body_str}'"
|
352
366
|
end
|
353
367
|
end
|
354
|
-
out << "\n"
|
355
368
|
else
|
356
369
|
out << "\n"
|
357
370
|
end
|
@@ -431,12 +444,13 @@ module Morpheus::Cli::PrintHelper
|
|
431
444
|
out = ""
|
432
445
|
bars = []
|
433
446
|
percent = 0
|
447
|
+
percent_sigdig = opts[:percent_sigdig] || 2
|
434
448
|
if max_value.to_i == 0
|
435
449
|
percent = 0
|
436
450
|
else
|
437
451
|
percent = ((used_value.to_f / max_value.to_f) * 100)
|
438
452
|
end
|
439
|
-
percent_label = ((used_value.nil? || max_value.to_f == 0.0) ? "n/a" : "#{percent.round(
|
453
|
+
percent_label = ((used_value.nil? || max_value.to_f == 0.0) ? "n/a" : "#{percent.round(percent_sigdig)}%").rjust(6, ' ')
|
440
454
|
bar_display = ""
|
441
455
|
if percent > 100
|
442
456
|
max_bars.times { bars << "|" }
|
@@ -674,7 +688,7 @@ module Morpheus::Cli::PrintHelper
|
|
674
688
|
else
|
675
689
|
# so let's use the passed in column definitions instead of the raw data properties
|
676
690
|
# columns = options[:include_fields]
|
677
|
-
new_columns =
|
691
|
+
new_columns = {}
|
678
692
|
options[:include_fields].each do |f|
|
679
693
|
matching_column = nil
|
680
694
|
# column definitions vary right now, array of symbols/strings/hashes or perhaps a single hash
|
@@ -692,7 +706,7 @@ module Morpheus::Cli::PrintHelper
|
|
692
706
|
matching_column = columns[matching_key]
|
693
707
|
end
|
694
708
|
end
|
695
|
-
new_columns
|
709
|
+
new_columns[f] = matching_column ? matching_column : f
|
696
710
|
end
|
697
711
|
columns = new_columns
|
698
712
|
end
|
@@ -1072,6 +1086,7 @@ module Morpheus::Cli::PrintHelper
|
|
1072
1086
|
column_defs.each do |column_def|
|
1073
1087
|
label = column_def.label
|
1074
1088
|
value = column_def.display_method.call(obj)
|
1089
|
+
value = value.is_a?(String) ? value : JSON.fast_generate(value)
|
1075
1090
|
# value = get_object_value(obj, column_def)
|
1076
1091
|
if do_quotes
|
1077
1092
|
cells << quote_csv_value(value)
|
@@ -696,7 +696,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
696
696
|
# prompt for service plan
|
697
697
|
plan_id = nil
|
698
698
|
service_plan = nil
|
699
|
-
service_plans_json =
|
699
|
+
service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
|
700
700
|
service_plans = service_plans_json["plans"]
|
701
701
|
if locked_fields.include?('plan.id')
|
702
702
|
plan_id = options[:options]['plan']['id'] rescue nil
|
@@ -764,7 +764,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
764
764
|
# pluck out the resourcePoolId option type to prompt for
|
765
765
|
resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
|
766
766
|
option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
|
767
|
-
resource_pool_options =
|
767
|
+
resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})['data']
|
768
768
|
resource_pool = resource_pool_options.find {|opt| opt['id'] == options[:resource_pool].to_i} if options[:resource_pool]
|
769
769
|
|
770
770
|
if resource_pool
|
@@ -1409,7 +1409,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1409
1409
|
if plan_info['addVolumes']
|
1410
1410
|
volume_index = current_volumes.size
|
1411
1411
|
has_another_volume = options[:options] && options[:options]["dataVolume#{volume_index}"]
|
1412
|
-
add_another_volume = has_another_volume || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add data volume?"))
|
1412
|
+
add_another_volume = has_another_volume || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add data volume?", {:default => false}))
|
1413
1413
|
while add_another_volume do
|
1414
1414
|
#puts "Configure Data #{volume_index} Volume"
|
1415
1415
|
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'morpheus/cli/mixins/print_helper'
|
2
|
+
# Provides common finder methods for VDI Pool management commands
|
3
|
+
module Morpheus::Cli::VdiHelper
|
4
|
+
|
5
|
+
def self.included(klass)
|
6
|
+
klass.send :include, Morpheus::Cli::PrintHelper
|
7
|
+
end
|
8
|
+
|
9
|
+
## VDI Pools
|
10
|
+
|
11
|
+
def vdi_pools_interface
|
12
|
+
raise "#{self.class} has not defined @vdi_pools_interface" if @vdi_pools_interface.nil?
|
13
|
+
@vdi_pools_interface
|
14
|
+
end
|
15
|
+
|
16
|
+
def vdi_pool_object_key
|
17
|
+
'vdiPool'
|
18
|
+
end
|
19
|
+
|
20
|
+
def vdi_pool_list_key
|
21
|
+
'vdiPools'
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_vdi_pool_by_name_or_id(val)
|
25
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
26
|
+
return find_vdi_pool_by_id(val)
|
27
|
+
else
|
28
|
+
return find_vdi_pool_by_name(val)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_vdi_pool_by_id(id)
|
33
|
+
begin
|
34
|
+
json_response = vdi_pools_interface.get(id.to_i)
|
35
|
+
return json_response[vdi_pool_object_key]
|
36
|
+
rescue RestClient::Exception => e
|
37
|
+
if e.response && e.response.code == 404
|
38
|
+
print_red_alert "VDI Pool not found by id '#{id}'"
|
39
|
+
else
|
40
|
+
raise e
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_vdi_pool_by_name(name)
|
46
|
+
json_response = vdi_pools_interface.list({name: name.to_s})
|
47
|
+
vdi_pools = json_response[vdi_pool_list_key]
|
48
|
+
if vdi_pools.empty?
|
49
|
+
print_red_alert "VDI Pool not found by name '#{name}'"
|
50
|
+
return nil
|
51
|
+
elsif vdi_pools.size > 1
|
52
|
+
print_red_alert "#{vdi_pools.size} VDI Pools found by name '#{name}'"
|
53
|
+
print_error "\n"
|
54
|
+
puts_error as_pretty_table(vdi_pools, [:id, :name], {color:red})
|
55
|
+
print_red_alert "Try using ID instead"
|
56
|
+
print_error reset,"\n"
|
57
|
+
return nil
|
58
|
+
else
|
59
|
+
return vdi_pools[0]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def format_vdi_pool_status(vdi_pool, return_color=cyan)
|
64
|
+
out = ""
|
65
|
+
status_string = vdi_pool['status'].to_s.downcase
|
66
|
+
if status_string
|
67
|
+
if ['available'].include?(status_string)
|
68
|
+
out << "#{green}#{status_string.upcase}"
|
69
|
+
elsif ['unavailable'].include?(status_string)
|
70
|
+
out << "#{red}#{status_string.upcase}"
|
71
|
+
else
|
72
|
+
out << "#{return_color}#{status_string.upcase}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
out + return_color
|
76
|
+
end
|
77
|
+
|
78
|
+
## VDI Allocations
|
79
|
+
|
80
|
+
def vdi_allocations_interface
|
81
|
+
raise "#{self.class} has not defined @vdi_allocations_interface" if @vdi_allocations_interface.nil?
|
82
|
+
@vdi_allocations_interface
|
83
|
+
end
|
84
|
+
|
85
|
+
def vdi_allocation_object_key
|
86
|
+
'vdiAllocation'
|
87
|
+
end
|
88
|
+
|
89
|
+
def vdi_allocation_list_key
|
90
|
+
'vdiAllocations'
|
91
|
+
end
|
92
|
+
|
93
|
+
def find_vdi_allocation_by_id(id)
|
94
|
+
begin
|
95
|
+
json_response = vdi_allocations_interface.get(id.to_i)
|
96
|
+
return json_response[vdi_allocation_object_key]
|
97
|
+
rescue RestClient::Exception => e
|
98
|
+
if e.response && e.response.code == 404
|
99
|
+
print_red_alert "VDI Allocation not found by id '#{id}'"
|
100
|
+
else
|
101
|
+
raise e
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def format_vdi_allocation_status(vdi_allocation, return_color=cyan)
|
107
|
+
out = ""
|
108
|
+
status_string = vdi_allocation['status'].to_s.downcase
|
109
|
+
if status_string
|
110
|
+
if ['available'].include?(status_string)
|
111
|
+
out << "#{green}#{status_string.upcase}"
|
112
|
+
# elsif ['preparing'].include?(status_string)
|
113
|
+
# out << "#{yellow}#{status_string.upcase}"
|
114
|
+
# elsif ['reserved', 'shutdown'].include?(status_string)
|
115
|
+
# out << "#{yellow}#{status_string.upcase}"
|
116
|
+
elsif ['failed'].include?(status_string)
|
117
|
+
out << "#{red}#{status_string.upcase}"
|
118
|
+
else
|
119
|
+
out << "#{return_color}#{status_string.upcase}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
out + return_color
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_available_vdi_apps(refresh=false)
|
126
|
+
if !@available_vdi_apps || refresh
|
127
|
+
@available_vdi_apps = @vdi_apps_interface.list({max:-1})['vdiApps'] # || []
|
128
|
+
end
|
129
|
+
return @available_vdi_apps
|
130
|
+
end
|
131
|
+
|
132
|
+
def get_vdi_app_by_name_or_code(name)
|
133
|
+
return get_available_vdi_apps().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
|
134
|
+
end
|
135
|
+
|
136
|
+
## VDI Apps
|
137
|
+
|
138
|
+
def vdi_apps_interface
|
139
|
+
raise "#{self.class} has not defined @vdi_apps_interface" if @vdi_apps_interface.nil?
|
140
|
+
@vdi_apps_interface
|
141
|
+
end
|
142
|
+
|
143
|
+
def vdi_app_object_key
|
144
|
+
'vdiApp'
|
145
|
+
end
|
146
|
+
|
147
|
+
def vdi_app_list_key
|
148
|
+
'vdiApps'
|
149
|
+
end
|
150
|
+
|
151
|
+
def find_vdi_app_by_name_or_id(val)
|
152
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
153
|
+
return find_vdi_app_by_id(val)
|
154
|
+
else
|
155
|
+
return find_vdi_app_by_name(val)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def find_vdi_app_by_id(id)
|
160
|
+
begin
|
161
|
+
json_response = vdi_apps_interface.get(id.to_i)
|
162
|
+
return json_response[vdi_app_object_key]
|
163
|
+
rescue RestClient::Exception => e
|
164
|
+
if e.response && e.response.code == 404
|
165
|
+
print_red_alert "VDI App not found by id '#{id}'"
|
166
|
+
else
|
167
|
+
raise e
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def find_vdi_app_by_name(name)
|
173
|
+
json_response = vdi_apps_interface.list({name: name.to_s})
|
174
|
+
vdi_apps = json_response[vdi_app_list_key]
|
175
|
+
if vdi_apps.empty?
|
176
|
+
print_red_alert "VDI App not found by name '#{name}'"
|
177
|
+
return nil
|
178
|
+
elsif vdi_apps.size > 1
|
179
|
+
print_red_alert "#{vdi_apps.size} VDI App found by name '#{name}'"
|
180
|
+
print_error "\n"
|
181
|
+
puts_error as_pretty_table(vdi_apps, {"ID" => 'id', "NAME" => 'name'}, {color:red})
|
182
|
+
print_red_alert "Try using ID instead"
|
183
|
+
print_error reset,"\n"
|
184
|
+
return nil
|
185
|
+
else
|
186
|
+
return vdi_apps[0]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
## VDI Gateways
|
192
|
+
|
193
|
+
def vdi_gateways_interface
|
194
|
+
raise "#{self.class} has not defined @vdi_gateways_interface" if @vdi_gateways_interface.nil?
|
195
|
+
@vdi_gateways_interface
|
196
|
+
end
|
197
|
+
|
198
|
+
def vdi_gateway_object_key
|
199
|
+
'vdiGateway'
|
200
|
+
end
|
201
|
+
|
202
|
+
def vdi_gateway_list_key
|
203
|
+
'vdiGateways'
|
204
|
+
end
|
205
|
+
|
206
|
+
def find_vdi_gateway_by_name_or_id(val)
|
207
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
208
|
+
return find_vdi_gateway_by_id(val)
|
209
|
+
else
|
210
|
+
return find_vdi_gateway_by_name(val)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def find_vdi_gateway_by_id(id)
|
215
|
+
begin
|
216
|
+
json_response = vdi_gateways_interface.get(id.to_i)
|
217
|
+
return json_response[vdi_gateway_object_key]
|
218
|
+
rescue RestClient::Exception => e
|
219
|
+
if e.response && e.response.code == 404
|
220
|
+
print_red_alert "VDI Gateway not found by id '#{id}'"
|
221
|
+
else
|
222
|
+
raise e
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def find_vdi_gateway_by_name(name)
|
228
|
+
json_response = vdi_gateways_interface.list({name: name.to_s})
|
229
|
+
vdi_gateways = json_response[vdi_gateway_list_key]
|
230
|
+
if vdi_gateways.empty?
|
231
|
+
print_red_alert "VDI Gateway not found by name '#{name}'"
|
232
|
+
return nil
|
233
|
+
elsif vdi_gateways.size > 1
|
234
|
+
print_red_alert "#{vdi_gateways.size} VDI Gateway found by name '#{name}'"
|
235
|
+
print_error "\n"
|
236
|
+
puts_error as_pretty_table(vdi_gateways, {"ID" => 'id', "NAME" => 'name'}, {color:red})
|
237
|
+
print_red_alert "Try using ID instead"
|
238
|
+
print_error reset,"\n"
|
239
|
+
return nil
|
240
|
+
else
|
241
|
+
return vdi_gateways[0]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
end
|
@@ -22,6 +22,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
22
22
|
def connect(opts)
|
23
23
|
@api_client = establish_remote_appliance_connection(opts)
|
24
24
|
@network_routers_interface = @api_client.network_routers
|
25
|
+
@network_services_interface = @api_client.network_services
|
25
26
|
@clouds_interface = @api_client.clouds
|
26
27
|
@options_interface = @api_client.options
|
27
28
|
@accounts_interface = @api_client.accounts
|
@@ -249,6 +250,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
249
250
|
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the network router. Default is on") do |val|
|
250
251
|
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
251
252
|
end
|
253
|
+
opts.on('--hostname VALUE', String, "Hostname for this network pool IP") do |val|
|
254
|
+
options[:options]['hostname'] = val
|
255
|
+
end
|
252
256
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
253
257
|
opts.footer = "Create a network router."
|
254
258
|
end
|
@@ -275,7 +279,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
275
279
|
group_options = available_groups
|
276
280
|
|
277
281
|
if options[:group]
|
278
|
-
group =
|
282
|
+
group = available_groups.find {|it| it['name'] == options[:group] || "#{it['value']}" == "#{options[:group]}".downcase}
|
279
283
|
|
280
284
|
if group.nil?
|
281
285
|
print_red_alert "Group #{options[:group]} not found"
|
@@ -292,10 +296,10 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
292
296
|
params = {'router' => {'site' => router['site']}, 'routerType' => {'id' => router_type['id']}}
|
293
297
|
|
294
298
|
if router_type['hasNetworkServer']
|
295
|
-
if options[:
|
296
|
-
server = find_network_server(options[:
|
299
|
+
if options[:network_server]
|
300
|
+
server = find_network_server(options[:network_server])
|
297
301
|
if server.nil?
|
298
|
-
print_red_alert "Network server #{options[:
|
302
|
+
print_red_alert "Network server #{options[:network_server]} not found"
|
299
303
|
exit 1
|
300
304
|
end
|
301
305
|
else
|
@@ -322,7 +326,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
322
326
|
# prompt for enabled
|
323
327
|
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
328
|
|
325
|
-
option_types = router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
329
|
+
option_types = router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName']) || it['showOnCreate'] === false}.sort {|it| it['displayOrder']}
|
326
330
|
|
327
331
|
# prompt options
|
328
332
|
option_opts = options[:options].deep_merge!({'config' => options[:options].clone})
|
@@ -570,7 +574,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
570
574
|
api_params = {}
|
571
575
|
api_params['networkServerId'] = router['networkServer']['id'] if router['networkServer']
|
572
576
|
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 => {'
|
577
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'rule' => ''}}), @api_client, api_params, nil, true)
|
574
578
|
payload = {'rule' => params.deep_merge(option_result)}
|
575
579
|
end
|
576
580
|
|
@@ -792,6 +796,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
792
796
|
opts.on('--mtu VALUE', String, "MTU for this route") do |val|
|
793
797
|
params['networkMtu'] = val
|
794
798
|
end
|
799
|
+
opts.on('--priority VALUE', Integer, "Priority for this route") do |val|
|
800
|
+
params['priority'] = val
|
801
|
+
end
|
795
802
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
796
803
|
opts.footer = "Create a network router route."
|
797
804
|
end
|
@@ -821,17 +828,18 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
821
828
|
payload = options[:payload]
|
822
829
|
else
|
823
830
|
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' =>
|
831
|
+
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => false}], options[:options], @api_client, params)['description']
|
825
832
|
|
826
833
|
# prompt for enabled if not set
|
827
834
|
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
835
|
|
829
|
-
# default
|
836
|
+
# default route
|
830
837
|
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
838
|
|
832
839
|
params['source'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'type' => 'text', 'fieldLabel' => 'Network', 'required' => true}], options[:options], @api_client, params)['source']
|
833
840
|
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' =>
|
841
|
+
params['networkMtu'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkMtu', 'type' => 'text', 'fieldLabel' => 'MTU', 'required' => false}], options[:options], @api_client, params)['networkMtu']
|
842
|
+
params['priority'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priority', 'type' => 'number', 'fieldLabel' => 'Priority', 'required' => false}], options[:options], @api_client, params)['priority']
|
835
843
|
|
836
844
|
payload = {'route' => params}
|
837
845
|
end
|
@@ -1278,4 +1286,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1278
1286
|
def available_groups()
|
1279
1287
|
@network_routers_interface.groups
|
1280
1288
|
end
|
1289
|
+
|
1290
|
+
def find_network_server(val)
|
1291
|
+
services = @network_services_interface.list()['networkServices']
|
1292
|
+
(val.to_s =~ /\A\d{1,}\Z/) ? services.find {|it| it['id'].to_i == val.to_i} : services.find {|it| it['name'] == val}
|
1293
|
+
end
|
1281
1294
|
end
|