morpheus-cli 6.2.3 → 6.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 +4 -1
- data/lib/morpheus/api/api_client.rb +8 -0
- data/lib/morpheus/api/library_cluster_packages_interface.rb +41 -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/clusters.rb +1 -2
- data/lib/morpheus/cli/commands/library_cluster_packages_command.rb +485 -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/policies_command.rb +112 -128
- data/lib/morpheus/cli/commands/roles.rb +3 -0
- data/lib/morpheus/cli/commands/self_service_command.rb +17 -0
- data/lib/morpheus/cli/commands/service_catalog_command.rb +70 -30
- data/lib/morpheus/cli/commands/virtual_images.rb +1 -1
- data/lib/morpheus/cli/error_handler.rb +18 -3
- data/lib/morpheus/cli/mixins/accounts_helper.rb +2 -0
- 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 +104 -7
- 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
|
@@ -763,61 +763,49 @@ class Morpheus::Cli::PoliciesCommand
|
|
763
763
|
params = {}
|
764
764
|
options = {}
|
765
765
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
766
|
-
opts.banner = subcommand_usage()
|
767
|
-
|
766
|
+
opts.banner = subcommand_usage("[search]")
|
767
|
+
build_standard_list_options(opts, options, [], [:search])
|
768
|
+
opts.footer = <<-EOT
|
769
|
+
Get details about a policy type.
|
770
|
+
[policy-type] is required. This is Name or ID of a policy type.
|
771
|
+
EOT
|
768
772
|
opts.footer = "List policy types."
|
769
773
|
end
|
770
774
|
optparse.parse!(args)
|
771
|
-
|
772
|
-
if args.count
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
end
|
777
|
-
|
775
|
+
verify_args!(args:args, optparse:optparse, count:0)
|
776
|
+
# if args.count > 0
|
777
|
+
# options[:phrase] = args.join(" ")
|
778
|
+
# end
|
779
|
+
params.merge!(parse_list_options(options))
|
778
780
|
connect(options)
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
781
|
+
@policies_interface.setopts(options)
|
782
|
+
if options[:dry_run]
|
783
|
+
print_dry_run @policies_interface.dry.list_policy_types(params)
|
784
|
+
return 0
|
785
|
+
end
|
786
|
+
json_response = @policies_interface.list_policy_types(params)
|
787
|
+
render_response(json_response, options, 'policyTypes') do
|
786
788
|
policy_types = json_response['policyTypes']
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
puts records_as_csv(policy_types, options)
|
795
|
-
return 0
|
796
|
-
else
|
797
|
-
print_h1 "Morpheus Policy Types"
|
798
|
-
rows = policy_types.collect {|policy_type|
|
799
|
-
row = {
|
800
|
-
id: policy_type['id'],
|
801
|
-
name: policy_type['name'],
|
802
|
-
code: policy_type['code'],
|
803
|
-
description: policy_type['description']
|
804
|
-
}
|
805
|
-
row
|
789
|
+
print_h1 "Morpheus Policy Types"
|
790
|
+
rows = policy_types.collect {|policy_type|
|
791
|
+
row = {
|
792
|
+
id: policy_type['id'],
|
793
|
+
name: policy_type['name'],
|
794
|
+
code: policy_type['code'],
|
795
|
+
description: policy_type['description']
|
806
796
|
}
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
print as_pretty_table(rows, columns, options)
|
813
|
-
print_results_pagination(json_response, {:label => "policy type", :n_label => "policy types"})
|
814
|
-
print reset, "\n"
|
797
|
+
row
|
798
|
+
}
|
799
|
+
columns = [:id, :name]
|
800
|
+
if options[:include_fields]
|
801
|
+
columns = options[:include_fields]
|
815
802
|
end
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
803
|
+
print cyan
|
804
|
+
print as_pretty_table(rows, columns, options)
|
805
|
+
print_results_pagination(json_response)
|
806
|
+
print reset, "\n"
|
820
807
|
end
|
808
|
+
return 0
|
821
809
|
end
|
822
810
|
|
823
811
|
def get_type(args)
|
@@ -825,91 +813,54 @@ class Morpheus::Cli::PoliciesCommand
|
|
825
813
|
options = {}
|
826
814
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
827
815
|
opts.banner = subcommand_usage("[policy-type]")
|
828
|
-
|
829
|
-
opts.footer =
|
830
|
-
|
816
|
+
build_standard_get_options(opts, options)
|
817
|
+
opts.footer = <<-EOT
|
818
|
+
Get details about a policy type.
|
819
|
+
[policy-type] is required. This is Name or ID of a policy type.
|
820
|
+
EOT
|
831
821
|
end
|
832
822
|
optparse.parse!(args)
|
833
|
-
|
834
|
-
if args.count != 1
|
835
|
-
print_error Morpheus::Terminal.angry_prompt
|
836
|
-
puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
|
837
|
-
return 1
|
838
|
-
end
|
839
|
-
|
823
|
+
verify_args!(args:args, optparse:optparse, count: 1)
|
840
824
|
connect(options)
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
puts as_json(json_response)
|
852
|
-
else
|
853
|
-
print_h1 "Policy Type Details"
|
854
|
-
print cyan
|
855
|
-
description_cols = {
|
856
|
-
"ID" => 'id',
|
857
|
-
"Name" => 'name',
|
858
|
-
# "Description" => 'description',
|
859
|
-
"Code" => 'code',
|
860
|
-
"Category" => 'category',
|
861
|
-
# "Load Method" => 'loadMethod',
|
862
|
-
# "Enforce Method" => 'enforceMethod',
|
863
|
-
# "Prepare Method" => 'prepareMethod',
|
864
|
-
# "Validate Method" => 'validateMethod',
|
865
|
-
"Provision Enforced" => lambda {|it| it['enforceOnProvision'] ? 'Yes' : 'No' },
|
866
|
-
"Managed Enforced" => lambda {|it| it['enforceOnManaged'] ? 'Yes' : 'No' },
|
867
|
-
}
|
868
|
-
print_description_list(description_cols, policy_type)
|
869
|
-
print reset,"\n"
|
870
|
-
|
871
|
-
# show option types
|
872
|
-
print_h2 "Policy Type Options"
|
873
|
-
policy_type_option_types = policy_type['optionTypes']
|
874
|
-
if !policy_type_option_types || policy_type_option_types.size() == 0
|
875
|
-
puts "No options found for policy type"
|
876
|
-
else
|
877
|
-
rows = policy_type_option_types.collect {|option_type|
|
878
|
-
field_str = option_type['fieldName'].to_s
|
879
|
-
if !option_type['fieldContext'].to_s.empty?
|
880
|
-
field_str = option_type['fieldContext'] + "." + field_str
|
881
|
-
end
|
882
|
-
description_str = option_type['description'].to_s
|
883
|
-
if option_type['helpBlock']
|
884
|
-
if description_str.empty?
|
885
|
-
description_str = option_type['helpBlock']
|
886
|
-
else
|
887
|
-
description_str += " " + option_type['helpBlock']
|
888
|
-
end
|
889
|
-
end
|
890
|
-
row = {
|
891
|
-
#code: option_type['code'],
|
892
|
-
field: field_str,
|
893
|
-
type: option_type['type'],
|
894
|
-
description: description_str,
|
895
|
-
default: option_type['defaultValue'],
|
896
|
-
required: option_type['required'] ? 'Yes' : 'No'
|
897
|
-
}
|
898
|
-
row
|
899
|
-
}
|
900
|
-
columns = [:field, :type, :description, :default, :required]
|
901
|
-
print cyan
|
902
|
-
print as_pretty_table(rows, columns)
|
903
|
-
print reset,"\n"
|
904
|
-
end
|
905
|
-
return 0
|
906
|
-
end
|
825
|
+
params.merge!(parse_query_options(options))
|
826
|
+
policy_type_id = args[0]
|
827
|
+
if policy_type_id.to_s !~ /\A\d{1,}\Z/
|
828
|
+
policy_type = find_policy_type_by_name_or_id(args[0])
|
829
|
+
return [1, "Policy Type not found for #{args[0]}"] if policy_type.nil?
|
830
|
+
policy_type_id = policy_type['id']
|
831
|
+
end
|
832
|
+
@policies_interface.setopts(options)
|
833
|
+
if options[:dry_run]
|
834
|
+
print_dry_run @policies_interface.dry.get_policy_type(policy_type_id, params)
|
907
835
|
return 0
|
908
|
-
rescue RestClient::Exception => e
|
909
|
-
print_rest_exception(e, options)
|
910
|
-
return 1
|
911
836
|
end
|
912
|
-
@policies_interface.
|
837
|
+
json_response = @policies_interface.get_policy_type(policy_type_id, params)
|
838
|
+
render_response(json_response, options, 'policyType') do
|
839
|
+
policy_type = json_response['policyType']
|
840
|
+
print_h1 "Policy Type Details"
|
841
|
+
print cyan
|
842
|
+
description_cols = {
|
843
|
+
"ID" => 'id',
|
844
|
+
"Name" => 'name',
|
845
|
+
# "Description" => 'description',
|
846
|
+
"Code" => 'code',
|
847
|
+
"Category" => 'category',
|
848
|
+
# "Load Method" => 'loadMethod',
|
849
|
+
# "Enforce Method" => 'enforceMethod',
|
850
|
+
# "Prepare Method" => 'prepareMethod',
|
851
|
+
# "Validate Method" => 'validateMethod',
|
852
|
+
"Provision Enforced" => lambda {|it| it['enforceOnProvision'] ? 'Yes' : 'No' },
|
853
|
+
"Managed Enforced" => lambda {|it| it['enforceOnManaged'] ? 'Yes' : 'No' },
|
854
|
+
}
|
855
|
+
print_description_list(description_cols, policy_type)
|
856
|
+
print reset,"\n"
|
857
|
+
|
858
|
+
# show option types
|
859
|
+
print_h2 "Policy Type Options"
|
860
|
+
print format_option_types_table(policy_type['optionTypes'], options, 'policy')
|
861
|
+
print reset,"\n"
|
862
|
+
end
|
863
|
+
return 0
|
913
864
|
end
|
914
865
|
|
915
866
|
private
|
@@ -978,9 +929,42 @@ class Morpheus::Cli::PoliciesCommand
|
|
978
929
|
end
|
979
930
|
end
|
980
931
|
|
932
|
+
def find_policy_type_by_name_or_id(val)
|
933
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
934
|
+
return find_policy_type_by_id(val)
|
935
|
+
else
|
936
|
+
return find_policy_type_by_name(val)
|
937
|
+
end
|
938
|
+
end
|
939
|
+
|
940
|
+
def find_policy_type_by_name(name)
|
941
|
+
json_response = nil
|
942
|
+
|
943
|
+
# json_response = @policies_interface.list_policy_types({name: name.to_s})
|
944
|
+
json_response = @policies_interface.list_policy_types({max: 10000})
|
945
|
+
policy_types = json_response['policyTypes']
|
946
|
+
match_value = name.to_s.downcase
|
947
|
+
policy_types = policy_types.select {|it| it['name'].to_s.downcase == match_value || it['code'].to_s.downcase == match_value }
|
948
|
+
if policy_types.empty?
|
949
|
+
print_red_alert "Policy not found by name #{name}"
|
950
|
+
return nil
|
951
|
+
elsif policy_types.size > 1
|
952
|
+
print_red_alert "#{policy_types.size} policy types found by name or code #{name}"
|
953
|
+
# print_policies_table(policy_types, {color: red})
|
954
|
+
rows = policy_types.collect do |it|
|
955
|
+
{id: it['id'], name: it['name'], code: it['code']}
|
956
|
+
end
|
957
|
+
puts as_pretty_table(rows, [:id, :name], {color:red})
|
958
|
+
return nil
|
959
|
+
else
|
960
|
+
policy_type = policy_types[0]
|
961
|
+
return policy_type
|
962
|
+
end
|
963
|
+
end
|
964
|
+
|
981
965
|
def find_policy_type_by_id(id)
|
982
966
|
begin
|
983
|
-
json_response = @policies_interface.
|
967
|
+
json_response = @policies_interface.get_policy_type(id.to_s)
|
984
968
|
return json_response['policyType']
|
985
969
|
rescue RestClient::Exception => e
|
986
970
|
if e.response && e.response.code == 404
|
@@ -631,6 +631,8 @@ EOT
|
|
631
631
|
params['authority'] = v_prompt['authority']
|
632
632
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2}], options[:options])
|
633
633
|
params['description'] = v_prompt['description']
|
634
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'landingUrl', 'fieldLabel' => 'landingUrl', 'type' => 'text', 'displayOrder' => 3, 'description' => 'An optional override for the default landing page after login for a user.'}], options[:options])
|
635
|
+
params['landingUrl'] = v_prompt['landingUrl']
|
634
636
|
|
635
637
|
if params['owner']
|
636
638
|
if @is_master_account && has_complete_access
|
@@ -2479,6 +2481,7 @@ Update default workflow access for a role.
|
|
2479
2481
|
[
|
2480
2482
|
{'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
|
2481
2483
|
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
|
2484
|
+
{'fieldName' => 'landingUrl', 'fieldLabel' => 'Landing URL', 'type' => 'text', 'description' => 'An optional override for the default landing page after login for a user.'},
|
2482
2485
|
{'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user'},
|
2483
2486
|
{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text'},
|
2484
2487
|
{'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use'},
|
@@ -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
|
@@ -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"
|
@@ -131,6 +131,7 @@ module Morpheus::Cli::AccountsHelper
|
|
131
131
|
"ID" => 'id',
|
132
132
|
"Name" => 'authority',
|
133
133
|
"Description" => 'description',
|
134
|
+
"Landing URL" => 'landingUrl',
|
134
135
|
#"Scope" => lambda {|it| it['scope'] },
|
135
136
|
"Type" => lambda {|it| format_role_type(it) },
|
136
137
|
"Multitenant" => lambda {|it|
|
@@ -149,6 +150,7 @@ module Morpheus::Cli::AccountsHelper
|
|
149
150
|
"ID" => 'id',
|
150
151
|
"Name" => 'authority',
|
151
152
|
"Description" => 'description',
|
153
|
+
"Landing URL" => 'landingUrl',
|
152
154
|
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
153
155
|
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
154
156
|
}
|
@@ -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
|