morpheus-cli 4.2.21 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +30 -0
  4. data/lib/morpheus/api/billing_interface.rb +34 -0
  5. data/lib/morpheus/api/catalog_item_types_interface.rb +9 -0
  6. data/lib/morpheus/api/deploy_interface.rb +1 -1
  7. data/lib/morpheus/api/deployments_interface.rb +20 -1
  8. data/lib/morpheus/api/forgot_password_interface.rb +17 -0
  9. data/lib/morpheus/api/instances_interface.rb +16 -2
  10. data/lib/morpheus/api/rest_interface.rb +0 -6
  11. data/lib/morpheus/api/roles_interface.rb +14 -0
  12. data/lib/morpheus/api/search_interface.rb +13 -0
  13. data/lib/morpheus/api/servers_interface.rb +14 -0
  14. data/lib/morpheus/api/service_catalog_interface.rb +89 -0
  15. data/lib/morpheus/api/usage_interface.rb +18 -0
  16. data/lib/morpheus/cli.rb +7 -3
  17. data/lib/morpheus/cli/apps.rb +6 -27
  18. data/lib/morpheus/cli/backup_jobs_command.rb +3 -0
  19. data/lib/morpheus/cli/backups_command.rb +3 -0
  20. data/lib/morpheus/cli/catalog_item_types_command.rb +622 -0
  21. data/lib/morpheus/cli/cli_command.rb +70 -21
  22. data/lib/morpheus/cli/commands/standard/curl_command.rb +26 -12
  23. data/lib/morpheus/cli/commands/standard/history_command.rb +3 -1
  24. data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
  25. data/lib/morpheus/cli/commands/standard/source_command.rb +1 -1
  26. data/lib/morpheus/cli/commands/standard/update_command.rb +76 -0
  27. data/lib/morpheus/cli/containers_command.rb +14 -24
  28. data/lib/morpheus/cli/cypher_command.rb +6 -2
  29. data/lib/morpheus/cli/deploy.rb +199 -90
  30. data/lib/morpheus/cli/deployments.rb +341 -28
  31. data/lib/morpheus/cli/deploys.rb +206 -41
  32. data/lib/morpheus/cli/error_handler.rb +7 -0
  33. data/lib/morpheus/cli/forgot_password.rb +133 -0
  34. data/lib/morpheus/cli/groups.rb +1 -1
  35. data/lib/morpheus/cli/health_command.rb +59 -2
  36. data/lib/morpheus/cli/hosts.rb +265 -34
  37. data/lib/morpheus/cli/instances.rb +186 -100
  38. data/lib/morpheus/cli/invoices_command.rb +33 -16
  39. data/lib/morpheus/cli/jobs_command.rb +28 -6
  40. data/lib/morpheus/cli/library_option_lists_command.rb +15 -7
  41. data/lib/morpheus/cli/library_option_types_command.rb +5 -2
  42. data/lib/morpheus/cli/logs_command.rb +9 -6
  43. data/lib/morpheus/cli/mixins/accounts_helper.rb +12 -7
  44. data/lib/morpheus/cli/mixins/backups_helper.rb +2 -4
  45. data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -3
  46. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  47. data/lib/morpheus/cli/mixins/print_helper.rb +46 -21
  48. data/lib/morpheus/cli/mixins/provisioning_helper.rb +100 -4
  49. data/lib/morpheus/cli/network_pools_command.rb +14 -6
  50. data/lib/morpheus/cli/option_types.rb +271 -22
  51. data/lib/morpheus/cli/ping.rb +0 -1
  52. data/lib/morpheus/cli/remote.rb +35 -12
  53. data/lib/morpheus/cli/reports_command.rb +99 -30
  54. data/lib/morpheus/cli/roles.rb +453 -113
  55. data/lib/morpheus/cli/search_command.rb +182 -0
  56. data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
  57. data/lib/morpheus/cli/service_plans_command.rb +2 -2
  58. data/lib/morpheus/cli/setup.rb +1 -1
  59. data/lib/morpheus/cli/shell.rb +33 -11
  60. data/lib/morpheus/cli/storage_providers_command.rb +40 -56
  61. data/lib/morpheus/cli/tasks.rb +29 -32
  62. data/lib/morpheus/cli/usage_command.rb +203 -0
  63. data/lib/morpheus/cli/user_settings_command.rb +1 -0
  64. data/lib/morpheus/cli/users.rb +12 -1
  65. data/lib/morpheus/cli/version.rb +1 -1
  66. data/lib/morpheus/cli/virtual_images.rb +429 -254
  67. data/lib/morpheus/cli/whoami.rb +6 -6
  68. data/lib/morpheus/cli/workflows.rb +34 -41
  69. data/lib/morpheus/formatters.rb +75 -7
  70. data/lib/morpheus/terminal.rb +6 -2
  71. metadata +14 -2
@@ -199,7 +199,6 @@ EOT
199
199
  "Version" => lambda {|it| appliance[:build_version] },
200
200
  # "Active" => lambda {|it| it[:active] ? "Yes " + format_is_current() : "No" },
201
201
  "Response Time" => lambda {|it| format_duration_seconds(took_sec) },
202
- #"Response Time" => lambda {|it| format_sig_dig(took_sec, 3) + "s" rescue "" },
203
202
  # "Error" => lambda {|it| error_string },
204
203
  "Status" => lambda {|it| format_appliance_status(appliance, cyan) },
205
204
  }
@@ -23,6 +23,8 @@ class Morpheus::Cli::Remote
23
23
 
24
24
  set_default_subcommand :list
25
25
 
26
+ set_subcommands_hidden :setup # this is going away too
27
+
26
28
  def initialize()
27
29
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
28
30
  end
@@ -137,7 +139,6 @@ EOT
137
139
  check_str
138
140
  },
139
141
  "Response Time" => lambda {|it| format_duration_milliseconds(it[:last_check][:took]) rescue "" },
140
- #"Response Time" => lambda {|it| format_sig_dig((it[:last_check][:took]/ 1000.to_f), 3) + "s" rescue "" },
141
142
  "Error" => {display_method: lambda {|it|
142
143
  error_str = it[:last_check] ? it[:last_check][:error].to_s : ""
143
144
  error_str
@@ -596,7 +597,7 @@ EOT
596
597
  if args.count != 0
597
598
  raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
598
599
  end
599
- connect(options) # needed?
600
+ #connect(options) # needed?
600
601
  _check_all_appliances(options)
601
602
  end
602
603
 
@@ -827,6 +828,12 @@ EOT
827
828
  options[:do_offline] = true
828
829
  end
829
830
  build_common_options(opts, options, [:json,:yaml,:csv,:fields, :quiet])
831
+ opts.footer = <<-EOT
832
+ Print details about the a remote appliance.
833
+ [name] is optional. This is the name of a remote.
834
+ By default, the current appliance is used.
835
+ Returns an error if the specified remote is not found, or there is no current remote.
836
+ EOT
830
837
  end
831
838
  optparse.parse!(args)
832
839
  id_list = nil
@@ -844,7 +851,16 @@ EOT
844
851
 
845
852
  def _get(appliance_name, options)
846
853
  exit_code, err = 0, nil
847
-
854
+ if appliance_name == 'current'
855
+ current_appliance = ::Morpheus::Cli::Remote.load_active_remote()
856
+ if current_appliance.nil?
857
+ #raise_command_error "No current appliance, see the command `remote use`"
858
+ unless options[:quiet]
859
+ print yellow, "No current appliance, see the command `remote use`", reset, "\n"
860
+ end
861
+ return 1, "No current appliance"
862
+ end
863
+ end
848
864
  appliance = load_remote_by_name(appliance_name)
849
865
  appliance_name = appliance[:name]
850
866
  appliance_url = appliance[:url]
@@ -1040,15 +1056,14 @@ EOT
1040
1056
  end
1041
1057
  build_common_options(opts, options, [:quiet])
1042
1058
  opts.footer = <<-EOT
1043
- [name] is required. This is the name of a remote, see the command `remote list`.
1059
+ [name] is required. This is the name of a remote to begin using.
1044
1060
  Start using a remote, making it the active (current) remote appliance.
1045
1061
  This switches the remote context of your client configuration for all subsequent commands.
1046
- So rely on 'remote use' with caution.
1047
1062
  It is important to always be aware of the context your commands are running in.
1048
1063
  The command `remote current` will return the current remote information.
1049
- Also, instead of using an active remote, the -r option can be specified in your commands.
1064
+ Instead of using an active remote, the -r option can be specified with each command.
1050
1065
 
1051
- It is recommeneded to set a custom prompt to show the remote name.
1066
+ It is recommeneded to set a custom prompt to show the current remote name.
1052
1067
  For example, add the following to your .morpheusrc file:
1053
1068
 
1054
1069
  # set your shell prompt to display the current username and remote
@@ -1156,13 +1171,22 @@ EOT
1156
1171
  end
1157
1172
  optparse.parse!(args)
1158
1173
  verify_args!(args:args, count:0, optparse:optparse)
1159
- connect(options)
1174
+ #connect(options)
1175
+
1176
+ current_appliance = ::Morpheus::Cli::Remote.load_active_remote()
1177
+ if current_appliance.nil?
1178
+ #raise_command_error "No current appliance, see the command `remote use`"
1179
+ unless options[:quiet]
1180
+ print yellow, "No current appliance, see the command `remote use`", reset, "\n"
1181
+ end
1182
+ return 1, "No current appliance"
1183
+ end
1160
1184
 
1161
1185
  # this does the same thing
1162
1186
  #return _get("current", options)
1163
-
1164
- # appliance = load_remote_by_name("current")
1165
- appliance = @remote_appliance
1187
+ appliance = current_appliance
1188
+ #appliance = load_remote_by_name("current")
1189
+ #appliance = @remote_appliance
1166
1190
  exit_code, err = 0, nil
1167
1191
  if appliance.nil?
1168
1192
  raise_command_error "no current remote appliance, see command `remote add`."
@@ -1283,7 +1307,6 @@ EOT
1283
1307
  end
1284
1308
  },
1285
1309
  "Response Time" => lambda {|it| format_duration_milliseconds(it[:last_check][:took]) rescue "" },
1286
- #"Response Time" => lambda {|it| format_sig_dig((it[:last_check][:took]/ 1000.to_f), 3) + "s" rescue "" },
1287
1310
  "Status" => lambda {|it| format_appliance_status(it, cyan) },
1288
1311
  "Error" => lambda {|it|
1289
1312
  error_str = it[:last_check] ? it[:last_check][:error] : ""
@@ -15,7 +15,10 @@ class Morpheus::Cli::ReportsCommand
15
15
  @reports_interface = @api_client.reports
16
16
  end
17
17
 
18
- register_subcommands :list, :get, :run, :view, :export, :remove, :types
18
+ register_subcommands :list, :get, :run, :view, :export, :remove
19
+ register_subcommands :'list-types' => :list_types
20
+ register_subcommands :'get-type' => :get_type
21
+ alias_subcommand :types, :'list-types'
19
22
 
20
23
  def default_refresh_interval
21
24
  5
@@ -271,10 +274,10 @@ class Morpheus::Cli::ReportsCommand
271
274
 
272
275
  # Report Types tell us what the available filters are...
273
276
  report_option_types = report_type['optionTypes'] || []
274
- report_option_types = report_option_types.collect {|it|
275
- it['fieldContext'] = nil
276
- it
277
- }
277
+ # report_option_types = report_option_types.collect {|it|
278
+ # it['fieldContext'] = nil
279
+ # it
280
+ # }
278
281
  # pluck out optionTypes like the UI does..
279
282
  metadata_option_type = nil
280
283
  if report_option_types.find {|it| it['fieldName'] == 'metadata' }
@@ -284,6 +287,13 @@ class Morpheus::Cli::ReportsCommand
284
287
  v_prompt = Morpheus::Cli::OptionTypes.prompt(report_option_types, options[:options], @api_client)
285
288
  payload.deep_merge!({'report' => v_prompt}) unless v_prompt.empty?
286
289
 
290
+ # strip out fieldContext: 'config' please
291
+ # just report.startDate instead of report.config.startDate
292
+ if payload['report']['config'].is_a?(Hash)
293
+ payload['report']['config']
294
+ payload['report'].deep_merge!(payload['report'].delete('config'))
295
+ end
296
+
287
297
  if metadata_option_type
288
298
  if !options[:options]['metadata']
289
299
  metadata_filter = prompt_metadata(options)
@@ -466,33 +476,30 @@ class Morpheus::Cli::ReportsCommand
466
476
  end
467
477
  end
468
478
 
469
- def types(args)
479
+ def list_types(args)
480
+ params = {}
470
481
  options = {}
471
482
  optparse = Morpheus::Cli::OptionParser.new do |opts|
472
483
  opts.banner = subcommand_usage()
473
- build_common_options(opts, options, [:list, :json, :dry_run, :remote])
484
+ build_standard_list_options(opts, options)
474
485
  opts.footer = "List report types."
475
486
  end
476
487
  optparse.parse!(args)
488
+ if args.count > 0
489
+ options[:phrase] = args.join(" ")
490
+ end
477
491
  connect(options)
478
- begin
479
- params = {}
480
- params.merge!(parse_list_options(options))
481
-
482
- @reports_interface.setopts(options)
483
- if options[:dry_run]
484
- print_dry_run @reports_interface.dry.types(params)
485
- return
486
- end
487
-
488
- json_response = @reports_interface.types(params)
489
- if options[:json]
490
- print JSON.pretty_generate(json_response)
491
- print "\n"
492
- return
493
- end
494
-
492
+ params.merge!(parse_list_options(options))
493
+
494
+ @reports_interface.setopts(options)
495
+ if options[:dry_run]
496
+ print_dry_run @reports_interface.dry.types(params)
497
+ return
498
+ end
495
499
 
500
+ json_response = @reports_interface.types(params)
501
+ report_types = json_response['reportTypes']
502
+ render_response(json_response, options, 'reportTypes') do
496
503
  title = "Morpheus Report Types"
497
504
  subtitles = []
498
505
  subtitles += parse_list_subtitles(options)
@@ -520,13 +527,75 @@ class Morpheus::Cli::ReportsCommand
520
527
  end
521
528
  end
522
529
  print reset,"\n"
523
- return 0
524
- rescue RestClient::Exception => e
525
- print_rest_exception(e, options)
526
- exit 1
530
+ end
531
+ if report_types.empty?
532
+ return 1, "no report types found"
533
+ else
534
+ return 0, nil
527
535
  end
528
536
  end
529
537
 
538
+ def get_type(args)
539
+ params = {}
540
+ options = {}
541
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
542
+ opts.banner = subcommand_usage()
543
+ build_standard_get_options(opts, options)
544
+ opts.footer = <<-EOT
545
+ Get report type
546
+ [name] is required. This is the name of a report type
547
+ EOT
548
+ end
549
+ optparse.parse!(args)
550
+ connect(options)
551
+ verify_args!(args:args, optparse:optparse, min:1)
552
+ params.merge!(parse_query_options(options))
553
+ params['name'] = args.join(" ")
554
+ @reports_interface.setopts(options)
555
+ if options[:dry_run]
556
+ print_dry_run @reports_interface.dry.types(params)
557
+ return
558
+ end
559
+
560
+ # json_response = @reports_interface.types(params)
561
+ # api does not have a show() action right now... so find by code or name only
562
+ report_type = find_report_type_by_name_or_code_id(params['name'])
563
+ return 1 if report_type.nil?
564
+
565
+ # json_response = @reports_interface.get_type(report_type['id'])
566
+ # report_type = json_response['reportType']
567
+ json_response = {'reportType' => report_type}
568
+ render_response(json_response, options, 'reportType') do
569
+ print_h1 "Report Type Details", [], options
570
+
571
+ description_cols = {
572
+ "ID" => 'id',
573
+ "Name" => 'name',
574
+ "Code" => 'code',
575
+ "Description" => 'description',
576
+ "Category" => 'category'
577
+ }
578
+ print_description_list(description_cols, report_type)
579
+
580
+ print_h2 "Option Types", options
581
+ opt_columns = [
582
+ {"ID" => lambda {|it| it['id'] } },
583
+ {"NAME" => lambda {|it| it['name'] } },
584
+ {"TYPE" => lambda {|it| it['type'] } },
585
+ {"FIELD NAME" => lambda {|it| it['fieldName'] } },
586
+ {"FIELD LABEL" => lambda {|it| it['fieldLabel'] } },
587
+ {"DEFAULT" => lambda {|it| it['defaultValue'] } },
588
+ {"REQUIRED" => lambda {|it| format_boolean it['required'] } },
589
+ ]
590
+ option_types = report_type['optionTypes']
591
+ sorted_option_types = (option_types && option_types[0] && option_types[0]['displayOrder']) ? option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i } : option_types
592
+ print as_pretty_table(sorted_option_types, opt_columns)
593
+
594
+ print reset,"\n"
595
+ end
596
+ return 0, nil
597
+
598
+ end
530
599
 
531
600
  def find_report_result_by_id(id)
532
601
  begin
@@ -551,7 +620,7 @@ class Morpheus::Cli::ReportsCommand
551
620
  end
552
621
 
553
622
  def find_report_type_by_id(id)
554
- @all_report_types ||= @reports_interface.list({max: 1000})['reportTypes'] || []
623
+ @all_report_types ||= @reports_interface.types({max: 10000})['reportTypes'] || []
555
624
  report_types = @all_report_types.select { |it| id && it['id'] == id.to_i }
556
625
  if report_types.empty?
557
626
  print_red_alert "Report Type not found by id #{id}"
@@ -570,7 +639,7 @@ class Morpheus::Cli::ReportsCommand
570
639
  end
571
640
 
572
641
  def find_report_type_by_name_or_code(name)
573
- @all_report_types ||= @reports_interface.list({max: 1000})['reportTypes'] || []
642
+ @all_report_types ||= @reports_interface.types({max: 10000})['reportTypes'] || []
574
643
  report_types = @all_report_types.select { |it| name && it['code'] == name || it['name'] == name }
575
644
  if report_types.empty?
576
645
  print_red_alert "Report Type not found by code #{name}"
@@ -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'
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'
17
17
  alias_subcommand :details, :get
18
18
  set_default_subcommand :list
19
19
 
@@ -101,12 +101,20 @@ class Morpheus::Cli::Roles
101
101
  opts.on('-b','--blueprint-access', "Display Blueprint Access") do
102
102
  options[:include_blueprint_access] = true
103
103
  end
104
- opts.on('-a','--all-access', "Display All Access Lists") do
104
+ opts.on(nil,'--catalog-item-type-access', "Display Catalog Item Type Access") do
105
+ options[:include_catalog_item_types_access] = true
106
+ end
107
+ opts.on(nil,'--personas', "Display Persona Access") do
108
+ options[:include_personas_access] = true
109
+ end
110
+ opts.on('-a','--all', "Display All Access Lists") do
105
111
  options[:include_feature_access] = true
106
112
  options[:include_group_access] = true
107
113
  options[:include_cloud_access] = true
108
114
  options[:include_instance_type_access] = true
109
115
  options[:include_blueprint_access] = true
116
+ options[:include_catalog_item_types_access] = true
117
+ options[:include_personas_access] = true
110
118
  end
111
119
  build_standard_get_options(opts, options)
112
120
  opts.footer = <<-EOT
@@ -198,57 +206,75 @@ EOT
198
206
  rows = rows.select {|row| row[:code].to_s =~ phrase_regexp || row[:name].to_s =~ phrase_regexp }
199
207
  end
200
208
  print as_pretty_table(rows, [:code, :name, :access], options)
209
+ print reset,"\n"
201
210
  else
202
211
  print cyan,"Use --permissions to list permissions","\n"
203
212
  end
204
213
 
214
+ has_group_access = true
215
+ has_cloud_access = true
205
216
  print_h2 "Global Access", options
206
- puts as_pretty_table([json_response], [
207
- {"Groups" => lambda {|it| get_access_string(it['globalSiteAccess']) } },
208
- {"Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) } },
209
- {"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) } },
210
- {"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) } },
211
- ], options)
212
-
213
- #print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
214
- print cyan
215
- if json_response['globalSiteAccess'] == 'custom'
216
- print_h2 "Group Access", options
217
- if options[:include_group_access]
218
- rows = json_response['sites'].collect do |it|
219
- {
220
- name: it['name'],
221
- access: format_access_string(it['access'], ["none","read","full"]),
222
- }
217
+ global_access_columns = {
218
+ "Groups" => lambda {|it| get_access_string(it['globalSiteAccess']) },
219
+ "Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) },
220
+ "Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) },
221
+ "Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) },
222
+ "Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) },
223
+ }
224
+ if role['roleType'].to_s.downcase == 'account'
225
+ global_access_columns.delete("Groups")
226
+ has_group_access = false
227
+ else
228
+ global_access_columns.delete("Clouds")
229
+ has_cloud_access = false
230
+ end
231
+ puts as_pretty_table([json_response], global_access_columns, options)
232
+
233
+ if has_group_access
234
+ #print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
235
+ print cyan
236
+ if json_response['globalSiteAccess'] == 'custom'
237
+ print_h2 "Group Access", options
238
+ if options[:include_group_access]
239
+ rows = json_response['sites'].collect do |it|
240
+ {
241
+ name: it['name'],
242
+ access: format_access_string(it['access'], ["none","read","full"]),
243
+ }
244
+ end
245
+ print as_pretty_table(rows, [:name, :access], options)
246
+ else
247
+ print cyan,"Use -g, --group-access to list custom access","\n"
223
248
  end
224
- print as_pretty_table(rows, [:name, :access], options)
249
+ print reset,"\n"
225
250
  else
226
- print cyan,"Use -g, --group-access to list custom access","\n"
251
+ # print "\n"
252
+ # print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
227
253
  end
228
- else
229
- # print "\n"
230
- # print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
231
254
  end
232
255
 
233
- print cyan
234
- #puts "Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}"
235
- #print "\n"
236
- if json_response['globalZoneAccess'] == 'custom'
237
- print_h2 "Cloud Access", options
238
- if options[:include_cloud_access]
239
- rows = json_response['zones'].collect do |it|
240
- {
241
- name: it['name'],
242
- access: format_access_string(it['access'], ["none","read","full"]),
243
- }
256
+ if has_cloud_access
257
+ print cyan
258
+ #puts "Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}"
259
+ #print "\n"
260
+ if json_response['globalZoneAccess'] == 'custom'
261
+ print_h2 "Cloud Access", options
262
+ if options[:include_cloud_access]
263
+ rows = json_response['zones'].collect do |it|
264
+ {
265
+ name: it['name'],
266
+ access: format_access_string(it['access'], ["none","read","full"]),
267
+ }
268
+ end
269
+ print as_pretty_table(rows, [:name, :access], options)
270
+ else
271
+ print cyan,"Use -c, --cloud-access to list custom access","\n"
244
272
  end
245
- print as_pretty_table(rows, [:name, :access], options)
273
+ print reset,"\n"
246
274
  else
247
- print cyan,"Use -c, --cloud-access to list custom access","\n"
275
+ # print "\n"
276
+ # print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
248
277
  end
249
- else
250
- # print "\n"
251
- # print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
252
278
  end
253
279
 
254
280
  print cyan
@@ -267,6 +293,7 @@ EOT
267
293
  else
268
294
  print cyan,"Use -i, --instance-type-access to list custom access","\n"
269
295
  end
296
+ print reset,"\n"
270
297
  else
271
298
  # print "\n"
272
299
  # print cyan,bold,"Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}",reset,"\n"
@@ -290,12 +317,55 @@ EOT
290
317
  else
291
318
  print cyan,"Use -b, --blueprint-access to list custom access","\n"
292
319
  end
320
+ print reset,"\n"
293
321
  else
294
322
  # print "\n"
295
323
  # print cyan,bold,"Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}",reset,"\n"
296
324
  end
297
- print reset,"\n"
325
+
326
+
327
+ catalog_item_type_global_access = json_response['globalCatalogItemTypeAccess']
328
+ catalog_item_type_permissions = json_response['catalogItemTypePermissions'] || []
329
+ print cyan
330
+ # print_h2 "catalog_item_type Access: #{get_access_string(json_response['globalCatalogItemTypeAccess'])}", options
331
+ # print "\n"
332
+ if catalog_item_type_global_access == 'custom'
333
+ print_h2 "Catalog Item Type Access", options
334
+ if options[:include_catalog_item_types_access]
335
+ rows = catalog_item_type_permissions.collect do |it|
336
+ {
337
+ name: it['name'],
338
+ access: format_access_string(it['access'], ["none","read","full"]),
339
+ }
340
+ end
341
+ print as_pretty_table(rows, [:name, :access], options)
342
+ else
343
+ print cyan,"Use --catalog-item-type-access to list custom access","\n"
344
+ end
345
+ else
346
+ # print "\n"
347
+ # print cyan,bold,"Catalog Item Type Access: #{get_access_string(json_response['globalCatalogItemTypeAccess'])}",reset,"\n"
348
+ end
349
+
350
+
351
+ persona_permissions = json_response['personaPermissions'] || json_response['personas'] || []
352
+ # if options[:include_personas_access]
353
+ if persona_permissions
354
+ print_h2 "Persona Access", options
355
+ rows = persona_permissions.collect do |it|
356
+ {
357
+ name: it['name'],
358
+ access: format_access_string(it['access'], ["none","read","full"]),
359
+ }
360
+ end
361
+ print as_pretty_table(rows, [:name, :access], options)
362
+ print reset,"\n"
363
+ end
364
+
365
+ # print reset,"\n"
366
+
298
367
  end
368
+
299
369
  return 0, nil
300
370
  end
301
371
 
@@ -449,6 +519,10 @@ EOT
449
519
  end
450
520
  end
451
521
 
522
+ # 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)
524
+ role_payload['defaultPersona'] = {'code' => v_prompt['defaultPersona']} unless v_prompt['defaultPersona'].to_s.strip.empty?
525
+
452
526
  payload = {"role" => role_payload}
453
527
  end
454
528
  @roles_interface.setopts(options)
@@ -493,7 +567,7 @@ EOT
493
567
  options = {}
494
568
  params = {}
495
569
  optparse = Morpheus::Cli::OptionParser.new do |opts|
496
- opts.banner = subcommand_usage("[name] [options]")
570
+ opts.banner = subcommand_usage("[role] [options]")
497
571
  build_option_type_options(opts, options, update_role_option_types)
498
572
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
499
573
  end
@@ -571,7 +645,7 @@ EOT
571
645
  def remove(args)
572
646
  options = {}
573
647
  optparse = Morpheus::Cli::OptionParser.new do |opts|
574
- opts.banner = subcommand_usage("[name]")
648
+ opts.banner = subcommand_usage("[role]")
575
649
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
576
650
  end
577
651
  optparse.parse!(args)
@@ -711,41 +785,46 @@ EOT
711
785
  group_name = nil
712
786
  access_value = nil
713
787
  do_all = false
788
+ allowed_access_values = ['full', 'read', 'none']
714
789
  optparse = Morpheus::Cli::OptionParser.new do |opts|
715
- opts.banner = subcommand_usage("[name]")
790
+ opts.banner = subcommand_usage("[role] [group] [access]")
716
791
  opts.on( '-g', '--group GROUP', "Group name or id" ) do |val|
717
792
  group_name = val
718
793
  end
719
794
  opts.on( nil, '--all', "Update all groups at once." ) do
720
795
  do_all = true
721
796
  end
722
- opts.on( '--access VALUE', String, "Access value [full|read|none]" ) do |val|
797
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
723
798
  access_value = val
724
799
  end
725
800
  build_common_options(opts, options, [:json, :dry_run, :remote])
726
801
  opts.footer = "Update role access for a group or all groups.\n" +
727
- "[name] is required. This is the name or id of a role.\n" +
802
+ "[role] is required. This is the name or id of a role.\n" +
728
803
  "--group or --all is required. This is the name or id of a group.\n" +
729
- "--access is required. This is the new access value."
804
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
730
805
  end
731
806
  optparse.parse!(args)
732
- if args.count < 1
733
- puts optparse
734
- return 1
735
- end
736
- name = args[0]
737
- # support old usage: [name] [group] [access]
738
- group_name ||= args[1]
739
- access_value ||= args[2]
740
807
 
741
- if (!group_name && !do_all) || !access_value
742
- puts optparse
743
- return 1
808
+ # usage: update-group-access [role] [access] --all
809
+ # update-group-access [role] [group] [access]
810
+ name = args[0]
811
+ if do_all
812
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
813
+ access_value = args[1] if args[1]
814
+ else
815
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
816
+ group_id = args[1] if args[1]
817
+ access_value = args[2] if args[2]
818
+ end
819
+ if !group_id && !do_all
820
+ raise_command_error("missing required argument: [group] or --all", optparse)
821
+ end
822
+ if !access_value
823
+ raise_command_error("missing required argument: [access]", optparse)
744
824
  end
745
-
746
825
  access_value = access_value.to_s.downcase
747
-
748
- if !['full', 'read', 'none'].include?(access_value)
826
+ if !allowed_access_values.include?(access_value)
827
+ raise_command_error("invalid access value: #{access_value}", optparse)
749
828
  puts optparse
750
829
  return 1
751
830
  end
@@ -856,6 +935,7 @@ EOT
856
935
  cloud_name = nil
857
936
  access_value = nil
858
937
  do_all = false
938
+ allowed_access_values = ['full', 'read', 'none']
859
939
  optparse = Morpheus::Cli::OptionParser.new do |opts|
860
940
  opts.banner = subcommand_usage("[name]")
861
941
  opts.on( '-c', '--cloud CLOUD', "Cloud name or id" ) do |val|
@@ -865,7 +945,7 @@ EOT
865
945
  opts.on( nil, '--all', "Update all clouds at once." ) do
866
946
  do_all = true
867
947
  end
868
- opts.on( '--access VALUE', String, "Access value [full|read|none]" ) do |val|
948
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
869
949
  access_value = val
870
950
  end
871
951
  opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
@@ -873,32 +953,34 @@ EOT
873
953
  end
874
954
  build_common_options(opts, options, [:json, :dry_run, :remote])
875
955
  opts.footer = "Update role access for a cloud or all clouds.\n" +
876
- "[name] is required. This is the name or id of a role.\n" +
956
+ "[role] is required. This is the name or id of a role.\n" +
877
957
  "--cloud or --all is required. This is the name or id of a cloud.\n" +
878
- "--access is required. This is the new access value."
958
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
879
959
  end
880
960
  optparse.parse!(args)
881
961
 
882
- if args.count < 1
883
- puts optparse
884
- return 1
885
- end
962
+ # usage: update-cloud-access [role] [access] --all
963
+ # update-cloud-access [role] [cloud] [access]
886
964
  name = args[0]
887
- # support old usage: [name] [cloud] [access]
888
- cloud_name ||= args[1]
889
- access_value ||= args[2]
890
-
891
- if (!cloud_name && !do_all) || !access_value
892
- puts optparse
893
- return 1
965
+ if do_all
966
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
967
+ access_value = args[1] if args[1]
968
+ else
969
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
970
+ cloud_id = args[1] if args[1]
971
+ access_value = args[2] if args[2]
972
+ end
973
+ if !cloud_id && !do_all
974
+ raise_command_error("missing required argument: [cloud] or --all", optparse)
975
+ end
976
+ if !access_value
977
+ raise_command_error("missing required argument: [access]", optparse)
894
978
  end
895
- puts "cloud_name is : #{cloud_name}"
896
- puts "access_value is : #{access_value}"
897
979
  access_value = access_value.to_s.downcase
898
-
899
- if !['full', 'none'].include?(access_value)
980
+ if !allowed_access_values.include?(access_value)
981
+ raise_command_error("invalid access value: #{access_value}", optparse)
900
982
  puts optparse
901
- exit 1
983
+ return 1
902
984
  end
903
985
 
904
986
  connect(options)
@@ -966,10 +1048,10 @@ EOT
966
1048
  end
967
1049
 
968
1050
  def update_global_instance_type_access(args)
969
- usage = "Usage: morpheus roles update-global-instance-type-access [name] [full|custom|none]"
1051
+ usage = "Usage: morpheus roles update-global-instance-type-access [role] [full|custom|none]"
970
1052
  options = {}
971
1053
  optparse = Morpheus::Cli::OptionParser.new do |opts|
972
- opts.banner = subcommand_usage("[name] [full|custom|none]")
1054
+ opts.banner = subcommand_usage("[role] [full|custom|none]")
973
1055
  build_common_options(opts, options, [:json, :dry_run, :remote])
974
1056
  end
975
1057
  optparse.parse!(args)
@@ -1018,22 +1100,23 @@ EOT
1018
1100
  instance_type_name = nil
1019
1101
  access_value = nil
1020
1102
  do_all = false
1103
+ allowed_access_values = ['full', 'none']
1021
1104
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1022
- opts.banner = subcommand_usage("[name]")
1105
+ opts.banner = subcommand_usage("[role] [type] [access]")
1023
1106
  opts.on( '--instance-type INSTANCE_TYPE', String, "Instance Type name" ) do |val|
1024
1107
  instance_type_name = val
1025
1108
  end
1026
1109
  opts.on( nil, '--all', "Update all instance types at once." ) do
1027
1110
  do_all = true
1028
1111
  end
1029
- opts.on( '--access VALUE', String, "Access value [full|read|none]" ) do |val|
1112
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
1030
1113
  access_value = val
1031
1114
  end
1032
1115
  build_common_options(opts, options, [:json, :dry_run, :remote])
1033
1116
  opts.footer = "Update role access for an instance type or all instance types.\n" +
1034
- "[name] is required. This is the name or id of a role.\n" +
1117
+ "[role] is required. This is the name or id of a role.\n" +
1035
1118
  "--instance-type or --all is required. This is the name of an instance type.\n" +
1036
- "--access is required. This is the new access value."
1119
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1037
1120
  end
1038
1121
  optparse.parse!(args)
1039
1122
 
@@ -1042,7 +1125,7 @@ EOT
1042
1125
  return 1
1043
1126
  end
1044
1127
  name = args[0]
1045
- # support old usage: [name] [instance-type] [access]
1128
+ # support old usage: [role] [instance-type] [access]
1046
1129
  instance_type_name ||= args[1]
1047
1130
  access_value ||= args[2]
1048
1131
 
@@ -1111,10 +1194,10 @@ EOT
1111
1194
  end
1112
1195
 
1113
1196
  def update_global_blueprint_access(args)
1114
- usage = "Usage: morpheus roles update-global-blueprint-access [name] [full|custom|none]"
1197
+ usage = "Usage: morpheus roles update-global-blueprint-access [role] [full|custom|none]"
1115
1198
  options = {}
1116
1199
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1117
- opts.banner = subcommand_usage("[name] [full|custom|none]")
1200
+ opts.banner = subcommand_usage("[role] [full|custom|none]")
1118
1201
  build_common_options(opts, options, [:json, :dry_run, :remote])
1119
1202
  end
1120
1203
  optparse.parse!(args)
@@ -1163,42 +1246,46 @@ EOT
1163
1246
  blueprint_id = nil
1164
1247
  access_value = nil
1165
1248
  do_all = false
1249
+ allowed_access_values = ['full', 'none']
1166
1250
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1167
- opts.banner = subcommand_usage("[name]")
1251
+ opts.banner = subcommand_usage("[role] [blueprint] [access]")
1168
1252
  opts.on( '--blueprint ID', String, "Blueprint ID or Name" ) do |val|
1169
1253
  blueprint_id = val
1170
1254
  end
1171
1255
  opts.on( nil, '--all', "Update all blueprints at once." ) do
1172
1256
  do_all = true
1173
1257
  end
1174
- opts.on( '--access VALUE', String, "Access value [full|read|none]" ) do |val|
1258
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
1175
1259
  access_value = val
1176
1260
  end
1177
1261
  build_common_options(opts, options, [:json, :dry_run, :remote])
1178
1262
  opts.footer = "Update role access for an blueprint or all blueprints.\n" +
1179
- "[name] is required. This is the name or id of a role.\n" +
1263
+ "[role] is required. This is the name or id of a role.\n" +
1180
1264
  "--blueprint or --all is required. This is the name or id of a blueprint.\n" +
1181
- "--access is required. This is the new access value."
1265
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1182
1266
  end
1183
1267
  optparse.parse!(args)
1184
1268
 
1185
- if args.count < 1
1186
- puts optparse
1187
- return 1
1188
- end
1269
+ # usage: update-blueprint-access [role] [access] --all
1270
+ # update-blueprint-access [role] [blueprint] [access]
1189
1271
  name = args[0]
1190
- # support old usage: [name] [blueprint] [access]
1191
- blueprint_id ||= args[1]
1192
- access_value ||= args[2]
1193
-
1194
- if (!blueprint_id && !do_all) || !access_value
1195
- puts_error optparse
1196
- return 1
1272
+ if do_all
1273
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
1274
+ access_value = args[1] if args[1]
1275
+ else
1276
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
1277
+ blueprint_id = args[1] if args[1]
1278
+ access_value = args[2] if args[2]
1279
+ end
1280
+ if !blueprint_id && !do_all
1281
+ raise_command_error("missing required argument: [blueprint] or --all", optparse)
1282
+ end
1283
+ if !access_value
1284
+ raise_command_error("missing required argument: [access]", optparse)
1197
1285
  end
1198
-
1199
1286
  access_value = access_value.to_s.downcase
1200
-
1201
- if !['full', 'none'].include?(access_value)
1287
+ if !allowed_access_values.include?(access_value)
1288
+ raise_command_error("invalid access value: #{access_value}", optparse)
1202
1289
  puts optparse
1203
1290
  return 1
1204
1291
  end
@@ -1267,16 +1354,269 @@ EOT
1267
1354
  end
1268
1355
  end
1269
1356
 
1357
+ def update_global_catalog_item_type_access(args)
1358
+ usage = "Usage: morpheus roles update-global-catalog-item-type-access [role] [full|custom|none]"
1359
+ options = {}
1360
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1361
+ opts.banner = subcommand_usage("[role] [full|custom|none]")
1362
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1363
+ end
1364
+ optparse.parse!(args)
1365
+
1366
+ if args.count < 2
1367
+ puts optparse
1368
+ exit 1
1369
+ end
1370
+ name = args[0]
1371
+ access_value = args[1].to_s.downcase
1372
+ if !['full', 'custom', 'none'].include?(access_value)
1373
+ puts optparse
1374
+ exit 1
1375
+ end
1376
+
1377
+
1378
+ connect(options)
1379
+ begin
1380
+ account = find_account_from_options(options)
1381
+ account_id = account ? account['id'] : nil
1382
+ role = find_role_by_name_or_id(account_id, name)
1383
+ exit 1 if role.nil?
1384
+
1385
+ params = {permissionCode: 'CatalogItemType', access: access_value}
1386
+ @roles_interface.setopts(options)
1387
+ if options[:dry_run]
1388
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
1389
+ return
1390
+ end
1391
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
1392
+
1393
+ if options[:json]
1394
+ print JSON.pretty_generate(json_response)
1395
+ print "\n"
1396
+ else
1397
+ print_green_success "Role #{role['authority']} global catalog item type access updated"
1398
+ end
1399
+ rescue RestClient::Exception => e
1400
+ print_rest_exception(e, options)
1401
+ exit 1
1402
+ end
1403
+ end
1404
+
1405
+ def update_catalog_item_type_access(args)
1406
+ options = {}
1407
+ catalog_item_type_id = nil
1408
+ access_value = nil
1409
+ do_all = false
1410
+ allowed_access_values = ['full', 'none']
1411
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1412
+ opts.banner = subcommand_usage("[role] [catalog-item-type] [access]")
1413
+ opts.on( '--catalog-item-type ID', String, "Catalog Item Type ID or Name" ) do |val|
1414
+ catalog_item_type_id = val
1415
+ end
1416
+ opts.on( nil, '--all', "Update all catalog item types at once." ) do
1417
+ do_all = true
1418
+ end
1419
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
1420
+ access_value = val
1421
+ end
1422
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1423
+ opts.footer = "Update role access for an catalog item type or all types.\n" +
1424
+ "[role] is required. This is the name or id of a role.\n" +
1425
+ "--catalog-item-type or --all is required. This is the name or id of a catalog item type.\n" +
1426
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1427
+ end
1428
+ optparse.parse!(args)
1429
+
1430
+ # usage: update-catalog_item_type-access [role] [access] --all
1431
+ # update-catalog_item_type-access [role] [catalog-item-type] [access]
1432
+ name = args[0]
1433
+ if do_all
1434
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
1435
+ access_value = args[1] if args[1]
1436
+ else
1437
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
1438
+ catalog_item_type_id = args[1] if args[1]
1439
+ access_value = args[2] if args[2]
1440
+ end
1441
+ if !catalog_item_type_id && !do_all
1442
+ raise_command_error("missing required argument: [catalog-item-type] or --all", optparse)
1443
+ end
1444
+ if !access_value
1445
+ raise_command_error("missing required argument: [access]", optparse)
1446
+ end
1447
+ access_value = access_value.to_s.downcase
1448
+ if !allowed_access_values.include?(access_value)
1449
+ raise_command_error("invalid access value: #{access_value}", optparse)
1450
+ puts optparse
1451
+ return 1
1452
+ end
1453
+
1454
+ connect(options)
1455
+ begin
1456
+ account = find_account_from_options(options)
1457
+ account_id = account ? account['id'] : nil
1458
+ role = find_role_by_name_or_id(account_id, name)
1459
+ return 1 if role.nil?
1460
+
1461
+ role_json = @roles_interface.get(account_id, role['id'])
1462
+ catalog_item_type_global_access = role_json['globalCatalogItemTypeAccess']
1463
+ catalog_item_type_permissions = role_json['catalogItemTypePermissions'] || []
1464
+ if catalog_item_type_global_access != 'custom'
1465
+ print "\n", red, "Global Catalog Item Type Access is currently: #{catalog_item_type_global_access.to_s.capitalize}"
1466
+ print "\n", "You must first set it to Custom via `morpheus roles update-global-catalog-item-type-access \"#{name}\" custom`"
1467
+ print "\n\n", reset
1468
+ return 1
1469
+ end
1470
+
1471
+ # hacky, but support name or code lookup via the list returned in the show payload
1472
+ catalog_item_type = nil
1473
+ if !do_all
1474
+ if catalog_item_type_id.to_s =~ /\A\d{1,}\Z/
1475
+ catalog_item_type = catalog_item_type_permissions.find {|b| b['id'] == catalog_item_type_id.to_i }
1476
+ else
1477
+ catalog_item_type = catalog_item_type_permissions.find {|b| b['name'] == catalog_item_type_id }
1478
+ end
1479
+ if catalog_item_type.nil?
1480
+ print_red_alert "Catalog Item Type not found: '#{catalog_item_type_id}'"
1481
+ return 1
1482
+ end
1483
+ end
1484
+
1485
+ params = {}
1486
+ if do_all
1487
+ params['allCatalogItemTypes'] = true
1488
+ else
1489
+ params['catalogItemTypeId'] = catalog_item_type['id']
1490
+ end
1491
+ params['access'] = access_value
1492
+ @roles_interface.setopts(options)
1493
+ if options[:dry_run]
1494
+ print_dry_run @roles_interface.dry.update_catalog_item_type(account_id, role['id'], params)
1495
+ return
1496
+ end
1497
+ json_response = @roles_interface.update_catalog_item_type(account_id, role['id'], params)
1498
+
1499
+ if options[:json]
1500
+ print JSON.pretty_generate(json_response)
1501
+ print "\n"
1502
+ else
1503
+ if do_all
1504
+ print_green_success "Role #{role['authority']} access updated for all catalog item types"
1505
+ else
1506
+ print_green_success "Role #{role['authority']} access updated for catalog item type #{catalog_item_type['name']}"
1507
+ end
1508
+ end
1509
+ return 0
1510
+ rescue RestClient::Exception => e
1511
+ print_rest_exception(e, options)
1512
+ exit 1
1513
+ end
1514
+ end
1515
+
1516
+ def update_persona_access(args)
1517
+ options = {}
1518
+ persona_id = nil
1519
+ name = nil
1520
+ access_value = nil
1521
+ do_all = false
1522
+ allowed_access_values = ['full', 'none']
1523
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1524
+ opts.banner = subcommand_usage("[role] [persona] [access]")
1525
+ opts.on( '--persona CODE', String, "Persona Code" ) do |val|
1526
+ persona_id = val
1527
+ end
1528
+ opts.on( nil, '--all', "Update all personas at once." ) do
1529
+ do_all = true
1530
+ end
1531
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
1532
+ access_value = val
1533
+ end
1534
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1535
+ opts.footer = "Update role access for a persona or all personas.\n" +
1536
+ "[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" +
1538
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1539
+ end
1540
+ optparse.parse!(args)
1541
+
1542
+ # usage: update-persona-access [role] [access] --all
1543
+ # update-persona-access [role] [persona] [access]
1544
+ name = args[0]
1545
+ if do_all
1546
+ verify_args!(args:args, optparse:optparse, min:1, max:2)
1547
+ access_value = args[1] if args[1]
1548
+ else
1549
+ verify_args!(args:args, optparse:optparse, min:1, max:3)
1550
+ persona_id = args[1] if args[1]
1551
+ access_value = args[2] if args[2]
1552
+ end
1553
+ if !persona_id && !do_all
1554
+ raise_command_error("missing required argument: [persona] or --all", optparse)
1555
+ end
1556
+ if !access_value
1557
+ raise_command_error("missing required argument: [access]", optparse)
1558
+ end
1559
+ access_value = access_value.to_s.downcase
1560
+ if !allowed_access_values.include?(access_value)
1561
+ raise_command_error("invalid access value: #{access_value}", optparse)
1562
+ puts optparse
1563
+ return 1
1564
+ end
1565
+
1566
+ connect(options)
1567
+ begin
1568
+ account = find_account_from_options(options)
1569
+ account_id = account ? account['id'] : nil
1570
+ role = find_role_by_name_or_id(account_id, name)
1571
+ return 1 if role.nil?
1572
+
1573
+ role_json = @roles_interface.get(account_id, role['id'])
1574
+
1575
+ # no lookup right now, pass the code serviceCatalog|standard
1576
+ persona_code = persona_id
1577
+
1578
+ params = {}
1579
+ if do_all
1580
+ params['allPersonas'] = true
1581
+ else
1582
+ params['personaCode'] = persona_code
1583
+ end
1584
+ params['access'] = access_value
1585
+ @roles_interface.setopts(options)
1586
+ if options[:dry_run]
1587
+ print_dry_run @roles_interface.dry.update_persona(account_id, role['id'], params)
1588
+ return
1589
+ end
1590
+ json_response = @roles_interface.update_persona(account_id, role['id'], params)
1591
+
1592
+ if options[:json]
1593
+ print JSON.pretty_generate(json_response)
1594
+ print "\n"
1595
+ else
1596
+ if do_all
1597
+ print_green_success "Role #{role['authority']} access updated for all personas"
1598
+ else
1599
+ print_green_success "Role #{role['authority']} access updated for persona #{persona_code}"
1600
+ end
1601
+ end
1602
+ return 0
1603
+ rescue RestClient::Exception => e
1604
+ print_rest_exception(e, options)
1605
+ exit 1
1606
+ end
1607
+ end
1608
+
1270
1609
  private
1271
1610
 
1272
1611
  def add_role_option_types
1273
1612
  [
1274
- {'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
1275
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
1276
- {'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user', 'displayOrder' => 3},
1277
- {'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4},
1278
- {'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', 'displayOrder' => 5},
1279
- {'fieldName' => 'multitenantLocked', 'fieldLabel' => 'Multitenant Locked', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'Prevents subtenants from branching off this role/modifying it. ', 'displayOrder' => 6}
1613
+ {'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
1614
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
1615
+ {'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user'},
1616
+ {'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text'},
1617
+ {'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
+ {'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'}
1280
1620
  ]
1281
1621
  end
1282
1622