morpheus-cli 7.0.6 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +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
|