morpheus-cli 5.2.4.1 → 5.3.1
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/README.md +1 -3
- data/lib/morpheus/api/api_client.rb +48 -14
- data/lib/morpheus/api/certificate_types_interface.rb +14 -0
- data/lib/morpheus/api/certificates_interface.rb +9 -0
- data/lib/morpheus/api/integration_types_interface.rb +14 -0
- data/lib/morpheus/api/integrations_interface.rb +7 -22
- data/lib/morpheus/api/network_services_interface.rb +14 -0
- data/lib/morpheus/api/read_interface.rb +23 -0
- data/lib/morpheus/api/rest_interface.rb +12 -10
- data/lib/morpheus/api/roles_interface.rb +7 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/user_settings_interface.rb +38 -18
- data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
- data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
- data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
- data/lib/morpheus/api/vdi_interface.rb +28 -0
- data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
- data/lib/morpheus/cli.rb +9 -2
- data/lib/morpheus/cli/activity_command.rb +7 -4
- data/lib/morpheus/cli/apps.rb +59 -75
- data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
- data/lib/morpheus/cli/certificates_command.rb +575 -0
- data/lib/morpheus/cli/cli_command.rb +61 -6
- data/lib/morpheus/cli/clouds.rb +1 -0
- data/lib/morpheus/cli/clusters.rb +5 -2
- data/lib/morpheus/cli/commands/standard/history_command.rb +4 -5
- data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
- data/lib/morpheus/cli/dashboard_command.rb +3 -3
- data/lib/morpheus/cli/execution_request_command.rb +15 -5
- data/lib/morpheus/cli/hosts.rb +245 -224
- data/lib/morpheus/cli/instances.rb +150 -167
- data/lib/morpheus/cli/integrations_command.rb +588 -41
- data/lib/morpheus/cli/invoices_command.rb +23 -46
- data/lib/morpheus/cli/login.rb +7 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
- data/lib/morpheus/cli/mixins/print_helper.rb +36 -18
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
- data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
- data/lib/morpheus/cli/network_domains_command.rb +2 -2
- data/lib/morpheus/cli/network_routers_command.rb +22 -9
- data/lib/morpheus/cli/networks_command.rb +2 -2
- data/lib/morpheus/cli/option_types.rb +34 -33
- data/lib/morpheus/cli/remote.rb +3 -2
- data/lib/morpheus/cli/reports_command.rb +5 -2
- data/lib/morpheus/cli/roles.rb +215 -55
- data/lib/morpheus/cli/service_plans_command.rb +4 -1
- data/lib/morpheus/cli/subnets_command.rb +11 -2
- data/lib/morpheus/cli/user_settings_command.rb +268 -57
- data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
- data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
- data/lib/morpheus/cli/vdi_command.rb +359 -0
- data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
- data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/rest_client.rb +30 -0
- data/lib/morpheus/terminal.rb +15 -7
- metadata +18 -2
@@ -181,7 +181,7 @@ class Morpheus::Cli::NetworkDomainsCommand
|
|
181
181
|
options['name'] = val
|
182
182
|
end
|
183
183
|
opts.on('--description VALUE', String, "Description for this network domain") do |val|
|
184
|
-
options['
|
184
|
+
options['description'] = val
|
185
185
|
end
|
186
186
|
opts.on('--public-zone [on|off]', String, "Public Zone") do |val|
|
187
187
|
options['publicZone'] = val.to_s == 'on' || val.to_s == 'true'
|
@@ -722,7 +722,7 @@ class Morpheus::Cli::NetworkDomainsCommand
|
|
722
722
|
payload['networkDomainRecord']['name'] = v_prompt['name'] unless v_prompt['name'].to_s.empty?
|
723
723
|
|
724
724
|
# Type
|
725
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => '
|
725
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'required' => true, 'optionSource' => 'dnsRecordType', 'description' => 'Type for this domain record.', 'defaultValue' => 'A'}], options[:options], @api_client)
|
726
726
|
payload['networkDomainRecord']['type'] = v_prompt['type'] unless v_prompt['type'].to_s.empty?
|
727
727
|
|
728
728
|
# Content
|
@@ -22,6 +22,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
22
22
|
def connect(opts)
|
23
23
|
@api_client = establish_remote_appliance_connection(opts)
|
24
24
|
@network_routers_interface = @api_client.network_routers
|
25
|
+
@network_services_interface = @api_client.network_services
|
25
26
|
@clouds_interface = @api_client.clouds
|
26
27
|
@options_interface = @api_client.options
|
27
28
|
@accounts_interface = @api_client.accounts
|
@@ -249,6 +250,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
249
250
|
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the network router. Default is on") do |val|
|
250
251
|
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
251
252
|
end
|
253
|
+
opts.on('--hostname VALUE', String, "Hostname for this network pool IP") do |val|
|
254
|
+
options[:options]['hostname'] = val
|
255
|
+
end
|
252
256
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
253
257
|
opts.footer = "Create a network router."
|
254
258
|
end
|
@@ -275,7 +279,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
275
279
|
group_options = available_groups
|
276
280
|
|
277
281
|
if options[:group]
|
278
|
-
group =
|
282
|
+
group = available_groups.find {|it| it['name'] == options[:group] || "#{it['value']}" == "#{options[:group]}".downcase}
|
279
283
|
|
280
284
|
if group.nil?
|
281
285
|
print_red_alert "Group #{options[:group]} not found"
|
@@ -292,10 +296,10 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
292
296
|
params = {'router' => {'site' => router['site']}, 'routerType' => {'id' => router_type['id']}}
|
293
297
|
|
294
298
|
if router_type['hasNetworkServer']
|
295
|
-
if options[:
|
296
|
-
server = find_network_server(options[:
|
299
|
+
if options[:network_server]
|
300
|
+
server = find_network_server(options[:network_server])
|
297
301
|
if server.nil?
|
298
|
-
print_red_alert "Network server #{options[:
|
302
|
+
print_red_alert "Network server #{options[:network_server]} not found"
|
299
303
|
exit 1
|
300
304
|
end
|
301
305
|
else
|
@@ -322,7 +326,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
322
326
|
# prompt for enabled
|
323
327
|
router['enabled'] = options[:enabled].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enable Router.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on' : options[:enabled]
|
324
328
|
|
325
|
-
option_types = router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
329
|
+
option_types = router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName']) || it['showOnCreate'] === false}.sort {|it| it['displayOrder']}
|
326
330
|
|
327
331
|
# prompt options
|
328
332
|
option_opts = options[:options].deep_merge!({'config' => options[:options].clone})
|
@@ -570,7 +574,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
570
574
|
api_params = {}
|
571
575
|
api_params['networkServerId'] = router['networkServer']['id'] if router['networkServer']
|
572
576
|
api_params['zoneId'] = router['zone']['id'] if router['networkServer'].nil?
|
573
|
-
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'
|
577
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'rule' => ''}}), @api_client, api_params, nil, true)
|
574
578
|
payload = {'rule' => params.deep_merge(option_result)}
|
575
579
|
end
|
576
580
|
|
@@ -792,6 +796,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
792
796
|
opts.on('--mtu VALUE', String, "MTU for this route") do |val|
|
793
797
|
params['networkMtu'] = val
|
794
798
|
end
|
799
|
+
opts.on('--priority VALUE', Integer, "Priority for this route") do |val|
|
800
|
+
params['priority'] = val
|
801
|
+
end
|
795
802
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
796
803
|
opts.footer = "Create a network router route."
|
797
804
|
end
|
@@ -821,17 +828,18 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
821
828
|
payload = options[:payload]
|
822
829
|
else
|
823
830
|
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Name', 'required' => true}], options[:options], @api_client, params)['name']
|
824
|
-
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' =>
|
831
|
+
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => false}], options[:options], @api_client, params)['description']
|
825
832
|
|
826
833
|
# prompt for enabled if not set
|
827
834
|
params['enabled'] = options[:enabled].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enabling Route.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on' : options[:enabled]
|
828
835
|
|
829
|
-
# default
|
836
|
+
# default route
|
830
837
|
params['defaultRoute'] = options[:defaultRoute].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultRoute', 'fieldLabel' => 'Default Route', 'type' => 'checkbox', 'description' => 'Default Route.', 'defaultValue' => false, 'required' => false}], options, @api_client, {})['defaultRoute'] == 'on' : options[:defaultRoute]
|
831
838
|
|
832
839
|
params['source'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'type' => 'text', 'fieldLabel' => 'Network', 'required' => true}], options[:options], @api_client, params)['source']
|
833
840
|
params['destination'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'destination', 'type' => 'text', 'fieldLabel' => 'Next Hop', 'required' => true}], options[:options], @api_client, params)['destination']
|
834
|
-
params['networkMtu'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkMtu', 'type' => 'text', 'fieldLabel' => 'MTU', 'required' =>
|
841
|
+
params['networkMtu'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkMtu', 'type' => 'text', 'fieldLabel' => 'MTU', 'required' => false}], options[:options], @api_client, params)['networkMtu']
|
842
|
+
params['priority'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priority', 'type' => 'number', 'fieldLabel' => 'Priority', 'required' => false}], options[:options], @api_client, params)['priority']
|
835
843
|
|
836
844
|
payload = {'route' => params}
|
837
845
|
end
|
@@ -1278,4 +1286,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1278
1286
|
def available_groups()
|
1279
1287
|
@network_routers_interface.groups
|
1280
1288
|
end
|
1289
|
+
|
1290
|
+
def find_network_server(val)
|
1291
|
+
services = @network_services_interface.list()['networkServices']
|
1292
|
+
(val.to_s =~ /\A\d{1,}\Z/) ? services.find {|it| it['id'].to_i == val.to_i} : services.find {|it| it['name'] == val}
|
1293
|
+
end
|
1281
1294
|
end
|
@@ -521,10 +521,10 @@ class Morpheus::Cli::NetworksCommand
|
|
521
521
|
if options['cidr']
|
522
522
|
payload['network']['cidr'] = options['cidr']
|
523
523
|
else
|
524
|
-
|
524
|
+
if network_type['cidrEditable']
|
525
525
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cidr', 'fieldLabel' => 'CIDR', 'type' => 'text', 'required' => network_type['cidrRequired'], 'description' => ''}], options)
|
526
526
|
payload['network']['cidr'] = v_prompt['cidr']
|
527
|
-
|
527
|
+
end
|
528
528
|
end
|
529
529
|
|
530
530
|
# Gateway
|
@@ -48,13 +48,23 @@ module Morpheus
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
# puts "Options Prompt #{options}"
|
51
|
-
#
|
52
|
-
|
53
|
-
|
51
|
+
# Sort options by default, group, advanced
|
52
|
+
cur_field_group = 'default'
|
53
|
+
(
|
54
|
+
option_types.reject {|it| (it['fieldGroup'] || 'default') != 'default'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i} +
|
55
|
+
option_types.reject {|it| ['default', 'advanced'].include?(it['fieldGroup'] || 'default')}.sort{|a,b| a['displayOrder'] <=> b['displayOrder']}.group_by{|it| it['fieldGroup']}.values.collect { |it| it.sort{|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}}.flatten +
|
56
|
+
option_types.reject {|it| it['fieldGroup'] != 'advanced'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}
|
57
|
+
).each do |option_type|
|
54
58
|
context_map = results
|
55
59
|
value = nil
|
56
60
|
value_found=false
|
57
61
|
|
62
|
+
if cur_field_group != (option_type['fieldGroup'] || 'default')
|
63
|
+
cur_field_group = option_type['fieldGroup']
|
64
|
+
cur_field_group = cur_field_group.to_s.sub(/options\Z/i, "").strip # avoid "ADVANCED OPTION OPTIONS"
|
65
|
+
print "\n#{cur_field_group.upcase} OPTIONS\n#{"=" * ("#{cur_field_group} OPTIONS".length)}\n\n"
|
66
|
+
end
|
67
|
+
|
58
68
|
# How about this instead?
|
59
69
|
# option_type = option_type.clone
|
60
70
|
# field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
@@ -78,6 +88,7 @@ module Morpheus
|
|
78
88
|
if !option_type['visibleOnCode'].to_s.empty?
|
79
89
|
visible_option_check_value = option_type['visibleOnCode']
|
80
90
|
end
|
91
|
+
|
81
92
|
if !visible_option_check_value.to_s.empty?
|
82
93
|
# support formats code=value or code:value OR code:(value|value2|value3)
|
83
94
|
# OR fieldContext.fieldName=value
|
@@ -101,8 +112,9 @@ module Morpheus
|
|
101
112
|
end
|
102
113
|
if depends_on_option_type
|
103
114
|
# dependent option type has a different value
|
104
|
-
depends_on_field_key = depends_on_option_type['fieldContext']
|
115
|
+
depends_on_field_key = depends_on_option_type['fieldContext'].nil? || depends_on_option_type['fieldContext'].empty? ? "#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}"
|
105
116
|
found_dep_value = get_object_value(results, depends_on_field_key) || get_object_value(options, depends_on_field_key)
|
117
|
+
|
106
118
|
if depends_on_values.size > 0
|
107
119
|
# must be in the specified values
|
108
120
|
# todo: uhh this actually needs to change to parse regex
|
@@ -139,7 +151,9 @@ module Morpheus
|
|
139
151
|
value = cur_namespace[field_name]
|
140
152
|
input_value = ['select', 'multiSelect','typeahead', 'multiTypeahead'].include?(option_type['type']) && option_type['fieldInput'] ? cur_namespace[option_type['fieldInput']] : nil
|
141
153
|
if option_type['type'] == 'number'
|
142
|
-
|
154
|
+
if !value.to_s.empty?
|
155
|
+
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
156
|
+
end
|
143
157
|
# these select prompts should just fall down through below, with the extra params no_prompt, use_value
|
144
158
|
elsif option_type['type'] == 'select'
|
145
159
|
value = select_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
@@ -273,22 +287,6 @@ module Morpheus
|
|
273
287
|
results
|
274
288
|
end
|
275
289
|
|
276
|
-
def self.grails_params(data, context=nil)
|
277
|
-
params = {}
|
278
|
-
data.each do |k,v|
|
279
|
-
if v.is_a?(Hash)
|
280
|
-
params.merge!(grails_params(v, context ? "#{context}.#{k.to_s}" : k))
|
281
|
-
else
|
282
|
-
if context
|
283
|
-
params["#{context}.#{k.to_s}"] = v
|
284
|
-
else
|
285
|
-
params[k.to_s] = v
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
return params
|
290
|
-
end
|
291
|
-
|
292
290
|
def self.radio_prompt(option_type)
|
293
291
|
value_found = false
|
294
292
|
value = nil
|
@@ -330,7 +328,9 @@ module Morpheus
|
|
330
328
|
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
331
329
|
input = $stdin.gets.chomp!
|
332
330
|
value = input.empty? ? option_type['defaultValue'] : input
|
333
|
-
|
331
|
+
if !value.to_s.empty?
|
332
|
+
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
333
|
+
end
|
334
334
|
if input == '?'
|
335
335
|
help_prompt(option_type)
|
336
336
|
elsif !value.nil? || option_type['required'] != true
|
@@ -363,7 +363,7 @@ module Morpheus
|
|
363
363
|
if option_type['selectOptions']
|
364
364
|
# calculate from inline lambda
|
365
365
|
if option_type['selectOptions'].is_a?(Proc)
|
366
|
-
select_options = option_type['selectOptions'].call(api_client,
|
366
|
+
select_options = option_type['selectOptions'].call(api_client, api_params || {})
|
367
367
|
else
|
368
368
|
# todo: better type validation
|
369
369
|
select_options = option_type['selectOptions']
|
@@ -371,13 +371,13 @@ module Morpheus
|
|
371
371
|
elsif option_type['optionSource']
|
372
372
|
# calculate from inline lambda
|
373
373
|
if option_type['optionSource'].is_a?(Proc)
|
374
|
-
select_options = option_type['optionSource'].call(api_client,
|
374
|
+
select_options = option_type['optionSource'].call(api_client, api_params || {})
|
375
375
|
elsif option_type['optionSource'] == 'list'
|
376
376
|
# /api/options/list is a special action for custom OptionTypeLists, just need to pass the optionTypeId parameter
|
377
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
377
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {}.merge({'optionTypeId' => option_type['id']}))
|
378
378
|
else
|
379
379
|
# remote optionSource aka /api/options/$optionSource?
|
380
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
380
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {})
|
381
381
|
end
|
382
382
|
else
|
383
383
|
raise "option '#{field_key}' is type: 'select' and missing selectOptions or optionSource!"
|
@@ -571,6 +571,7 @@ module Morpheus
|
|
571
571
|
# looking for help with this input
|
572
572
|
if input == '?'
|
573
573
|
help_prompt(option_type)
|
574
|
+
select_options = load_options(option_type, api_client, api_params)
|
574
575
|
display_select_options(option_type, select_options) unless select_options.empty?
|
575
576
|
next
|
576
577
|
end
|
@@ -888,7 +889,7 @@ module Morpheus
|
|
888
889
|
if option_type['selectOptions']
|
889
890
|
# calculate from inline lambda
|
890
891
|
if option_type['selectOptions'].is_a?(Proc)
|
891
|
-
select_options = option_type['selectOptions'].call(api_client,
|
892
|
+
select_options = option_type['selectOptions'].call(api_client, api_params || {})
|
892
893
|
else
|
893
894
|
select_options = option_type['selectOptions']
|
894
895
|
end
|
@@ -903,13 +904,13 @@ module Morpheus
|
|
903
904
|
elsif option_type['optionSource']
|
904
905
|
# calculate from inline lambda
|
905
906
|
if option_type['optionSource'].is_a?(Proc)
|
906
|
-
select_options = option_type['optionSource'].call(api_client,
|
907
|
+
select_options = option_type['optionSource'].call(api_client, api_params || {})
|
907
908
|
elsif option_type['optionSource'] == 'list'
|
908
909
|
# /api/options/list is a special action for custom OptionTypeLists, just need to pass the optionTypeId parameter
|
909
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
910
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {}.merge({'optionTypeId' => option_type['id']}))
|
910
911
|
else
|
911
912
|
# remote optionSource aka /api/options/$optionSource?
|
912
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
913
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {})
|
913
914
|
end
|
914
915
|
else
|
915
916
|
raise "option '#{field_key}' is type: 'typeahead' and missing selectOptions or optionSource!"
|
@@ -935,8 +936,8 @@ module Morpheus
|
|
935
936
|
end
|
936
937
|
|
937
938
|
|
938
|
-
def self.load_source_options(source,api_client,params)
|
939
|
-
api_client.options.options_for_source(source,params)['data']
|
939
|
+
def self.load_source_options(source,sourceType,api_client,params)
|
940
|
+
api_client.options.options_for_source("#{sourceType ? "#{sourceType}/" : ''}#{source}",params)['data']
|
940
941
|
end
|
941
942
|
|
942
943
|
def self.format_select_options_help(opt, select_options = [], paging = nil)
|
@@ -951,7 +952,7 @@ module Morpheus
|
|
951
952
|
out = ""
|
952
953
|
out << "\n"
|
953
954
|
out << "#{header}\n"
|
954
|
-
out << "
|
955
|
+
out << "#{'=' * header.length}\n"
|
955
956
|
select_options.each do |option|
|
956
957
|
out << " * #{option['name']} [#{option['value']}]\n"
|
957
958
|
end
|
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -1276,7 +1276,8 @@ EOT
|
|
1276
1276
|
|
1277
1277
|
def format_remote_details(appliance, options={})
|
1278
1278
|
columns = {
|
1279
|
-
"Name" => :name,
|
1279
|
+
#"Name" => :name,
|
1280
|
+
"Name" => lambda {|it| it[:name].to_s },
|
1280
1281
|
#"Name" => lambda {|it| it[:active] ? "#{it[:name]} #{bold}(current)#{reset}#{cyan}" : it[:name] },
|
1281
1282
|
"URL" => lambda {|it| it[:url] || it[:host] },
|
1282
1283
|
#"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
@@ -1336,7 +1337,7 @@ EOT
|
|
1336
1337
|
include Term::ANSIColor
|
1337
1338
|
|
1338
1339
|
# for caching the the contents of YAML file $home/appliances
|
1339
|
-
# it is structured like :appliance_name => {:host => "
|
1340
|
+
# it is structured like :appliance_name => {:host => "https://api.gomorpheus.com", :active => true}
|
1340
1341
|
# not named @@appliances to avoid confusion with the instance variable . This is also a command class...
|
1341
1342
|
@@appliance_config = nil
|
1342
1343
|
|
@@ -346,7 +346,7 @@ class Morpheus::Cli::ReportsCommand
|
|
346
346
|
report_result = find_report_result_by_id(args[0])
|
347
347
|
return 1 if report_result.nil?
|
348
348
|
|
349
|
-
link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/operations/reports/#{report_result['type']['code']}/
|
349
|
+
link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/operations/reports/#{report_result['type']['code']}/results/#{report_result['id']}%3Fcontext=results"
|
350
350
|
|
351
351
|
if options[:dry_run]
|
352
352
|
puts Morpheus::Util.open_url_command(link)
|
@@ -368,7 +368,6 @@ class Morpheus::Cli::ReportsCommand
|
|
368
368
|
do_mkdir = false
|
369
369
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
370
370
|
opts.banner = subcommand_usage("[id] [file]")
|
371
|
-
build_common_options(opts, options, [:dry_run, :remote])
|
372
371
|
opts.on( '--format VALUE', String, "Report Format for exported file, json or csv. Default is json." ) do |val|
|
373
372
|
report_format = val
|
374
373
|
end
|
@@ -379,6 +378,7 @@ class Morpheus::Cli::ReportsCommand
|
|
379
378
|
opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
|
380
379
|
do_mkdir = true
|
381
380
|
end
|
381
|
+
build_common_options(opts, options, [:dry_run, :remote])
|
382
382
|
opts.footer = "Export a report result as json or csv." + "\n" +
|
383
383
|
"[id] is required. This is id of the report result." + "\n" +
|
384
384
|
"[file] is required. This is local destination for the downloaded file."
|
@@ -394,6 +394,9 @@ class Morpheus::Cli::ReportsCommand
|
|
394
394
|
|
395
395
|
outfile = args[1]
|
396
396
|
outfile = File.expand_path(outfile)
|
397
|
+
if outfile =~ /\.csv\Z/i
|
398
|
+
report_format = "csv"
|
399
|
+
end
|
397
400
|
|
398
401
|
if Dir.exists?(outfile)
|
399
402
|
print_red_alert "[file] is invalid. It is the name of an existing directory: #{outfile}"
|
data/lib/morpheus/cli/roles.rb
CHANGED
@@ -13,7 +13,7 @@ class Morpheus::Cli::Roles
|
|
13
13
|
include Morpheus::Cli::AccountsHelper
|
14
14
|
include Morpheus::Cli::ProvisioningHelper
|
15
15
|
include Morpheus::Cli::WhoamiHelper
|
16
|
-
register_subcommands :list, :get, :add, :update, :remove, :'list-permissions', :'update-feature-access', :'update-global-group-access', :'update-group-access', :'update-global-cloud-access', :'update-cloud-access', :'update-global-instance-type-access', :'update-instance-type-access', :'update-global-blueprint-access', :'update-blueprint-access', :'update-global-catalog-item-type-access', :'update-catalog-item-type-access', :'update-persona-access'
|
16
|
+
register_subcommands :list, :get, :add, :update, :remove, :'list-permissions', :'update-feature-access', :'update-global-group-access', :'update-group-access', :'update-global-cloud-access', :'update-cloud-access', :'update-global-instance-type-access', :'update-instance-type-access', :'update-global-blueprint-access', :'update-blueprint-access', :'update-global-catalog-item-type-access', :'update-catalog-item-type-access', :'update-persona-access', :'update-global-vdi-pool-access', :'update-vdi-pool-access'
|
17
17
|
alias_subcommand :details, :get
|
18
18
|
set_default_subcommand :list
|
19
19
|
|
@@ -102,19 +102,23 @@ class Morpheus::Cli::Roles
|
|
102
102
|
options[:include_blueprint_access] = true
|
103
103
|
end
|
104
104
|
opts.on(nil,'--catalog-item-type-access', "Display Catalog Item Type Access") do
|
105
|
-
options[:
|
105
|
+
options[:include_catalog_item_type_access] = true
|
106
106
|
end
|
107
107
|
opts.on(nil,'--personas', "Display Persona Access") do
|
108
108
|
options[:include_personas_access] = true
|
109
109
|
end
|
110
|
+
opts.on(nil,'--vdi-pool-access', "Display VDI Pool Access") do
|
111
|
+
options[:include_vdi_pool_access] = true
|
112
|
+
end
|
110
113
|
opts.on('-a','--all', "Display All Access Lists") do
|
111
114
|
options[:include_feature_access] = true
|
112
115
|
options[:include_group_access] = true
|
113
116
|
options[:include_cloud_access] = true
|
114
117
|
options[:include_instance_type_access] = true
|
115
118
|
options[:include_blueprint_access] = true
|
116
|
-
options[:
|
119
|
+
options[:include_catalog_item_type_access] = true
|
117
120
|
options[:include_personas_access] = true
|
121
|
+
options[:include_vdi_pool_access] = true
|
118
122
|
end
|
119
123
|
build_standard_get_options(opts, options)
|
120
124
|
opts.footer = <<-EOT
|
@@ -206,9 +210,9 @@ EOT
|
|
206
210
|
rows = rows.select {|row| row[:code].to_s =~ phrase_regexp || row[:name].to_s =~ phrase_regexp }
|
207
211
|
end
|
208
212
|
print as_pretty_table(rows, [:code, :name, :access], options)
|
209
|
-
print reset,"\n"
|
213
|
+
# print reset,"\n"
|
210
214
|
else
|
211
|
-
print cyan,"Use --permissions to list permissions","\n"
|
215
|
+
print cyan,"Use --permissions to list feature permissions","\n"
|
212
216
|
end
|
213
217
|
|
214
218
|
has_group_access = true
|
@@ -220,6 +224,7 @@ EOT
|
|
220
224
|
"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) },
|
221
225
|
"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) },
|
222
226
|
"Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) },
|
227
|
+
"VDI Pools" => lambda {|it| get_access_string(it['globalVdiPoolAccess']) },
|
223
228
|
}
|
224
229
|
if role['roleType'].to_s.downcase == 'account'
|
225
230
|
global_access_columns.delete("Groups")
|
@@ -228,7 +233,7 @@ EOT
|
|
228
233
|
global_access_columns.delete("Clouds")
|
229
234
|
has_cloud_access = false
|
230
235
|
end
|
231
|
-
|
236
|
+
print as_pretty_table([json_response], global_access_columns, options)
|
232
237
|
|
233
238
|
if has_group_access
|
234
239
|
#print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
|
@@ -246,7 +251,7 @@ EOT
|
|
246
251
|
else
|
247
252
|
print cyan,"Use -g, --group-access to list custom access","\n"
|
248
253
|
end
|
249
|
-
print reset,"\n"
|
254
|
+
# print reset,"\n"
|
250
255
|
else
|
251
256
|
# print "\n"
|
252
257
|
# print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
|
@@ -270,7 +275,7 @@ EOT
|
|
270
275
|
else
|
271
276
|
print cyan,"Use -c, --cloud-access to list custom access","\n"
|
272
277
|
end
|
273
|
-
print reset,"\n"
|
278
|
+
# print reset,"\n"
|
274
279
|
else
|
275
280
|
# print "\n"
|
276
281
|
# print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
|
@@ -293,7 +298,7 @@ EOT
|
|
293
298
|
else
|
294
299
|
print cyan,"Use -i, --instance-type-access to list custom access","\n"
|
295
300
|
end
|
296
|
-
print reset,"\n"
|
301
|
+
# print reset,"\n"
|
297
302
|
else
|
298
303
|
# print "\n"
|
299
304
|
# print cyan,bold,"Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}",reset,"\n"
|
@@ -317,7 +322,7 @@ EOT
|
|
317
322
|
else
|
318
323
|
print cyan,"Use -b, --blueprint-access to list custom access","\n"
|
319
324
|
end
|
320
|
-
print reset,"\n"
|
325
|
+
# print reset,"\n"
|
321
326
|
else
|
322
327
|
# print "\n"
|
323
328
|
# print cyan,bold,"Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}",reset,"\n"
|
@@ -331,7 +336,7 @@ EOT
|
|
331
336
|
# print "\n"
|
332
337
|
if catalog_item_type_global_access == 'custom'
|
333
338
|
print_h2 "Catalog Item Type Access", options
|
334
|
-
if options[:
|
339
|
+
if options[:include_catalog_item_type_access]
|
335
340
|
rows = catalog_item_type_permissions.collect do |it|
|
336
341
|
{
|
337
342
|
name: it['name'],
|
@@ -350,6 +355,7 @@ EOT
|
|
350
355
|
|
351
356
|
persona_permissions = json_response['personaPermissions'] || json_response['personas'] || []
|
352
357
|
# if options[:include_personas_access]
|
358
|
+
print cyan
|
353
359
|
if persona_permissions
|
354
360
|
print_h2 "Persona Access", options
|
355
361
|
rows = persona_permissions.collect do |it|
|
@@ -358,13 +364,34 @@ EOT
|
|
358
364
|
access: format_access_string(it['access'], ["none","read","full"]),
|
359
365
|
}
|
360
366
|
end
|
361
|
-
print as_pretty_table(rows, [:name, :access], options)
|
362
|
-
print reset,"\n"
|
367
|
+
print as_pretty_table(rows, [:name, :access], options)
|
363
368
|
end
|
364
369
|
|
365
370
|
# print reset,"\n"
|
366
371
|
|
372
|
+
vdi_pool_global_access = json_response['globalVdiPoolAccess']
|
373
|
+
vdi_pool_permissions = json_response['vdiPoolPermissions'] || []
|
374
|
+
print cyan
|
375
|
+
if vdi_pool_global_access == 'custom'
|
376
|
+
print_h2 "VDI Pool Access", options
|
377
|
+
if options[:include_vdi_pool_access]
|
378
|
+
rows = vdi_pool_permissions.collect do |it|
|
379
|
+
{
|
380
|
+
name: it['name'],
|
381
|
+
access: format_access_string(it['access'], ["none","read","full"]),
|
382
|
+
}
|
383
|
+
end
|
384
|
+
print as_pretty_table(rows, [:name, :access], options)
|
385
|
+
else
|
386
|
+
print cyan,"Use --vdi-pool-access to list custom access","\n"
|
387
|
+
end
|
388
|
+
else
|
389
|
+
# print "\n"
|
390
|
+
# print cyan,bold,"VDI Pool Access: #{get_access_string(json_response['globalVdiPoolAccess'])}",reset,"\n"
|
391
|
+
end
|
392
|
+
|
367
393
|
end
|
394
|
+
print reset,"\n"
|
368
395
|
|
369
396
|
return 0, nil
|
370
397
|
end
|
@@ -520,7 +547,7 @@ EOT
|
|
520
547
|
end
|
521
548
|
|
522
549
|
# v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'optionSource' => 'personas', 'description' => 'Default Persona'}], options[:options], @api_client)
|
523
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' =>
|
550
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' => get_persona_select_options(), 'description' => 'Default Persona'}], options[:options], @api_client)
|
524
551
|
role_payload['defaultPersona'] = {'code' => v_prompt['defaultPersona']} unless v_prompt['defaultPersona'].to_s.strip.empty?
|
525
552
|
|
526
553
|
payload = {"role" => role_payload}
|
@@ -782,14 +809,14 @@ EOT
|
|
782
809
|
def update_group_access(args)
|
783
810
|
options = {}
|
784
811
|
name = nil
|
785
|
-
|
812
|
+
group_id = nil
|
786
813
|
access_value = nil
|
787
814
|
do_all = false
|
788
815
|
allowed_access_values = ['full', 'read', 'none']
|
789
816
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
790
817
|
opts.banner = subcommand_usage("[role] [group] [access]")
|
791
818
|
opts.on( '-g', '--group GROUP', "Group name or id" ) do |val|
|
792
|
-
|
819
|
+
group_id = val
|
793
820
|
end
|
794
821
|
opts.on( nil, '--all', "Update all groups at once." ) do
|
795
822
|
do_all = true
|
@@ -845,9 +872,8 @@ EOT
|
|
845
872
|
end
|
846
873
|
|
847
874
|
group = nil
|
848
|
-
group_id = nil
|
849
875
|
if !do_all
|
850
|
-
group = find_group_by_name_or_id_for_provisioning(
|
876
|
+
group = find_group_by_name_or_id_for_provisioning(group_id)
|
851
877
|
return 1 if group.nil?
|
852
878
|
group_id = group['id']
|
853
879
|
end
|
@@ -932,15 +958,14 @@ EOT
|
|
932
958
|
|
933
959
|
def update_cloud_access(args)
|
934
960
|
options = {}
|
935
|
-
|
961
|
+
cloud_id = nil
|
936
962
|
access_value = nil
|
937
963
|
do_all = false
|
938
964
|
allowed_access_values = ['full', 'read', 'none']
|
939
965
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
940
966
|
opts.banner = subcommand_usage("[name]")
|
941
967
|
opts.on( '-c', '--cloud CLOUD', "Cloud name or id" ) do |val|
|
942
|
-
|
943
|
-
cloud_name = val
|
968
|
+
cloud_id = val
|
944
969
|
end
|
945
970
|
opts.on( nil, '--all', "Update all clouds at once." ) do
|
946
971
|
do_all = true
|
@@ -948,9 +973,6 @@ EOT
|
|
948
973
|
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
949
974
|
access_value = val
|
950
975
|
end
|
951
|
-
opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
|
952
|
-
options[:group] = val
|
953
|
-
end
|
954
976
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
955
977
|
opts.footer = "Update role access for a cloud or all clouds.\n" +
|
956
978
|
"[role] is required. This is the name or id of a role.\n" +
|
@@ -998,23 +1020,11 @@ EOT
|
|
998
1020
|
exit 1
|
999
1021
|
end
|
1000
1022
|
|
1001
|
-
|
1002
|
-
group_id = nil
|
1003
|
-
cloud_id = nil
|
1023
|
+
cloud = nil
|
1004
1024
|
if !do_all
|
1005
|
-
|
1006
|
-
if
|
1007
|
-
|
1008
|
-
group_id = group['id']
|
1009
|
-
else
|
1010
|
-
group_id = @active_group_id
|
1011
|
-
end
|
1012
|
-
if group_id.nil?
|
1013
|
-
print_red_alert "Group not found or specified!"
|
1014
|
-
return 1
|
1015
|
-
end
|
1016
|
-
cloud_id = find_cloud_id_by_name(group_id, cloud_name)
|
1017
|
-
return 1 if cloud_id.nil?
|
1025
|
+
cloud = find_cloud_by_name_or_id_for_provisioning(nil, cloud_id)
|
1026
|
+
return 1 if cloud.nil?
|
1027
|
+
cloud_id = cloud['id']
|
1018
1028
|
end
|
1019
1029
|
params = {}
|
1020
1030
|
if do_all
|
@@ -1037,7 +1047,7 @@ EOT
|
|
1037
1047
|
if do_all
|
1038
1048
|
print_green_success "Role #{role['authority']} access updated for all clouds"
|
1039
1049
|
else
|
1040
|
-
print_green_success "Role #{role['authority']} access updated for cloud
|
1050
|
+
print_green_success "Role #{role['authority']} access updated for cloud #{cloud['name']}"
|
1041
1051
|
end
|
1042
1052
|
end
|
1043
1053
|
return 0
|
@@ -1534,7 +1544,7 @@ EOT
|
|
1534
1544
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1535
1545
|
opts.footer = "Update role access for a persona or all personas.\n" +
|
1536
1546
|
"[role] is required. This is the name or id of a role.\n" +
|
1537
|
-
"--persona or --all is required. This is the code of a persona. Service Catalog or
|
1547
|
+
"--persona or --all is required. This is the code of a persona. Service Catalog, Standard, or Virtual Desktop\n" +
|
1538
1548
|
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
1539
1549
|
end
|
1540
1550
|
optparse.parse!(args)
|
@@ -1606,6 +1616,160 @@ EOT
|
|
1606
1616
|
end
|
1607
1617
|
end
|
1608
1618
|
|
1619
|
+
def update_global_vdi_pool_access(args)
|
1620
|
+
usage = "Usage: morpheus roles update-global-vdi-pool-access [role] [full|custom|none]"
|
1621
|
+
options = {}
|
1622
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1623
|
+
opts.banner = subcommand_usage("[role] [full|custom|none]")
|
1624
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1625
|
+
end
|
1626
|
+
optparse.parse!(args)
|
1627
|
+
verify_args!(args:args, optparse:optparse, count: 2)
|
1628
|
+
name = args[0]
|
1629
|
+
access_value = args[1].to_s.downcase
|
1630
|
+
if !['full', 'custom', 'none'].include?(access_value)
|
1631
|
+
raise_command_error("invalid access value: #{args[1]}", optparse)
|
1632
|
+
end
|
1633
|
+
|
1634
|
+
|
1635
|
+
connect(options)
|
1636
|
+
begin
|
1637
|
+
account = find_account_from_options(options)
|
1638
|
+
account_id = account ? account['id'] : nil
|
1639
|
+
role = find_role_by_name_or_id(account_id, name)
|
1640
|
+
exit 1 if role.nil?
|
1641
|
+
# note: VdiPools being plural is odd, the others are singular
|
1642
|
+
params = {permissionCode: 'VdiPools', access: access_value}
|
1643
|
+
@roles_interface.setopts(options)
|
1644
|
+
if options[:dry_run]
|
1645
|
+
print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
|
1646
|
+
return
|
1647
|
+
end
|
1648
|
+
json_response = @roles_interface.update_permission(account_id, role['id'], params)
|
1649
|
+
|
1650
|
+
if options[:json]
|
1651
|
+
print JSON.pretty_generate(json_response)
|
1652
|
+
print "\n"
|
1653
|
+
else
|
1654
|
+
print_green_success "Role #{role['authority']} global vdi pool access updated"
|
1655
|
+
end
|
1656
|
+
rescue RestClient::Exception => e
|
1657
|
+
print_rest_exception(e, options)
|
1658
|
+
exit 1
|
1659
|
+
end
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
def update_vdi_pool_access(args)
|
1663
|
+
options = {}
|
1664
|
+
vdi_pool_id = nil
|
1665
|
+
access_value = nil
|
1666
|
+
do_all = false
|
1667
|
+
allowed_access_values = ['full', 'none']
|
1668
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1669
|
+
opts.banner = subcommand_usage("[role] [vdi-pool] [access]")
|
1670
|
+
opts.on( '--vdi-pool ID', String, "VDI Pool ID or Name" ) do |val|
|
1671
|
+
vdi_pool_id = val
|
1672
|
+
end
|
1673
|
+
opts.on( nil, '--all', "Update all VDI pools at once." ) do
|
1674
|
+
do_all = true
|
1675
|
+
end
|
1676
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
1677
|
+
access_value = val
|
1678
|
+
end
|
1679
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1680
|
+
opts.footer = "Update role access for a VDI pool or all VDI pools.\n" +
|
1681
|
+
"[role] is required. This is the name or id of a role.\n" +
|
1682
|
+
"--vdi-pool or --all is required. This is the name or id of a VDI pool.\n" +
|
1683
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
1684
|
+
end
|
1685
|
+
optparse.parse!(args)
|
1686
|
+
|
1687
|
+
# usage: update-vdi-pool-access [role] [access] --all
|
1688
|
+
# update-vdi-pool-access [role] [vdi-pool] [access]
|
1689
|
+
name = args[0]
|
1690
|
+
if do_all
|
1691
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
1692
|
+
access_value = args[1] if args[1]
|
1693
|
+
else
|
1694
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
1695
|
+
vdi_pool_id = args[1] if args[1]
|
1696
|
+
access_value = args[2] if args[2]
|
1697
|
+
end
|
1698
|
+
if !vdi_pool_id && !do_all
|
1699
|
+
raise_command_error("missing required argument: [vdi-pool] or --all", optparse)
|
1700
|
+
end
|
1701
|
+
if !access_value
|
1702
|
+
raise_command_error("missing required argument: [access]", optparse)
|
1703
|
+
end
|
1704
|
+
access_value = access_value.to_s.downcase
|
1705
|
+
if !allowed_access_values.include?(access_value)
|
1706
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
1707
|
+
puts optparse
|
1708
|
+
return 1
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
connect(options)
|
1712
|
+
begin
|
1713
|
+
account = find_account_from_options(options)
|
1714
|
+
account_id = account ? account['id'] : nil
|
1715
|
+
role = find_role_by_name_or_id(account_id, name)
|
1716
|
+
return 1 if role.nil?
|
1717
|
+
|
1718
|
+
role_json = @roles_interface.get(account_id, role['id'])
|
1719
|
+
vdi_pool_global_access = role_json['globalVdiPoolAccess']
|
1720
|
+
vdi_pool_permissions = role_json['vdiPoolPermissions'] || []
|
1721
|
+
if vdi_pool_global_access != 'custom'
|
1722
|
+
print "\n", red, "Global VDI Pool Access is currently: #{vdi_pool_global_access.to_s.capitalize}"
|
1723
|
+
print "\n", "You must first set it to Custom via `morpheus roles update-global-vdi-pool-access \"#{name}\" custom`"
|
1724
|
+
print "\n\n", reset
|
1725
|
+
return 1
|
1726
|
+
end
|
1727
|
+
|
1728
|
+
# hacky, but support name or code lookup via the list returned in the show payload
|
1729
|
+
vdi_pool = nil
|
1730
|
+
if !do_all
|
1731
|
+
if vdi_pool_id.to_s =~ /\A\d{1,}\Z/
|
1732
|
+
vdi_pool = vdi_pool_permissions.find {|b| b['id'] == vdi_pool_id.to_i }
|
1733
|
+
else
|
1734
|
+
vdi_pool = vdi_pool_permissions.find {|b| b['name'] == vdi_pool_id }
|
1735
|
+
end
|
1736
|
+
if vdi_pool.nil?
|
1737
|
+
print_red_alert "VDI Pool not found: '#{vdi_pool_id}'"
|
1738
|
+
return 1
|
1739
|
+
end
|
1740
|
+
end
|
1741
|
+
|
1742
|
+
params = {}
|
1743
|
+
if do_all
|
1744
|
+
params['allVdiPools'] = true
|
1745
|
+
else
|
1746
|
+
params['vdiPoolId'] = vdi_pool['id']
|
1747
|
+
end
|
1748
|
+
params['access'] = access_value
|
1749
|
+
@roles_interface.setopts(options)
|
1750
|
+
if options[:dry_run]
|
1751
|
+
print_dry_run @roles_interface.dry.update_vdi_pool(account_id, role['id'], params)
|
1752
|
+
return
|
1753
|
+
end
|
1754
|
+
json_response = @roles_interface.update_vdi_pool(account_id, role['id'], params)
|
1755
|
+
|
1756
|
+
if options[:json]
|
1757
|
+
print JSON.pretty_generate(json_response)
|
1758
|
+
print "\n"
|
1759
|
+
else
|
1760
|
+
if do_all
|
1761
|
+
print_green_success "Role #{role['authority']} access updated for all VDI pools"
|
1762
|
+
else
|
1763
|
+
print_green_success "Role #{role['authority']} access updated for VDI pool #{vdi_pool['name']}"
|
1764
|
+
end
|
1765
|
+
end
|
1766
|
+
return 0
|
1767
|
+
rescue RestClient::Exception => e
|
1768
|
+
print_rest_exception(e, options)
|
1769
|
+
exit 1
|
1770
|
+
end
|
1771
|
+
end
|
1772
|
+
|
1609
1773
|
private
|
1610
1774
|
|
1611
1775
|
def add_role_option_types
|
@@ -1616,7 +1780,7 @@ EOT
|
|
1616
1780
|
{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text'},
|
1617
1781
|
{'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'},
|
1618
1782
|
{'fieldName' => 'multitenantLocked', 'fieldLabel' => 'Multitenant Locked', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'Prevents subtenants from branching off this role/modifying it. '},
|
1619
|
-
{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' =>
|
1783
|
+
{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' => get_persona_select_options(), 'description' => 'Default Persona'}
|
1620
1784
|
]
|
1621
1785
|
end
|
1622
1786
|
|
@@ -1624,20 +1788,16 @@ EOT
|
|
1624
1788
|
add_role_option_types.reject {|it| ['roleType', 'baseRole'].include?(it['fieldName']) }
|
1625
1789
|
end
|
1626
1790
|
|
1627
|
-
|
1628
|
-
def find_cloud_id_by_name(group_id, name)
|
1629
|
-
option_results = @options_interface.options_for_source('clouds', {groupId: group_id})
|
1630
|
-
match = option_results['data'].find { |grp| grp['value'].to_s == name.to_s || grp['name'].downcase == name.downcase}
|
1631
|
-
if match.nil?
|
1632
|
-
print_red_alert "Cloud not found by name #{name}"
|
1633
|
-
return nil
|
1634
|
-
else
|
1635
|
-
return match['value']
|
1636
|
-
end
|
1637
|
-
end
|
1638
|
-
|
1639
1791
|
def role_type_options
|
1640
1792
|
[{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}]
|
1641
1793
|
end
|
1642
1794
|
|
1795
|
+
def get_persona_select_options
|
1796
|
+
[
|
1797
|
+
{'name'=>'Service Catalog','value'=>'serviceCatalog'},
|
1798
|
+
{'name'=>'Standard','value'=>'standard'},
|
1799
|
+
{'name'=>'Virtual Desktop','value'=>'vdi'}
|
1800
|
+
]
|
1801
|
+
end
|
1802
|
+
|
1643
1803
|
end
|