morpheus-cli 7.0.6 → 8.0.0
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/lib/morpheus/api/api_client.rb +11 -0
- data/lib/morpheus/api/clusters_interface.rb +25 -0
- data/lib/morpheus/api/datastores_interface.rb +6 -0
- data/lib/morpheus/api/library_operating_systems_interface.rb +63 -0
- data/lib/morpheus/api/processes_interface.rb +17 -5
- data/lib/morpheus/cli/commands/backup_jobs_command.rb +50 -17
- data/lib/morpheus/cli/commands/backups_command.rb +36 -9
- data/lib/morpheus/cli/commands/clusters.rb +398 -25
- data/lib/morpheus/cli/commands/hosts.rb +3 -0
- data/lib/morpheus/cli/commands/instances.rb +33 -4
- data/lib/morpheus/cli/commands/library_container_types_command.rb +6 -0
- data/lib/morpheus/cli/commands/library_operating_systems_command.rb +671 -0
- data/lib/morpheus/cli/commands/license.rb +11 -1
- data/lib/morpheus/cli/commands/plugins.rb +2 -2
- data/lib/morpheus/cli/commands/processes_command.rb +71 -1
- data/lib/morpheus/cli/commands/setup.rb +32 -18
- data/lib/morpheus/cli/commands/virtual_images.rb +10 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +28 -2
- data/lib/morpheus/cli/option_types.rb +9 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +12 -0
- metadata +5 -3
@@ -294,6 +294,13 @@ class Morpheus::Cli::License
|
|
294
294
|
elsif license['zoneTypesExcluded'] && license['zoneTypesExcluded'].size > 0
|
295
295
|
description_cols["Excluded Clouds"] = lambda {|it| it['zoneTypesExcluded'].join(', ') }
|
296
296
|
end
|
297
|
+
|
298
|
+
if license['taskTypes'] && license['taskTypes'].size > 0
|
299
|
+
description_cols["Included Tasks"] = lambda {|it| it['taskTypes'].join(', ') }
|
300
|
+
elsif license['taskTypesExcluded'] && license['taskTypesExcluded'].size > 0
|
301
|
+
description_cols["Excluded Tasks"] = lambda {|it| it['taskTypesExcluded'].join(', ') }
|
302
|
+
end
|
303
|
+
|
297
304
|
print_description_list(description_cols, license)
|
298
305
|
end
|
299
306
|
|
@@ -306,6 +313,7 @@ class Morpheus::Cli::License
|
|
306
313
|
used_discovered_servers = current_usage['discoveredServers']
|
307
314
|
used_hosts = current_usage['hosts']
|
308
315
|
used_mvm = current_usage['mvm']
|
316
|
+
used_mvm_sockets = current_usage['mvmSockets']
|
309
317
|
used_iac = current_usage['iac']
|
310
318
|
used_xaas = current_usage['xaas']
|
311
319
|
used_executions = current_usage['executions']
|
@@ -317,6 +325,7 @@ class Morpheus::Cli::License
|
|
317
325
|
max_discovered_servers = license['maxDiscoveredServers']
|
318
326
|
max_hosts = license['maxHosts']
|
319
327
|
max_mvm = license['maxMvm']
|
328
|
+
max_mvm_sockets = license['maxMvmSockets']
|
320
329
|
max_iac = license['maxIac']
|
321
330
|
max_xaas = license['maxXaas']
|
322
331
|
max_executions = license['maxExecutions']
|
@@ -328,7 +337,8 @@ class Morpheus::Cli::License
|
|
328
337
|
out << cyan + "Managed Servers".rjust(label_width, ' ') + ": " + generate_usage_bar(used_managed_servers, max_managed_servers, chart_opts) + cyan + used_managed_servers.to_s.rjust(8, ' ') + " / " + (max_managed_servers ? max_managed_servers.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
329
338
|
out << cyan + "Discovered Servers".rjust(label_width, ' ') + ": " + generate_usage_bar(used_discovered_servers, max_discovered_servers, chart_opts) + cyan + used_discovered_servers.to_s.rjust(8, ' ') + " / " + (max_discovered_servers ? max_discovered_servers.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
330
339
|
out << cyan + "Hosts".rjust(label_width, ' ') + ": " + generate_usage_bar(used_hosts, max_hosts, chart_opts) + cyan + used_hosts.to_s.rjust(8, ' ') + " / " + (max_hosts ? max_hosts.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
331
|
-
out << cyan + "
|
340
|
+
out << cyan + "HPE VM Hosts".rjust(label_width, ' ') + ": " + generate_usage_bar(used_mvm, max_mvm, chart_opts) + cyan + used_mvm.to_s.rjust(8, ' ') + " / " + (max_mvm ? max_mvm.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
341
|
+
out << cyan + "HPE VM Sockets".rjust(label_width, ' ') + ": " + generate_usage_bar(used_mvm_sockets, max_mvm_sockets, chart_opts) + cyan + used_mvm_sockets.to_s.rjust(8, ' ') + " / " + (max_mvm_sockets ? max_mvm_sockets.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
332
342
|
out << cyan + "Iac Deployments".rjust(label_width, ' ') + ": " + generate_usage_bar(used_iac, max_iac, chart_opts) + cyan + used_iac.to_s.rjust(8, ' ') + " / " + (max_iac ? max_iac.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
333
343
|
out << cyan + "Xaas Instances".rjust(label_width, ' ') + ": " + generate_usage_bar(used_xaas, max_xaas, chart_opts) + cyan + used_xaas.to_s.rjust(8, ' ') + " / " + (max_xaas ? max_xaas.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
334
344
|
out << cyan + "Executions".rjust(label_width, ' ') + ": " + generate_usage_bar(used_executions, max_executions, chart_opts) + cyan + used_executions.to_s.rjust(8, ' ') + " / " + (max_executions ? max_executions.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
@@ -16,7 +16,7 @@ class Morpheus::Cli::PluginsCommand
|
|
16
16
|
params = {}
|
17
17
|
filename = nil
|
18
18
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
19
|
-
opts.banner = subcommand_usage("[
|
19
|
+
opts.banner = subcommand_usage("[file]")
|
20
20
|
build_standard_post_options(opts, options)
|
21
21
|
opts.footer = <<-EOT
|
22
22
|
Upload a plugin file.
|
@@ -55,7 +55,7 @@ EOT
|
|
55
55
|
params = {}
|
56
56
|
filename = nil
|
57
57
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
58
|
-
opts.banner = subcommand_usage("
|
58
|
+
opts.banner = subcommand_usage("")
|
59
59
|
build_standard_post_options(opts, options)
|
60
60
|
opts.footer = <<-EOT
|
61
61
|
Check for installed plugins that have available updates.
|
@@ -9,7 +9,7 @@ class Morpheus::Cli::Processes
|
|
9
9
|
|
10
10
|
set_command_name :'process'
|
11
11
|
|
12
|
-
register_subcommands :list, :get, {:'get-event' => :event_details}
|
12
|
+
register_subcommands :list, :get, {:'get-event' => :event_details}, :retry, :cancel
|
13
13
|
|
14
14
|
# alias_subcommand :details, :get
|
15
15
|
# set_default_subcommand :list
|
@@ -346,6 +346,76 @@ class Morpheus::Cli::Processes
|
|
346
346
|
end
|
347
347
|
end
|
348
348
|
|
349
|
+
def retry(args)
|
350
|
+
options = {}
|
351
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
352
|
+
opts.banner = subcommand_usage("[id]")
|
353
|
+
build_standard_update_options(opts, options, [:auto_confirm])
|
354
|
+
opts.footer = <<-EOT
|
355
|
+
Retry a process.
|
356
|
+
[id] is required. This is the id of a process.
|
357
|
+
Only a process that is failed or cancelled and is of a retryable type can be retried.
|
358
|
+
EOT
|
359
|
+
end
|
360
|
+
optparse.parse!(args)
|
361
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
362
|
+
connect(options)
|
363
|
+
# process = find_process_by_id(args[0])
|
364
|
+
# return 1 if process.nil?
|
365
|
+
process_id = args[0]
|
366
|
+
payload = parse_payload(options)
|
367
|
+
if payload.nil?
|
368
|
+
payload = parse_passed_options(options)
|
369
|
+
# prompt
|
370
|
+
end
|
371
|
+
confirm!("Are you sure you would like to retry process #{process_id}?", options)
|
372
|
+
@processes_interface.setopts(options)
|
373
|
+
if options[:dry_run]
|
374
|
+
print_dry_run @processes_interface.dry.retry(process_id, payload)
|
375
|
+
return
|
376
|
+
end
|
377
|
+
json_response = @processes_interface.retry(process_id, payload)
|
378
|
+
render_response(json_response, options) do
|
379
|
+
print_green_success "Retrying process #{process_id}"
|
380
|
+
end
|
381
|
+
return 0, nil
|
382
|
+
end
|
383
|
+
|
384
|
+
def cancel(args)
|
385
|
+
options = {}
|
386
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
387
|
+
opts.banner = subcommand_usage("[id]")
|
388
|
+
build_standard_update_options(opts, options, [:auto_confirm])
|
389
|
+
opts.footer = <<-EOT
|
390
|
+
Cancel a process.
|
391
|
+
[id] is required. This is the id of a process.
|
392
|
+
Only a process that is currently running and is of a cancellable type can be canceled.
|
393
|
+
EOT
|
394
|
+
end
|
395
|
+
optparse.parse!(args)
|
396
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
397
|
+
connect(options)
|
398
|
+
# process = find_process_by_id(args[0])
|
399
|
+
# return 1 if process.nil?
|
400
|
+
process_id = args[0]
|
401
|
+
payload = parse_payload(options)
|
402
|
+
if payload.nil?
|
403
|
+
payload = parse_passed_options(options)
|
404
|
+
# prompt
|
405
|
+
end
|
406
|
+
confirm!("Are you sure you would like to cancel process #{process_id}?", options)
|
407
|
+
@processes_interface.setopts(options)
|
408
|
+
if options[:dry_run]
|
409
|
+
print_dry_run @processes_interface.dry.cancel(process_id, payload)
|
410
|
+
return
|
411
|
+
end
|
412
|
+
json_response = @processes_interface.cancel(process_id, payload)
|
413
|
+
render_response(json_response, options) do
|
414
|
+
print_green_success "Cancelling process #{process_id}"
|
415
|
+
end
|
416
|
+
return 0, nil
|
417
|
+
end
|
418
|
+
|
349
419
|
def event_details(args)
|
350
420
|
options = {}
|
351
421
|
params = {}
|
@@ -35,6 +35,9 @@ class Morpheus::Cli::Setup
|
|
35
35
|
opts.on('--hubmode MODE','--hubmode MODE', "Choose an option for hub registration possible values are login, register, skip.") do |val|
|
36
36
|
options[:hubmode] = val.to_s.downcase
|
37
37
|
end
|
38
|
+
opts.on('--license KEY', String, "License key to install") do |val|
|
39
|
+
options[:license] = val
|
40
|
+
end
|
38
41
|
opts.on('--force','--force', "Force setup, make api request even if setup is unavailable.") do
|
39
42
|
options[:force] = true
|
40
43
|
end
|
@@ -127,10 +130,10 @@ EOT
|
|
127
130
|
puts "It looks like you are the first one here, so let's begin."
|
128
131
|
print reset, "\n"
|
129
132
|
# print "\n"
|
130
|
-
unless Morpheus::Cli::OptionTypes.confirm("Would you like to setup and initialize the remote appliance now?", options)
|
131
|
-
|
132
|
-
end
|
133
|
-
print "\n"
|
133
|
+
# unless Morpheus::Cli::OptionTypes.confirm("Would you like to setup and initialize the remote appliance now?", options)
|
134
|
+
# return 9, "aborted command"
|
135
|
+
# end
|
136
|
+
# print "\n"
|
134
137
|
hubmode = nil
|
135
138
|
hub_init_payload = nil # gets included as payload for hub scoped like hub.email
|
136
139
|
if hub_settings['enabled']
|
@@ -354,6 +357,15 @@ EOT
|
|
354
357
|
payload.delete('hub')
|
355
358
|
end
|
356
359
|
|
360
|
+
# License Key prompt
|
361
|
+
print_h2 "License", options
|
362
|
+
if options[:license]
|
363
|
+
payload['licenseKey'] = options[:license].strip
|
364
|
+
else
|
365
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'licenseKey', 'fieldLabel' => 'License Key', 'type' => 'text', 'description' => "Enter a License Key to install now or leave blank to use a community license or install one manually later."}], options[:options])
|
366
|
+
key = v_prompt['licenseKey']
|
367
|
+
payload['licenseKey'] = key.strip if !key.to_s.strip.empty?
|
368
|
+
end
|
357
369
|
end
|
358
370
|
|
359
371
|
# ok, make the api request
|
@@ -383,24 +395,26 @@ EOT
|
|
383
395
|
print reset
|
384
396
|
#print "\n"
|
385
397
|
|
386
|
-
|
387
|
-
if
|
388
|
-
|
389
|
-
|
398
|
+
unless options[:no_prompt]
|
399
|
+
if hubmode == 'skip' && payload['licenseKey'].to_s.empty?
|
400
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to install your License Key now?", options.merge({:default => true}))
|
401
|
+
cmd_res = Morpheus::Cli::License.new.install([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
402
|
+
# license_is_valid = cmd_res != false
|
403
|
+
end
|
390
404
|
end
|
391
|
-
end
|
392
405
|
|
393
|
-
|
394
|
-
|
406
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to create the first group now?", options.merge({:default => true}))
|
407
|
+
cmd_res = Morpheus::Cli::Groups.new.add(['--use'] + (options[:remote] ? ["-r",options[:remote]] : []))
|
395
408
|
|
396
|
-
|
409
|
+
#print "\n"
|
397
410
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
411
|
+
# if cmd_res !=
|
412
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to create the first cloud now?", options.merge({:default => true}))
|
413
|
+
cmd_res = Morpheus::Cli::Clouds.new.add([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
414
|
+
#print "\n"
|
415
|
+
end
|
416
|
+
# end
|
417
|
+
end
|
404
418
|
end
|
405
419
|
print "\n",reset
|
406
420
|
return exit_code, err
|
@@ -531,6 +531,7 @@ EOT
|
|
531
531
|
v_prompt.deep_compact!
|
532
532
|
virtual_image_payload.deep_merge!(v_prompt)
|
533
533
|
virtual_image_files = virtual_image_payload.delete('virtualImageFiles')
|
534
|
+
upload_type = virtual_image_payload.delete('uploadType') # not used serverside
|
534
535
|
virtual_image_payload['imageType'] = image_type['code']
|
535
536
|
storage_provider_id = virtual_image_payload.delete('storageProviderId')
|
536
537
|
if !storage_provider_id.to_s.empty?
|
@@ -551,6 +552,11 @@ EOT
|
|
551
552
|
if virtual_image_payload && virtual_image_payload['imageType'] == 'vmware'
|
552
553
|
virtual_image_payload['imageType'] == 'vmdk'
|
553
554
|
end
|
555
|
+
# no need to make second request anymore, just include virtualImage.url
|
556
|
+
if file_url
|
557
|
+
virtual_image_payload['url'] = file_url
|
558
|
+
file_url = nil
|
559
|
+
end
|
554
560
|
#payload = {'virtualImage' => virtual_image_payload}
|
555
561
|
payload.deep_merge!({'virtualImage' => virtual_image_payload})
|
556
562
|
end
|
@@ -967,7 +973,7 @@ EOT
|
|
967
973
|
{'fieldName' => 'installAgent', 'fieldLabel' => 'Install Agent?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Install Agent?', 'displayOrder' => 6},
|
968
974
|
{'fieldName' => 'sshUsername', 'fieldLabel' => 'SSH Username', 'type' => 'text', 'required' => false, 'description' => 'Enter an SSH Username', 'displayOrder' => 7},
|
969
975
|
{'fieldName' => 'sshPassword', 'fieldLabel' => 'SSH Password', 'type' => 'password', 'required' => false, 'description' => 'Enter an SSH Password', 'displayOrder' => 8},
|
970
|
-
{'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => '
|
976
|
+
{'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => 'Bucket', 'optionSource' => 'storageProviders', 'required' => false, 'description' => 'Select Storage Provider.', 'displayOrder' => 9},
|
971
977
|
{'fieldName' => 'userData', 'fieldLabel' => 'Cloud-Init User Data', 'type' => 'textarea', 'required' => false, 'displayOrder' => 10},
|
972
978
|
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}], 'required' => false, 'description' => 'Visibility', 'category' => 'permissions', 'defaultValue' => 'private', 'displayOrder' => 40},
|
973
979
|
{'fieldName' => 'isAutoJoinDomain', 'fieldLabel' => 'Auto Join Domain?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Auto Join Domain?', 'category' => 'advanced', 'displayOrder' => 40},
|
@@ -999,7 +1005,9 @@ EOT
|
|
999
1005
|
tmp_option_types.reject! {|opt| ['storageProviderId', 'userData', 'sshUsername', 'sshPassword'].include?(opt['fieldName'])}
|
1000
1006
|
else
|
1001
1007
|
if include_file_selection
|
1002
|
-
tmp_option_types << {'
|
1008
|
+
tmp_option_types << {'code' => 'virtualImage.uploadType', 'fieldName' => 'uploadType', 'fieldLabel' => 'Create Image ID', 'type' => 'select', 'selectOptions' => [{'name' => 'File', 'value' => 'file'},{'name' => 'URL/Path', 'value' => 'url'},{'name' => 'None', 'value' => 'none'}], 'defaultValue' => 'file', 'required' => false, 'description' => 'Choose upload type: file, url or none', 'displayOrder' => 11}
|
1009
|
+
tmp_option_types << {'dependsOnCode' => 'virtualImage.uploadType:file', 'fieldContext' => 'virtualImageFiles', 'fieldName' => 'imageFile', 'fieldLabel' => 'Image File', 'type' => 'file', 'required' => false, 'description' => 'Choose an image file to upload', 'displayOrder' => 12}
|
1010
|
+
tmp_option_types << {'dependsOnCode' => 'virtualImage.uploadType:url', 'fieldName' => 'url', 'fieldLabel' => 'URL/Path', 'type' => 'text', 'required' => false, 'description' => 'Enter URL/Path to virtual image file(s)', 'displayOrder' => 13}
|
1003
1011
|
end
|
1004
1012
|
end
|
1005
1013
|
end
|
@@ -2150,25 +2150,51 @@ module Morpheus::Cli::ProvisioningHelper
|
|
2150
2150
|
end
|
2151
2151
|
|
2152
2152
|
# Tenants
|
2153
|
+
default_stores = []
|
2154
|
+
default_targets = []
|
2153
2155
|
unless excludes.include?('tenants')
|
2154
2156
|
if !options[:tenants].nil?
|
2155
2157
|
accounts = options[:tenants].collect {|id| id.to_i}
|
2156
2158
|
elsif !options[:no_prompt]
|
2157
2159
|
account_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'account', 'type' => 'select', 'fieldLabel' => 'Add Tenant', 'selectOptions' => available_accounts, 'required' => false, 'description' => 'Add Tenant Permissions.'}], options[:options], @api_client, {})['account']
|
2158
2160
|
|
2159
|
-
|
2161
|
+
unless account_id.nil?
|
2160
2162
|
accounts << account_id
|
2161
2163
|
available_accounts = available_accounts.reject {|it| it['value'] == account_id}
|
2162
2164
|
|
2165
|
+
# Prompt default store / target
|
2166
|
+
if options[:for_datastore]
|
2167
|
+
if Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultTarget', 'type' => 'checkbox', 'fieldLabel' => 'Default', 'required' => false, 'description' => 'Designate as Default Store.', 'defaultValue' => false}], options[:options].merge({:checkbox_as_boolean => true}), @api_client, {})['defaultTarget']
|
2168
|
+
default_targets << account_id
|
2169
|
+
end
|
2170
|
+
if Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultStore', 'type' => 'checkbox', 'fieldLabel' => 'Image Target', 'required' => false, 'description' => 'Designate as Image Target.', 'defaultValue' => false}], options[:options].merge({:checkbox_as_boolean => true}), @api_client, {})['defaultStore']
|
2171
|
+
default_stores << account_id
|
2172
|
+
end
|
2173
|
+
end
|
2174
|
+
|
2163
2175
|
while !available_accounts.empty? && (account_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'account', 'type' => 'select', 'fieldLabel' => 'Add Another Tenant', 'selectOptions' => available_accounts, 'required' => false, 'description' => 'Add Tenant Permissions.'}], options[:options], @api_client, {})['account'])
|
2164
2176
|
if !account_id.nil?
|
2165
2177
|
accounts << account_id
|
2166
2178
|
available_accounts = available_accounts.reject {|it| it['value'] == account_id}
|
2179
|
+
|
2180
|
+
# Prompt default store / target
|
2181
|
+
if options[:for_datastore]
|
2182
|
+
if Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultTarget', 'type' => 'checkbox', 'fieldLabel' => 'Default', 'required' => false, 'description' => 'Designate as Default Store.', 'defaultValue' => false}], options[:options].merge({:checkbox_as_boolean => true}), @api_client, {})['defaultTarget']
|
2183
|
+
default_targets << account_id
|
2184
|
+
end
|
2185
|
+
if Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultStore', 'type' => 'checkbox', 'fieldLabel' => 'Image Target', 'required' => false, 'description' => 'Designate as Image Target.', 'defaultValue' => false}], options[:options].merge({:checkbox_as_boolean => true}), @api_client, {})['defaultStore']
|
2186
|
+
default_stores << account_id
|
2187
|
+
end
|
2188
|
+
end
|
2167
2189
|
end
|
2168
2190
|
end
|
2169
2191
|
end
|
2170
2192
|
end
|
2171
|
-
|
2193
|
+
if options[:for_datastore]
|
2194
|
+
permissions['tenantPermissions'] = accounts.collect {|it| {'id' => it, 'defaultStore' => default_stores.include?(it), 'defaultTarget' => default_targets.include?(it)}}
|
2195
|
+
else
|
2196
|
+
permissions['tenantPermissions'] = {'accounts' => accounts}
|
2197
|
+
end
|
2172
2198
|
end
|
2173
2199
|
end
|
2174
2200
|
permissions
|
@@ -404,6 +404,9 @@ module Morpheus
|
|
404
404
|
value = password_prompt(option_type)
|
405
405
|
elsif option_type['type'] == 'checkbox'
|
406
406
|
value = checkbox_prompt(option_type)
|
407
|
+
if options[:checkbox_as_boolean]
|
408
|
+
value = (value == 'on')
|
409
|
+
end
|
407
410
|
elsif option_type['type'] == 'radio'
|
408
411
|
value = radio_prompt(option_type)
|
409
412
|
elsif option_type['type'] == 'textarea'
|
@@ -1324,15 +1327,19 @@ module Morpheus
|
|
1324
1327
|
|
1325
1328
|
# supports multi-part fields via config.fields
|
1326
1329
|
# {"fields": [{"name":"tag", "required":true, "label": "Tag"}, {"name":"value", "required":false, "label": "Scope"}]}
|
1330
|
+
min_count = option_type['minCount'] || 1
|
1331
|
+
count = 0
|
1332
|
+
|
1327
1333
|
if option_type['config']['fields']
|
1328
|
-
while (option_type['required'] && rtn.empty?) || self.confirm("Add#{rtn.empty? ? '': ' more'} #{option_type['fieldLabel']}?", {:default => false})
|
1334
|
+
while (option_type['required'] && (rtn.empty? || count < min_count)) || self.confirm("Add#{rtn.empty? ? '': ' more'} #{option_type['fieldLabel']}?", {:default => false})
|
1329
1335
|
rtn ||= []
|
1330
1336
|
value = {}
|
1331
1337
|
option_type['config']['fields'].each do |field|
|
1332
1338
|
field_label = field['label'] || field['name'].capitalize
|
1333
|
-
value[field['name']] = generic_prompt(option_type.merge({'fieldLabel' => field_label, 'required' => field['required'], 'description' => "#{option_type['fieldLabel']} #{field_label}"}))
|
1339
|
+
value[field['name']] = generic_prompt(option_type.merge({'fieldLabel' => min_count > 1 ? "#{field_label} #{count + 1}" : field_label, 'required' => field['required'], 'description' => "#{option_type['fieldLabel']} #{field_label}"}))
|
1334
1340
|
end
|
1335
1341
|
rtn << value
|
1342
|
+
count += 1
|
1336
1343
|
end
|
1337
1344
|
else
|
1338
1345
|
if rtn = generic_prompt(option_type)
|
data/lib/morpheus/cli/version.rb
CHANGED
data/lib/morpheus/formatters.rb
CHANGED
@@ -478,6 +478,18 @@ def format_name_values(obj)
|
|
478
478
|
end
|
479
479
|
end
|
480
480
|
|
481
|
+
def format_name_and_id(obj)
|
482
|
+
if(obj.is_a?(Array))
|
483
|
+
return "" if obj.empty? # && hide_empty
|
484
|
+
names, ids = obj.collect {|it| it['name'] rescue "" }, obj.collect {|it| it['id'] rescue "" }
|
485
|
+
"#{names.join(", ")} [#{ids.join(",")}]"
|
486
|
+
elsif(obj.is_a?(Hash))
|
487
|
+
"#{obj['name']} [#{obj['id']}]" rescue ""
|
488
|
+
else
|
489
|
+
object.to_s
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
481
493
|
def a_or_an(v)
|
482
494
|
v.to_s =~ /^[aeiou]/i ? "an" : "a"
|
483
495
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 8.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2024-
|
14
|
+
date: 2024-11-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: public_suffix
|
@@ -289,6 +289,7 @@ files:
|
|
289
289
|
- lib/morpheus/api/library_container_upgrades_interface.rb
|
290
290
|
- lib/morpheus/api/library_instance_types_interface.rb
|
291
291
|
- lib/morpheus/api/library_layouts_interface.rb
|
292
|
+
- lib/morpheus/api/library_operating_systems_interface.rb
|
292
293
|
- lib/morpheus/api/library_spec_template_types_interface.rb
|
293
294
|
- lib/morpheus/api/library_spec_templates_interface.rb
|
294
295
|
- lib/morpheus/api/license_interface.rb
|
@@ -473,6 +474,7 @@ files:
|
|
473
474
|
- lib/morpheus/cli/commands/library_forms_command.rb
|
474
475
|
- lib/morpheus/cli/commands/library_instance_types_command.rb
|
475
476
|
- lib/morpheus/cli/commands/library_layouts_command.rb
|
477
|
+
- lib/morpheus/cli/commands/library_operating_systems_command.rb
|
476
478
|
- lib/morpheus/cli/commands/library_option_lists_command.rb
|
477
479
|
- lib/morpheus/cli/commands/library_option_types_command.rb
|
478
480
|
- lib/morpheus/cli/commands/library_spec_templates_command.rb
|
@@ -667,7 +669,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
667
669
|
- !ruby/object:Gem::Version
|
668
670
|
version: '0'
|
669
671
|
requirements: []
|
670
|
-
rubygems_version: 3.
|
672
|
+
rubygems_version: 3.4.10
|
671
673
|
signing_key:
|
672
674
|
specification_version: 4
|
673
675
|
summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance
|