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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +1 -3
  4. data/lib/morpheus/api/api_client.rb +48 -14
  5. data/lib/morpheus/api/certificate_types_interface.rb +14 -0
  6. data/lib/morpheus/api/certificates_interface.rb +9 -0
  7. data/lib/morpheus/api/integration_types_interface.rb +14 -0
  8. data/lib/morpheus/api/integrations_interface.rb +7 -22
  9. data/lib/morpheus/api/network_services_interface.rb +14 -0
  10. data/lib/morpheus/api/read_interface.rb +23 -0
  11. data/lib/morpheus/api/rest_interface.rb +12 -10
  12. data/lib/morpheus/api/roles_interface.rb +7 -0
  13. data/lib/morpheus/api/servers_interface.rb +7 -0
  14. data/lib/morpheus/api/user_settings_interface.rb +38 -18
  15. data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
  16. data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
  17. data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
  18. data/lib/morpheus/api/vdi_interface.rb +28 -0
  19. data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
  20. data/lib/morpheus/cli.rb +9 -2
  21. data/lib/morpheus/cli/activity_command.rb +7 -4
  22. data/lib/morpheus/cli/apps.rb +59 -75
  23. data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
  24. data/lib/morpheus/cli/certificates_command.rb +575 -0
  25. data/lib/morpheus/cli/cli_command.rb +61 -6
  26. data/lib/morpheus/cli/clouds.rb +1 -0
  27. data/lib/morpheus/cli/clusters.rb +5 -2
  28. data/lib/morpheus/cli/commands/standard/history_command.rb +4 -5
  29. data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
  30. data/lib/morpheus/cli/dashboard_command.rb +3 -3
  31. data/lib/morpheus/cli/execution_request_command.rb +15 -5
  32. data/lib/morpheus/cli/hosts.rb +245 -224
  33. data/lib/morpheus/cli/instances.rb +150 -167
  34. data/lib/morpheus/cli/integrations_command.rb +588 -41
  35. data/lib/morpheus/cli/invoices_command.rb +23 -46
  36. data/lib/morpheus/cli/login.rb +7 -0
  37. data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
  38. data/lib/morpheus/cli/mixins/print_helper.rb +36 -18
  39. data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
  40. data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
  41. data/lib/morpheus/cli/network_domains_command.rb +2 -2
  42. data/lib/morpheus/cli/network_routers_command.rb +22 -9
  43. data/lib/morpheus/cli/networks_command.rb +2 -2
  44. data/lib/morpheus/cli/option_types.rb +34 -33
  45. data/lib/morpheus/cli/remote.rb +3 -2
  46. data/lib/morpheus/cli/reports_command.rb +5 -2
  47. data/lib/morpheus/cli/roles.rb +215 -55
  48. data/lib/morpheus/cli/service_plans_command.rb +4 -1
  49. data/lib/morpheus/cli/subnets_command.rb +11 -2
  50. data/lib/morpheus/cli/user_settings_command.rb +268 -57
  51. data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
  52. data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
  53. data/lib/morpheus/cli/vdi_command.rb +359 -0
  54. data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
  55. data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
  56. data/lib/morpheus/cli/version.rb +1 -1
  57. data/lib/morpheus/rest_client.rb +30 -0
  58. data/lib/morpheus/terminal.rb +15 -7
  59. 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['type'] = val
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' => 'content', 'fieldLabel' => 'Type', 'type' => 'select', 'required' => true, 'optionSource' => 'dnsRecordType', 'description' => 'Type for this domain record.', 'defaultValue' => 'A'}], options[:options], @api_client)
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 = avail_groups.find {|it| it['name'] == options[:group] || "#{it['value']}" == "#{options[:group]}".downcase}
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[:server]
296
- server = find_network_server(options[:server])
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[:server]} not found"
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 => {'networkRouter' => ''}}), @api_client, api_params, nil, true)
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' => true}], options[:options], @api_client, params)['description']
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 ruote
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' => true}], options[:options], @api_client, params)['networkMtu']
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
- #if network_type['cidrEditable']
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
- #end
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
- # only sort if displayOrder is set
52
- sorted_option_types = (option_types[0] && option_types[0]['displayOrder']) ? option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i } : option_types
53
- sorted_option_types.each do |option_type|
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'] ? "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldName']}"
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
- value = value.to_s.include?('.') ? value.to_f : value.to_i
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
- value = value.to_s.include?('.') ? value.to_f : value.to_i
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, grails_params(api_params || {}))
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, grails_params(api_params || {}))
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, grails_params(api_params || {}).merge({'optionTypeId' => option_type['id']}))
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, grails_params(api_params || {}))
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, grails_params(api_params || {}))
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, grails_params(api_params || {}))
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, grails_params(api_params || {}).merge({'optionTypeId' => option_type['id']}))
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, grails_params(api_params || {}))
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 << "===============\n"
955
+ out << "#{'=' * header.length}\n"
955
956
  select_options.each do |option|
956
957
  out << " * #{option['name']} [#{option['value']}]\n"
957
958
  end
@@ -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 => "htt[://api.gomorpheus.com", :active => true}
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']}/reportResults/#{report_result['id']}"
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}"
@@ -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[:include_catalog_item_types_access] = true
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[:include_catalog_item_types_access] = true
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
- puts as_pretty_table([json_response], global_access_columns, options)
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[:include_catalog_item_types_access]
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' => [{'name'=>'Service Catalog','value'=>'serviceCatalog'},{'name'=>'Standard','value'=>'standard'}], 'description' => 'Default Persona'}], options[:options], @api_client)
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
- group_name = nil
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
- group_name = val
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(group_name)
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
- cloud_name = nil
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
- puts "val is : #{val}"
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
- # crap, group_id is needed for this api, maybe just use infrastructure or some other optionSource instead.
1002
- group_id = nil
1003
- cloud_id = nil
1023
+ cloud = nil
1004
1024
  if !do_all
1005
- group_id = nil
1006
- if !options[:group].nil?
1007
- group = find_group_by_name_or_id_for_provisioning(options[:group])
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 id #{cloud_id}"
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 Standard\n" +
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' => [{'name'=>'Service Catalog','value'=>'serviceCatalog'},{'name'=>'Standard','value'=>'standard'}], 'description' => 'Default Persona'}
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