morpheus-cli 5.2.4.1 → 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/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
|