morpheus-cli 5.2.4.1 → 5.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/activity_command.rb +7 -4
- 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 +5 -2
- data/lib/morpheus/cli/commands/standard/history_command.rb +4 -5
- data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
- data/lib/morpheus/cli/dashboard_command.rb +3 -3
- data/lib/morpheus/cli/execution_request_command.rb +15 -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/invoices_command.rb +23 -46
- data/lib/morpheus/cli/login.rb +7 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
- data/lib/morpheus/cli/mixins/print_helper.rb +36 -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_domains_command.rb +2 -2
- 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 +3 -2
- data/lib/morpheus/cli/reports_command.rb +5 -2
- data/lib/morpheus/cli/roles.rb +215 -55
- data/lib/morpheus/cli/service_plans_command.rb +4 -1
- 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
@@ -140,32 +140,32 @@ class Morpheus::Cli::InvoicesCommand
|
|
140
140
|
# construct params
|
141
141
|
params.merge!(parse_list_options(options))
|
142
142
|
if options[:clouds]
|
143
|
-
cloud_ids = parse_cloud_id_list(options[:clouds])
|
143
|
+
cloud_ids = parse_cloud_id_list(options[:clouds], {}, false, true)
|
144
144
|
return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
|
145
145
|
params['zoneId'] = cloud_ids
|
146
146
|
end
|
147
147
|
if options[:groups]
|
148
|
-
group_ids = parse_group_id_list(options[:groups])
|
148
|
+
group_ids = parse_group_id_list(options[:groups], {}, false, true)
|
149
149
|
return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
|
150
150
|
params['siteId'] = group_ids
|
151
151
|
end
|
152
152
|
if options[:instances]
|
153
|
-
instance_ids = parse_instance_id_list(options[:instances])
|
153
|
+
instance_ids = parse_instance_id_list(options[:instances], {}, false, true)
|
154
154
|
return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
|
155
155
|
params['instanceId'] = instance_ids
|
156
156
|
end
|
157
157
|
if options[:servers]
|
158
|
-
server_ids = parse_server_id_list(options[:servers])
|
158
|
+
server_ids = parse_server_id_list(options[:servers], {}, false, true)
|
159
159
|
return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
|
160
160
|
params['serverId'] = server_ids
|
161
161
|
end
|
162
162
|
if options[:users]
|
163
|
-
user_ids = parse_user_id_list(options[:users])
|
163
|
+
user_ids = parse_user_id_list(options[:users], {}, false, true)
|
164
164
|
return 1, "users not found for #{options[:users]}" if user_ids.nil?
|
165
165
|
params['userId'] = user_ids
|
166
166
|
end
|
167
167
|
if options[:projects]
|
168
|
-
project_ids = parse_project_id_list(options[:projects])
|
168
|
+
project_ids = parse_project_id_list(options[:projects], {}, false, true)
|
169
169
|
return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
|
170
170
|
params['projectId'] = project_ids
|
171
171
|
end
|
@@ -636,37 +636,20 @@ Update an invoice.
|
|
636
636
|
params = {}
|
637
637
|
payload = {}
|
638
638
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
639
|
-
opts.banner = subcommand_usage("[
|
640
|
-
opts.on( '--
|
641
|
-
payload[:daily] = true
|
642
|
-
end
|
643
|
-
opts.on( '--costing', "Refresh Costing Data" ) do
|
644
|
-
payload[:costing] = true
|
645
|
-
end
|
646
|
-
opts.on( '--current', "Collect the most up to date costing data." ) do
|
647
|
-
payload[:current] = true
|
648
|
-
end
|
649
|
-
opts.on( '--date DATE', String, "Date to collect costing for. By default the cost data is collected for the end of the previous period." ) do |val|
|
650
|
-
payload[:date] = val.to_s
|
651
|
-
end
|
652
|
-
opts.on( '-c', '--cloud CLOUD', "Specify cloud(s) to refresh costing for." ) do |val|
|
639
|
+
opts.banner = subcommand_usage("[-c CLOUD]")
|
640
|
+
opts.on( '-c', '--clouds CLOUD', "Specify clouds to refresh costing for." ) do |val|
|
653
641
|
payload[:clouds] ||= []
|
654
642
|
payload[:clouds] << val
|
655
643
|
end
|
656
|
-
opts.on( '--all', "Refresh costing for all clouds." ) do
|
644
|
+
opts.on( '--all', "Refresh costing for all clouds. This can be used instead of --clouds" ) do
|
657
645
|
payload[:all] = true
|
658
646
|
end
|
659
|
-
|
660
|
-
|
661
|
-
|
647
|
+
opts.on( '--date DATE', String, "Date to collect costing for. By default the cost data is collected for the end of the previous job interval (hour or day)." ) do |val|
|
648
|
+
payload[:date] = val.to_s
|
649
|
+
end
|
662
650
|
build_standard_update_options(opts, options, [:query, :auto_confirm])
|
663
651
|
opts.footer = <<-EOT
|
664
|
-
Refresh
|
665
|
-
By default, nothing is changed.
|
666
|
-
Include --daily to regenerate invoice records.
|
667
|
-
Include --costing to refresh actual costing data.
|
668
|
-
Include --current to refresh costing data for the actual current time.
|
669
|
-
To get the latest invoice costing data, include --daily --costing --current --all
|
652
|
+
Refresh invoice costing data for the specified clouds.
|
670
653
|
EOT
|
671
654
|
end
|
672
655
|
optparse.parse!(args)
|
@@ -677,17 +660,11 @@ EOT
|
|
677
660
|
payload = options[:payload]
|
678
661
|
end
|
679
662
|
payload.deep_merge!(parse_passed_options(options))
|
680
|
-
# --clouds
|
663
|
+
# --clouds lookup ID for name
|
681
664
|
if payload[:clouds]
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
else
|
686
|
-
cloud = find_cloud_option(cloud_id)
|
687
|
-
return 1 if cloud.nil?
|
688
|
-
cloud['id']
|
689
|
-
end
|
690
|
-
}
|
665
|
+
cloud_ids = parse_cloud_id_list(payload[:clouds], {}, false, true)
|
666
|
+
return 1, "clouds not found for #{payload[:clouds]}" if cloud_ids.nil?
|
667
|
+
payload[:clouds] = cloud_ids
|
691
668
|
end
|
692
669
|
# are you sure?
|
693
670
|
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to refresh invoices?")
|
@@ -831,32 +808,32 @@ EOT
|
|
831
808
|
# construct params
|
832
809
|
params.merge!(parse_list_options(options))
|
833
810
|
if options[:clouds]
|
834
|
-
cloud_ids = parse_cloud_id_list(options[:clouds])
|
811
|
+
cloud_ids = parse_cloud_id_list(options[:clouds], {}, false, true)
|
835
812
|
return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
|
836
813
|
params['zoneId'] = cloud_ids
|
837
814
|
end
|
838
815
|
if options[:groups]
|
839
|
-
group_ids = parse_group_id_list(options[:groups])
|
816
|
+
group_ids = parse_group_id_list(options[:groups], {}, false, true)
|
840
817
|
return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
|
841
818
|
params['siteId'] = group_ids
|
842
819
|
end
|
843
820
|
if options[:instances]
|
844
|
-
instance_ids = parse_instance_id_list(options[:instances])
|
821
|
+
instance_ids = parse_instance_id_list(options[:instances], {}, false, true)
|
845
822
|
return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
|
846
823
|
params['instanceId'] = instance_ids
|
847
824
|
end
|
848
825
|
if options[:servers]
|
849
|
-
server_ids = parse_server_id_list(options[:servers])
|
826
|
+
server_ids = parse_server_id_list(options[:servers], {}, false, true)
|
850
827
|
return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
|
851
828
|
params['serverId'] = server_ids
|
852
829
|
end
|
853
830
|
if options[:users]
|
854
|
-
user_ids = parse_user_id_list(options[:users])
|
831
|
+
user_ids = parse_user_id_list(options[:users], {}, false, true)
|
855
832
|
return 1, "users not found for #{options[:users]}" if user_ids.nil?
|
856
833
|
params['userId'] = user_ids
|
857
834
|
end
|
858
835
|
if options[:projects]
|
859
|
-
project_ids = parse_project_id_list(options[:projects])
|
836
|
+
project_ids = parse_project_id_list(options[:projects], {}, false, true)
|
860
837
|
return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
|
861
838
|
params['projectId'] = project_ids
|
862
839
|
end
|
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
|
@@ -178,7 +178,7 @@ module Morpheus::Cli::OptionSourceHelper
|
|
178
178
|
# todo: some other common ones, accounts (tenants), etc.
|
179
179
|
# todo: a generic set of parse and find methods like
|
180
180
|
# like this:
|
181
|
-
def parse_option_source_id_list(option_source, id_list, api_params={}, refresh=false)
|
181
|
+
def parse_option_source_id_list(option_source, id_list, api_params={}, refresh=false, allow_any_id=false)
|
182
182
|
option_source_label = option_source.to_s # .capitalize
|
183
183
|
option_data = load_option_source_data(option_source, api_params, refresh)
|
184
184
|
found_ids = []
|
@@ -189,9 +189,8 @@ module Morpheus::Cli::OptionSourceHelper
|
|
189
189
|
# never match blank nil or empty strings
|
190
190
|
print_red_alert "#{option_source_label} cannot be not found by with a blank id!"
|
191
191
|
return nil
|
192
|
-
|
193
|
-
|
194
|
-
# found_ids << record_id
|
192
|
+
elsif allow_any_id && record_id.to_s =~ /\A\d{1,}\Z/
|
193
|
+
found_ids << record_id.to_i
|
195
194
|
else
|
196
195
|
# search with in a presedence by value, then name, then id (usually same as value)
|
197
196
|
# exact match on value first.
|
@@ -228,28 +227,28 @@ module Morpheus::Cli::OptionSourceHelper
|
|
228
227
|
return found_ids
|
229
228
|
end
|
230
229
|
|
231
|
-
def parse_cloud_id_list(id_list, api_params={}, refresh=false)
|
232
|
-
parse_option_source_id_list('clouds', id_list, api_params, refresh)
|
230
|
+
def parse_cloud_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
|
231
|
+
parse_option_source_id_list('clouds', id_list, api_params, refresh, allow_any_id)
|
233
232
|
end
|
234
233
|
|
235
|
-
def parse_group_id_list(id_list, api_params={}, refresh=false)
|
236
|
-
parse_option_source_id_list('groups', id_list, api_params, refresh)
|
234
|
+
def parse_group_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
|
235
|
+
parse_option_source_id_list('groups', id_list, api_params, refresh, allow_any_id)
|
237
236
|
end
|
238
237
|
|
239
|
-
def parse_user_id_list(id_list, api_params={}, refresh=false)
|
240
|
-
parse_option_source_id_list('users', id_list, api_params, refresh)
|
238
|
+
def parse_user_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
|
239
|
+
parse_option_source_id_list('users', id_list, api_params, refresh, allow_any_id)
|
241
240
|
end
|
242
241
|
|
243
|
-
def parse_tenant_id_list(id_list, api_params={}, refresh=false)
|
244
|
-
parse_option_source_id_list('allTenants', id_list, api_params, refresh)
|
242
|
+
def parse_tenant_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
|
243
|
+
parse_option_source_id_list('allTenants', id_list, api_params, refresh, allow_any_id)
|
245
244
|
end
|
246
245
|
|
247
|
-
# def parse_blueprints_id_list(id_list)
|
248
|
-
# parse_option_source_id_list('blueprints', id_list, api_params, refresh)
|
246
|
+
# def parse_blueprints_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
|
247
|
+
# parse_option_source_id_list('blueprints', id_list, api_params, refresh, allow_any_id)
|
249
248
|
# end
|
250
249
|
|
251
|
-
def parse_project_id_list(id_list, api_params={}, refresh=false)
|
252
|
-
parse_option_source_id_list('projects', id_list, api_params, refresh)
|
250
|
+
def parse_project_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
|
251
|
+
parse_option_source_id_list('projects', id_list, api_params, refresh, allow_any_id)
|
253
252
|
end
|
254
253
|
|
255
254
|
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
|
@@ -720,6 +734,7 @@ module Morpheus::Cli::PrintHelper
|
|
720
734
|
columns.each do |column_def|
|
721
735
|
# r << column_def.display_method.respond_to?(:call) ? column_def.display_method.call(row_data) : get_object_value(row_data, column_def.display_method)
|
722
736
|
value = column_def.display_method.call(row_data)
|
737
|
+
value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
|
723
738
|
row << value
|
724
739
|
end
|
725
740
|
rows << row
|
@@ -802,6 +817,7 @@ module Morpheus::Cli::PrintHelper
|
|
802
817
|
columns.each do |column_def|
|
803
818
|
# r << column_def.display_method.respond_to?(:call) ? column_def.display_method.call(row_data) : get_object_value(row_data, column_def.display_method)
|
804
819
|
value = column_def.display_method.call(row_data)
|
820
|
+
value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
|
805
821
|
row << value
|
806
822
|
end
|
807
823
|
rows << row
|
@@ -879,6 +895,7 @@ module Morpheus::Cli::PrintHelper
|
|
879
895
|
label = label.upcase if ALL_LABELS_UPCASE
|
880
896
|
# value = get_object_value(obj, column_def.display_method)
|
881
897
|
value = column_def.display_method.call(obj)
|
898
|
+
value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
|
882
899
|
if label.size > max_label_width
|
883
900
|
max_label_width = label.size
|
884
901
|
end
|
@@ -1069,6 +1086,7 @@ module Morpheus::Cli::PrintHelper
|
|
1069
1086
|
column_defs.each do |column_def|
|
1070
1087
|
label = column_def.label
|
1071
1088
|
value = column_def.display_method.call(obj)
|
1089
|
+
value = value.is_a?(String) ? value : JSON.fast_generate(value)
|
1072
1090
|
# value = get_object_value(obj, column_def)
|
1073
1091
|
if do_quotes
|
1074
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
|