morpheus-cli 6.3.0 → 6.3.2
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 +3 -6
- data/lib/morpheus/api/api_client.rb +8 -0
- data/lib/morpheus/api/library_cluster_packages_interface.rb +60 -0
- data/lib/morpheus/api/option_type_forms_interface.rb +9 -0
- data/lib/morpheus/cli/cli_command.rb +3 -1
- data/lib/morpheus/cli/cli_registry.rb +2 -4
- data/lib/morpheus/cli/commands/backups_command.rb +1 -1
- data/lib/morpheus/cli/commands/catalog_item_types_command.rb +54 -12
- data/lib/morpheus/cli/commands/certificates_command.rb +1 -1
- data/lib/morpheus/cli/commands/cloud_folders_command.rb +18 -1
- data/lib/morpheus/cli/commands/library_cluster_packages_command.rb +552 -0
- data/lib/morpheus/cli/commands/library_forms_command.rb +625 -0
- data/lib/morpheus/cli/commands/network_servers_command.rb +19 -9
- data/lib/morpheus/cli/commands/self_service_command.rb +17 -0
- data/lib/morpheus/cli/commands/service_catalog_command.rb +72 -31
- data/lib/morpheus/cli/commands/virtual_images.rb +1 -1
- data/lib/morpheus/cli/error_handler.rb +18 -3
- data/lib/morpheus/cli/mixins/print_helper.rb +20 -6
- data/lib/morpheus/cli/mixins/prompt_helper.rb +132 -11
- data/lib/morpheus/cli/option_types.rb +182 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/routes.rb +9 -0
- metadata +7 -2
@@ -23,8 +23,8 @@ class Morpheus::Cli::NetworkServersCommand
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def add(args)
|
26
|
-
options = {}
|
27
|
-
params =
|
26
|
+
options = {params: {}}
|
27
|
+
params = options[:params]
|
28
28
|
ip_range_list = nil
|
29
29
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
30
30
|
opts.banner = subcommand_usage("[name]")
|
@@ -55,18 +55,20 @@ EOT
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# merge -O options into normally parsed options
|
58
|
-
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
58
|
+
#params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
59
59
|
|
60
60
|
# construct payload
|
61
61
|
payload = nil
|
62
62
|
if options[:payload]
|
63
63
|
payload = options[:payload]
|
64
|
+
payload.deep_merge!({rest_object_key => parse_passed_options(options)})
|
65
|
+
payload.deep_merge!({rest_object_key => params})
|
64
66
|
else
|
65
|
-
|
66
|
-
|
67
|
+
payload = {}
|
68
|
+
payload.deep_merge!({rest_object_key => parse_passed_options(options)})
|
67
69
|
# Name
|
68
70
|
if !params['name']
|
69
|
-
params['name'] = prompt_value({'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network server.'},
|
71
|
+
params['name'] = prompt_value({'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network server.'}, options)
|
70
72
|
# params['name'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network server.'}], params, @api_client, {}, options[:no_prompt])['name']
|
71
73
|
end
|
72
74
|
|
@@ -93,7 +95,7 @@ EOT
|
|
93
95
|
end
|
94
96
|
network_type_code = selected_type['code']
|
95
97
|
else
|
96
|
-
network_type_code = prompt_value({'fieldName' => 'type', 'fieldLabel' => 'Network Server Type', 'type' => 'select', 'selectOptions' => network_server_type_options, 'required' => true, 'description' => 'Choose a network server type.'}, params
|
98
|
+
network_type_code = prompt_value({'fieldName' => 'type', 'fieldLabel' => 'Network Server Type', 'type' => 'select', 'selectOptions' => network_server_type_options, 'required' => true, 'description' => 'Choose a network server type.'}, options.merge(params))
|
97
99
|
#network_type_code = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Network Server Type', 'type' => 'select', 'selectOptions' => network_server_type_options, 'required' => true, 'description' => 'Choose a network server type.'}], options, @api_client, {}, options[:no_prompt])['type']
|
98
100
|
selected_type = network_server_type_options.find {|it| it['code'] == network_type_code }
|
99
101
|
if selected_type.nil?
|
@@ -106,9 +108,9 @@ EOT
|
|
106
108
|
# prompt options by type
|
107
109
|
network_server_type = @network_server_types_interface.get(network_type_id.to_i)['networkServerType']
|
108
110
|
# params['type'] = network_server_type['code']
|
109
|
-
option_result =
|
111
|
+
option_result = prompt(network_server_type['optionTypes'], options.merge({:context_map => {'networkServer' => ''}}))
|
110
112
|
params.deep_merge!(option_result)
|
111
|
-
payload
|
113
|
+
payload.deep_merge!({rest_object_key => params})
|
112
114
|
end
|
113
115
|
@network_servers_interface.setopts(options)
|
114
116
|
if options[:dry_run]
|
@@ -218,6 +220,14 @@ EOT
|
|
218
220
|
|
219
221
|
private
|
220
222
|
|
223
|
+
def network_server_list_key
|
224
|
+
'networkServers'
|
225
|
+
end
|
226
|
+
|
227
|
+
def network_server_object_key
|
228
|
+
'networkServer'
|
229
|
+
end
|
230
|
+
|
221
231
|
# def render_response_for_get(json_response, options)
|
222
232
|
# # load the type and show fields dynamically based on optionTypes
|
223
233
|
# render_response(json_response, options, rest_object_key) do
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
require 'morpheus/cli/commands/catalog_item_types_command'
|
3
|
+
|
4
|
+
class Morpheus::Cli::SelfServiceCommand
|
5
|
+
include Morpheus::Cli::CliCommand
|
6
|
+
|
7
|
+
set_command_name :'self-service'
|
8
|
+
set_command_description "Deprecated and replaced by catalog-item-types"
|
9
|
+
|
10
|
+
set_command_hidden
|
11
|
+
|
12
|
+
def handle(args)
|
13
|
+
print_error yellow,"[DEPRECATED] The command `self-service` is deprecated and replaced by `catalog-item-types`.",reset,"\n"
|
14
|
+
Morpheus::Cli::CatalogItemTypesCommand.new.handle(args)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -308,7 +308,7 @@ EOT
|
|
308
308
|
catalog_item_type = json_response[catalog_item_type_object_key]
|
309
309
|
# need to load by id to get optionTypes
|
310
310
|
# maybe do ?name=foo&includeOptionTypes=true
|
311
|
-
if catalog_item_type['optionTypes'].nil?
|
311
|
+
if catalog_item_type['optionTypes'].nil? && catalog_item_type['form'].nil?
|
312
312
|
catalog_item_type = find_catalog_item_type_by_id(catalog_item_type['id'])
|
313
313
|
return [1, "catalog item type not found"] if catalog_item_type.nil?
|
314
314
|
end
|
@@ -318,14 +318,25 @@ EOT
|
|
318
318
|
show_columns = catalog_item_type_column_definitions
|
319
319
|
print_description_list(show_columns, catalog_item_type)
|
320
320
|
|
321
|
+
form = catalog_item_type['form']
|
322
|
+
if form
|
323
|
+
# print_h2 "Configuration Options (Form: #{form['name']})"
|
324
|
+
print_h2 "Configuration Options"
|
325
|
+
form_inputs = (form['options'] || [])
|
326
|
+
if form['fieldGroups']
|
327
|
+
form['fieldGroups'].each { |field_group| form_inputs += (field_group['options'] || []) }
|
328
|
+
end
|
329
|
+
#print format_simple_option_types_table(form_inputs, options)
|
330
|
+
print format_option_types_table(form_inputs, options, 'config.customOptions')
|
331
|
+
# print reset,"\n"
|
332
|
+
else
|
333
|
+
# print cyan,"No form inputs found for this catalog item.","\n",reset
|
334
|
+
end
|
335
|
+
|
321
336
|
if catalog_item_type['optionTypes'] && catalog_item_type['optionTypes'].size > 0
|
322
337
|
print_h2 "Configuration Options"
|
323
|
-
print
|
324
|
-
|
325
|
-
"NAME" => lambda {|it| it['fieldName'] },
|
326
|
-
"TYPE" => lambda {|it| it['type'] },
|
327
|
-
"REQUIRED" => lambda {|it| format_boolean it['required'] },
|
328
|
-
})
|
338
|
+
#print format_simple_option_types_table(catalog_item_type['optionTypes'], options)
|
339
|
+
print format_option_types_table(catalog_item_type['optionTypes'], options, 'config.customOptions')
|
329
340
|
else
|
330
341
|
# print cyan,"No option types found for this catalog item.","\n",reset
|
331
342
|
end
|
@@ -645,21 +656,38 @@ EOT
|
|
645
656
|
|
646
657
|
# this is silly, need to load by id to get optionTypes
|
647
658
|
# maybe do ?name=foo&includeOptionTypes=true
|
648
|
-
if catalog_item_type['optionTypes'].nil?
|
659
|
+
if catalog_item_type['optionTypes'].nil? && catalog_item_type['form'].nil?
|
649
660
|
catalog_item_type = find_catalog_item_type_by_id(catalog_item_type['id'])
|
650
661
|
return [1, "catalog item type not found"] if catalog_item_type.nil?
|
651
662
|
end
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
config_prompt = Morpheus::Cli::OptionTypes.prompt(catalog_option_types, options[:options], @api_client, api_params, options[:no_prompt], false, false, true)['config']
|
663
|
+
|
664
|
+
if catalog_item_type['formType'] == 'form'
|
665
|
+
# prompt for form options
|
666
|
+
if catalog_item_type['form'].nil?
|
667
|
+
raise_command_error "No form found for catalog item type '#{catalog_item_type['name']}'"
|
668
|
+
end
|
669
|
+
# use the new PromptHelper method prompt_form()
|
670
|
+
config_prompt = prompt_form(catalog_item_type['form'], options.merge({:context_map => {'config.customOptions' => 'config'}, :api_params => construct_catalog_api_params(catalog_item_type)}))['config']
|
661
671
|
payload[add_item_object_key].deep_merge!({'config' => config_prompt})
|
672
|
+
else
|
673
|
+
# prompt for optionTypes
|
674
|
+
catalog_option_types = catalog_item_type['optionTypes']
|
675
|
+
if catalog_option_types.nil?
|
676
|
+
#raise_command_error "No options found for catalog item type '#{catalog_item_type['name']}'"
|
677
|
+
catalog_option_types = []
|
678
|
+
end
|
679
|
+
# instead of config.customOptions just use config...
|
680
|
+
catalog_option_types = catalog_option_types.collect {|it|
|
681
|
+
it['fieldContext'] = 'config'
|
682
|
+
it
|
683
|
+
}
|
684
|
+
if catalog_option_types && !catalog_option_types.empty?
|
685
|
+
api_params = construct_catalog_api_params(catalog_item_type)
|
686
|
+
config_prompt = Morpheus::Cli::OptionTypes.prompt(catalog_option_types, options[:options], @api_client, api_params, options[:no_prompt], false, false, true)['config']
|
687
|
+
payload[add_item_object_key].deep_merge!({'config' => config_prompt})
|
688
|
+
end
|
662
689
|
end
|
690
|
+
|
663
691
|
if workflow_context
|
664
692
|
payload[add_item_object_key]['context'] = workflow_context
|
665
693
|
else
|
@@ -673,7 +701,7 @@ EOT
|
|
673
701
|
elsif !catalog_item_type['context'].nil?
|
674
702
|
workflow_context = catalog_item_type['context']
|
675
703
|
end
|
676
|
-
payload[add_item_object_key]['context'] = workflow_context
|
704
|
+
payload[add_item_object_key]['context'] = workflow_context if workflow_context
|
677
705
|
end
|
678
706
|
|
679
707
|
if workflow_target
|
@@ -981,23 +1009,35 @@ EOT
|
|
981
1009
|
|
982
1010
|
# this is silly, need to load by id to get optionTypes
|
983
1011
|
# maybe do ?name=foo&includeOptionTypes=true
|
984
|
-
if catalog_item_type['optionTypes'].nil?
|
1012
|
+
if catalog_item_type['optionTypes'].nil? && catalog_item_type['form'].nil?
|
985
1013
|
catalog_item_type = find_catalog_item_type_by_id(catalog_item_type['id'])
|
986
1014
|
return [1, "catalog item type not found"] if catalog_item_type.nil?
|
987
1015
|
end
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
api_params = construct_catalog_api_params(catalog_item_type)
|
997
|
-
config_prompt = Morpheus::Cli::OptionTypes.prompt(catalog_option_types, options[:options], @api_client, api_params, options[:no_prompt], false, false, true)['config']
|
1016
|
+
|
1017
|
+
if catalog_item_type['formType'] == 'form'
|
1018
|
+
# prompt for form options
|
1019
|
+
if catalog_item_type['form'].nil?
|
1020
|
+
raise_command_error "No form found for catalog item type '#{catalog_item_type['name']}'"
|
1021
|
+
end
|
1022
|
+
# use the new PromptHelper method prompt_form()
|
1023
|
+
config_prompt = prompt_form(catalog_item_type['form'], options.merge({:context_map => {'config.customOptions' => 'config'}, :api_params => construct_catalog_api_params(catalog_item_type)}))['config']
|
998
1024
|
item_payload.deep_merge!({'config' => config_prompt})
|
1025
|
+
else
|
1026
|
+
# prompt for optionTypes
|
1027
|
+
catalog_option_types = catalog_item_type['optionTypes']
|
1028
|
+
# instead of config.customOptions just use config...
|
1029
|
+
catalog_option_types = catalog_option_types.collect {|it|
|
1030
|
+
it['fieldContext'] = nil
|
1031
|
+
it['fieldContext'] = 'config'
|
1032
|
+
it
|
1033
|
+
}
|
1034
|
+
if catalog_option_types && !catalog_option_types.empty?
|
1035
|
+
api_params = construct_catalog_api_params(catalog_item_type)
|
1036
|
+
config_prompt = Morpheus::Cli::OptionTypes.prompt(catalog_option_types, options[:options], @api_client, api_params, options[:no_prompt], false, false, true)['config']
|
1037
|
+
item_payload.deep_merge!({'config' => config_prompt})
|
1038
|
+
end
|
999
1039
|
end
|
1000
|
-
|
1040
|
+
|
1001
1041
|
if workflow_context
|
1002
1042
|
item_payload['context'] = workflow_context
|
1003
1043
|
else
|
@@ -1465,7 +1505,8 @@ EOT
|
|
1465
1505
|
# this should be fixed on the api side, so it automatically extracts this input from the config
|
1466
1506
|
begin
|
1467
1507
|
instance_type_code = nil
|
1468
|
-
catalog_item_type =
|
1508
|
+
catalog_item_type = record
|
1509
|
+
#catalog_item_type = find_by_id(:catalog_item_type, catalog_item_type_id.to_i)
|
1469
1510
|
if catalog_item_type
|
1470
1511
|
if catalog_item_type['type'] == 'instance'
|
1471
1512
|
if catalog_item_type['config'] && catalog_item_type['config']['type']
|
@@ -847,7 +847,7 @@ EOT
|
|
847
847
|
print_description_list(virtual_image_location_column_definitions, location, options)
|
848
848
|
if volumes && !volumes.empty?
|
849
849
|
print_h2 "Volumes", options
|
850
|
-
volume_rows =
|
850
|
+
volume_rows = volumes.collect do |volume|
|
851
851
|
{name: volume['name'], size: Filesize.from("#{volume['rawSize']} B").pretty}
|
852
852
|
end
|
853
853
|
print cyan
|
@@ -216,9 +216,11 @@ class Morpheus::Cli::ErrorHandler
|
|
216
216
|
@stderr.puts response['msg']
|
217
217
|
end
|
218
218
|
if response['errors']
|
219
|
-
response['errors'].each do |key, value|
|
220
|
-
|
221
|
-
end
|
219
|
+
# response['errors'].each do |key, value|
|
220
|
+
# @stderr.print "* #{key}: #{value}\n"
|
221
|
+
# end
|
222
|
+
# puts as_yaml(response['errors'])
|
223
|
+
@stderr.print format_rest_errors(response['errors'])
|
222
224
|
end
|
223
225
|
@stderr.print reset
|
224
226
|
else
|
@@ -231,6 +233,19 @@ class Morpheus::Cli::ErrorHandler
|
|
231
233
|
end
|
232
234
|
end
|
233
235
|
|
236
|
+
def format_rest_errors(errors, context=nil)
|
237
|
+
out = ""
|
238
|
+
Hash(errors).each do |key, value|
|
239
|
+
if value.is_a?(Hash)
|
240
|
+
out << format_rest_errors(value, context ? "#{context}.#{key}" : key)
|
241
|
+
else
|
242
|
+
prefix = context ? (context + '.') : ''
|
243
|
+
out << "* #{prefix}#{key}: #{value}\n"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
out
|
247
|
+
end
|
248
|
+
|
234
249
|
def print_rest_request(req)
|
235
250
|
@stderr.print "REQUEST"
|
236
251
|
@stderr.print "\n"
|
@@ -1511,6 +1511,8 @@ module Morpheus::Cli::PrintHelper
|
|
1511
1511
|
end
|
1512
1512
|
|
1513
1513
|
def format_option_types_table(option_types, options={}, domain_name=nil)
|
1514
|
+
show_option_source = option_types.find {|it| !it['optionList'].to_s.empty? || !it['optionSource'].to_s.empty? }
|
1515
|
+
show_default = option_types.find {|it| !it['defaultValue'].nil? }
|
1514
1516
|
columns = [
|
1515
1517
|
{"FIELD LABEL" => lambda {|it| it['fieldLabel'] } },
|
1516
1518
|
{"FIELD NAME" => lambda {|it|
|
@@ -1521,17 +1523,29 @@ module Morpheus::Cli::PrintHelper
|
|
1521
1523
|
end
|
1522
1524
|
} },
|
1523
1525
|
{"TYPE" => lambda {|it| it['type'] } },
|
1524
|
-
{"
|
1525
|
-
|
1526
|
+
{"REQUIRED" => lambda {|it| format_boolean it['required'] } },
|
1527
|
+
show_option_source ? {"OPTION SOURCE" => lambda {|it|
|
1528
|
+
if it['optionList']
|
1529
|
+
it['optionList']['name']
|
1530
|
+
elsif it['optionSourceType']
|
1526
1531
|
"#{it['optionSourceType']}/#{it['optionSource']}"
|
1527
1532
|
else
|
1528
1533
|
"#{it['optionSource']}"
|
1529
1534
|
end
|
1530
|
-
} },
|
1531
|
-
{"DEFAULT" => lambda {|it| it['defaultValue'] } },
|
1532
|
-
|
1533
|
-
]
|
1535
|
+
} } : nil,
|
1536
|
+
show_default ? {"DEFAULT" => lambda {|it| it['defaultValue'] } } : nil,
|
1537
|
+
].compact
|
1534
1538
|
as_pretty_table(option_types, columns, options)
|
1535
1539
|
end
|
1540
|
+
|
1541
|
+
def format_simple_option_types_table(option_types, options={})
|
1542
|
+
as_pretty_table(option_types, {
|
1543
|
+
"LABEL" => lambda {|it| it['fieldLabel'] },
|
1544
|
+
"NAME" => lambda {|it| it['fieldName'] },
|
1545
|
+
"TYPE" => lambda {|it| it['type'] },
|
1546
|
+
"REQUIRED" => lambda {|it| format_boolean it['required'] },
|
1547
|
+
"DEFAULT" => lambda {|it| it['defaultValue'] },
|
1548
|
+
}, options)
|
1549
|
+
end
|
1536
1550
|
|
1537
1551
|
end
|
@@ -1,15 +1,136 @@
|
|
1
|
+
require 'morpheus/cli/option_types'
|
2
|
+
|
1
3
|
# Mixin for Morpheus::Cli command classes
|
2
|
-
# Provides common methods for prompting for
|
4
|
+
# Provides common methods for prompting for option type inputs and forms.
|
5
|
+
# Prompting is delegated to the {Morpheus::Cli::OptionTypes} module
|
6
|
+
# while the provided {#prompt} simplifies the required parameters
|
7
|
+
# The command class must establish the +@api_client+ on its own.
|
8
|
+
#
|
3
9
|
module Morpheus::Cli::PromptHelper
|
4
10
|
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
# @param
|
9
|
-
#
|
10
|
-
# @
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# Prompt for a list of inputs (OptionType) and return a Hash containing
|
12
|
+
# all of the provides values. The user is prompted to provide a value
|
13
|
+
# for each input, unless the value is already set in the options.
|
14
|
+
# @param [Array, Hash] option_types the list of OptionType inputs with fieldName, fieldLabel, etc.
|
15
|
+
# A single option type Hash can be passed instead.
|
16
|
+
# @param [Hash] options the standard command options
|
17
|
+
# This map is a mixture of keys that are Symbols that provide some common
|
18
|
+
# functionality like :no_prompt, :context_map, etc.
|
19
|
+
# Any keys that are Strings get used to lookup input values, along with
|
20
|
+
# +options[:options]+ and +options[:params]+.
|
21
|
+
# The precedence for providing option values is as follows:
|
22
|
+
# 1. options['foo'] 2. options[:params]['foo'] 3. options[:options]['foo'] 4. User is prompted.
|
23
|
+
# @option options [Hash] :options map of values provided by the user via the generic -O OPTIONS switch, gets merged into the context used for providing input values
|
24
|
+
# @option options [Hash] :params map of additional values provided by the user via explicite options, gets merged into the context used for providing input values
|
25
|
+
# @option options [Hash] :no_prompt supresses prompting, use default values and error if a required input is not provided. Default is of course +false+.
|
26
|
+
# @option options [Hash] :context_map Can to change the fieldContext of the option_types, eg. :context_map => {'networkDhcpRelay' => ''}
|
27
|
+
# @option options [APIClient] :api_client The {APIClient} to use for option types that request api calls. Default is the @api_client established by the class
|
28
|
+
# @option options [Hash] :api_params Optional map of parameters to include in API request for select option types
|
29
|
+
# @option options [Boolean] :paging_enabled Enable paging if there are a lot of available options to display. Default is +false+.
|
30
|
+
# @option options [Boolean] :ignore_empty Ignore inputs that have no options, this can be used to allow prompting to continue without error if a select input has no options.
|
31
|
+
# @option options [Boolean] :skip_sort Do not sort the inputs by displayOrder, assume they are already sorted. Default is +true+.
|
32
|
+
# @return [Hash] containing the values provided for each option type, the key is the input fieldName
|
33
|
+
#
|
34
|
+
# @example Prompt for name
|
35
|
+
#
|
36
|
+
# results = prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true}], options)
|
37
|
+
# puts "Name: #{results['name']}"
|
38
|
+
#
|
39
|
+
def prompt(option_types, options={})
|
40
|
+
# option types can be passed as a single input instead of an array
|
41
|
+
option_types = option_types.is_a?(Hash) ? [option_types] : option_types #Array(option_types)
|
42
|
+
# construct options parameter for Morpheus::Cli::OptionTypes.prompt
|
43
|
+
options = construct_prompt_options(options)
|
44
|
+
# by default the @api_client established by the command is used
|
45
|
+
api_client = options.key?(:api_client) ? options[:api_client] : @api_client
|
46
|
+
api_params = options.key?(:api_params) ? options[:api_params] : {}
|
47
|
+
no_prompt = options.key?(:no_prompt) ? options[:no_prompt] : false
|
48
|
+
paging_enabled = options.key?(:paging_enabled) ? options[:paging_enabled] : true
|
49
|
+
ignore_empty = options.key?(:ignore_empty) ? options[:ignore_empty] : false
|
50
|
+
# Defaulting skip_sort to true which is the opposite of OptionTypes.prompt()
|
51
|
+
# The API handles sorting most of the time now, calling function can sort before prompting if needed
|
52
|
+
# maybe switch this later if needed, removing skip_sort would be nice though...
|
53
|
+
skip_sort = options.key?(:skip_sort) ? options[:skip_sort] : true
|
54
|
+
results = Morpheus::Cli::OptionTypes.prompt(option_types, options, api_client, api_params, no_prompt, paging_enabled, ignore_empty, skip_sort)
|
55
|
+
# trying to get rid of the need to do these compact and booleanize calls..
|
56
|
+
# for now you can use options.merge({compact: true,booleanize: true}) or modify the results yourself
|
57
|
+
results.deep_compact! if options[:compact]
|
58
|
+
results.booleanize! if options[:booleanize] # 'on' => true
|
59
|
+
return results
|
60
|
+
end
|
61
|
+
|
62
|
+
# Process 1-N inputs (OptionType) in a special 'edit mode' that supresses user interaction.
|
63
|
+
# This is used by +update+ commands where we want to process option types
|
64
|
+
# without prompting the user so that the results only contains values that are passed in explicitely as options and default values are not used.
|
65
|
+
# @see {#prompt} method for details on the supported options
|
66
|
+
#
|
67
|
+
def no_prompt(option_types, options={})
|
68
|
+
options = options.merge({:edit_mode => true, :no_prompt => true})
|
69
|
+
options.delete(:no_prompt) if options[:always_prompt] # --prompt to always prompt
|
70
|
+
return prompt(option_types, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Prompt for a single input and return only the value
|
74
|
+
# @param [Hash] option_type the OptionType input record to prompt for, contains fieldName, fieldLabel, etc.
|
75
|
+
# @param [Hash] options the standard command options
|
76
|
+
# @see {#prompt} method for details on the supported options
|
77
|
+
# @return [String, Number, Hash, Array, nil] value provided by the options or user input, usually a string or a number or nil if no value is provided.
|
78
|
+
#
|
79
|
+
# @example Prompt for name value
|
80
|
+
#
|
81
|
+
# chosen_name = prompt_value({'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true}, options)
|
82
|
+
# puts "Chosen Name: #{chosen_name}"
|
83
|
+
#
|
84
|
+
def prompt_value(option_type, options={})
|
85
|
+
# this does not need with fieldContext, so get rid of it
|
86
|
+
# option_types = [option_type.merge({'fieldContext' => nil})]
|
87
|
+
# results = prompt(Array(option_type), options)
|
88
|
+
# return results[option_type['fieldName']]
|
89
|
+
|
90
|
+
# this works with fieldContext now, hooray
|
91
|
+
# use get_object_value() to traverse object to get the value
|
92
|
+
option_types = [option_type] # Array(option_type)
|
93
|
+
results = prompt(option_types, options)
|
94
|
+
return get_option_type_value(results, option_types.first)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Process inputs of a form, prompting for its options and field groups
|
98
|
+
# @param [Hash] form the OptionTypeForm to process
|
99
|
+
# @param [Hash] options the standard command options
|
100
|
+
# @see {#prompt} method for defailts on the supported options
|
101
|
+
# @return Hash containing the values provided for each option type, the key is the fieldName
|
102
|
+
#
|
103
|
+
def prompt_form(form, options={})
|
104
|
+
form_results = {}
|
105
|
+
results = prompt(Array(form['options']), options.merge(form_results))
|
106
|
+
form_results.deep_merge!(results)
|
107
|
+
# prompt for each field group, merging results into options context as we go
|
108
|
+
Array(form['fieldGroups']).each do |field_group|
|
109
|
+
# todo: look at isCollapsible, defaultCollapsed and visibleOnCode to see if the group should
|
110
|
+
# if collapsed then just use options.merge({:no_prompt => true}) and maybe need to set :required => false ?
|
111
|
+
results = prompt(field_group['options'], options.merge(form_results))
|
112
|
+
form_results.deep_merge!(results)
|
113
|
+
end
|
114
|
+
return form_results
|
115
|
+
end
|
116
|
+
|
117
|
+
protected
|
118
|
+
|
119
|
+
# construct options parameter for Morpheus::Cli::OptionTypes.prompt
|
120
|
+
# This options Hash is a mixture of Symbols that provide some common functionality like :no_prompt, and :context_map, etc.
|
121
|
+
# String keys are used to lookup values being passed into the command in order to prevent prompting the user
|
122
|
+
# The precedence for providing option values is as follows:
|
123
|
+
# 1. options['foo'] 2. options[:params]['foo'] 3. options[:options]['foo']
|
124
|
+
#
|
125
|
+
def construct_prompt_options(options)
|
126
|
+
passed_options = Hash(options[:options]).select {|k,v| k.is_a?(String) }
|
127
|
+
params = Hash(options[:params]).select {|k,v| k.is_a?(String) }
|
128
|
+
return passed_options.deep_merge(params).deep_merge!(options)
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_option_type_value(results, option_type)
|
132
|
+
field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
133
|
+
get_object_value(results, field_key)
|
134
|
+
end
|
135
|
+
|
15
136
|
end
|