morpheus-cli 4.2.21 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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