morpheus-cli 4.2.20 → 5.0.2

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 +26 -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 +7 -0
  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 +7 -0
  14. data/lib/morpheus/api/usage_interface.rb +18 -0
  15. data/lib/morpheus/cli.rb +6 -3
  16. data/lib/morpheus/cli/apps.rb +3 -4
  17. data/lib/morpheus/cli/backup_jobs_command.rb +3 -0
  18. data/lib/morpheus/cli/backups_command.rb +3 -0
  19. data/lib/morpheus/cli/budgets_command.rb +4 -4
  20. data/lib/morpheus/cli/catalog_command.rb +507 -0
  21. data/lib/morpheus/cli/cli_command.rb +45 -20
  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 -0
  28. data/lib/morpheus/cli/deploy.rb +199 -90
  29. data/lib/morpheus/cli/deployments.rb +342 -29
  30. data/lib/morpheus/cli/deploys.rb +206 -41
  31. data/lib/morpheus/cli/error_handler.rb +7 -0
  32. data/lib/morpheus/cli/forgot_password.rb +133 -0
  33. data/lib/morpheus/cli/groups.rb +1 -1
  34. data/lib/morpheus/cli/health_command.rb +2 -2
  35. data/lib/morpheus/cli/hosts.rb +181 -26
  36. data/lib/morpheus/cli/instances.rb +102 -33
  37. data/lib/morpheus/cli/invoices_command.rb +33 -16
  38. data/lib/morpheus/cli/jobs_command.rb +28 -6
  39. data/lib/morpheus/cli/library_option_lists_command.rb +14 -6
  40. data/lib/morpheus/cli/logs_command.rb +9 -6
  41. data/lib/morpheus/cli/mixins/accounts_helper.rb +7 -6
  42. data/lib/morpheus/cli/mixins/backups_helper.rb +2 -4
  43. data/lib/morpheus/cli/mixins/catalog_helper.rb +66 -0
  44. data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -3
  45. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  46. data/lib/morpheus/cli/mixins/print_helper.rb +46 -21
  47. data/lib/morpheus/cli/mixins/provisioning_helper.rb +24 -4
  48. data/lib/morpheus/cli/network_pools_command.rb +14 -6
  49. data/lib/morpheus/cli/option_types.rb +266 -17
  50. data/lib/morpheus/cli/ping.rb +0 -1
  51. data/lib/morpheus/cli/provisioning_licenses_command.rb +2 -2
  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 +305 -3
  55. data/lib/morpheus/cli/search_command.rb +182 -0
  56. data/lib/morpheus/cli/service_plans_command.rb +2 -2
  57. data/lib/morpheus/cli/setup.rb +1 -1
  58. data/lib/morpheus/cli/shell.rb +33 -11
  59. data/lib/morpheus/cli/storage_providers_command.rb +40 -56
  60. data/lib/morpheus/cli/tasks.rb +20 -21
  61. data/lib/morpheus/cli/tenants_command.rb +1 -1
  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 +280 -199
  67. data/lib/morpheus/cli/whoami.rb +6 -6
  68. data/lib/morpheus/cli/workflows.rb +34 -41
  69. data/lib/morpheus/formatters.rb +48 -5
  70. data/lib/morpheus/terminal.rb +6 -2
  71. metadata +13 -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
  }
@@ -478,7 +478,7 @@ class Morpheus::Cli::ProvisioningLicensesCommand
478
478
 
479
479
  def add_license_option_types
480
480
  [
481
- {'fieldName' => 'licenseType', 'fieldLabel' => 'License Type', 'type' => 'select', 'optionSource' => lambda {
481
+ {'fieldName' => 'licenseType', 'fieldLabel' => 'License Type', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
482
482
  # @options_interface.options_for_source("licenseTypes", {})['data']
483
483
  get_license_types_dropdown()
484
484
  }, 'required' => true, 'displayOrder' => 1},
@@ -493,7 +493,7 @@ class Morpheus::Cli::ProvisioningLicensesCommand
493
493
  # @options_interface.options_for_source("virtualImages", {})['data']
494
494
  get_virtual_images_dropdown()
495
495
  }, 'displayOrder' => 9},
496
- {'fieldName' => 'tenants', 'fieldLabel' => 'Tenants', 'type' => 'multiSelect', 'optionSource' => lambda {
496
+ {'fieldName' => 'tenants', 'fieldLabel' => 'Tenants', 'type' => 'multiSelect', 'optionSource' => lambda { |api_client, api_params|
497
497
  @options_interface.options_for_source("allTenants", {})['data']
498
498
  }, 'displayOrder' => 10},
499
499
  ]
@@ -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,6 +206,7 @@ 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
@@ -208,6 +217,7 @@ EOT
208
217
  {"Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) } },
209
218
  {"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) } },
210
219
  {"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) } },
220
+ {"Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) } },
211
221
  ], options)
212
222
 
213
223
  #print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
@@ -225,6 +235,7 @@ EOT
225
235
  else
226
236
  print cyan,"Use -g, --group-access to list custom access","\n"
227
237
  end
238
+ print reset,"\n"
228
239
  else
229
240
  # print "\n"
230
241
  # print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
@@ -246,6 +257,7 @@ EOT
246
257
  else
247
258
  print cyan,"Use -c, --cloud-access to list custom access","\n"
248
259
  end
260
+ print reset,"\n"
249
261
  else
250
262
  # print "\n"
251
263
  # print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
@@ -267,6 +279,7 @@ EOT
267
279
  else
268
280
  print cyan,"Use -i, --instance-type-access to list custom access","\n"
269
281
  end
282
+ print reset,"\n"
270
283
  else
271
284
  # print "\n"
272
285
  # print cyan,bold,"Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}",reset,"\n"
@@ -290,12 +303,54 @@ EOT
290
303
  else
291
304
  print cyan,"Use -b, --blueprint-access to list custom access","\n"
292
305
  end
306
+ print reset,"\n"
293
307
  else
294
308
  # print "\n"
295
309
  # print cyan,bold,"Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}",reset,"\n"
296
310
  end
297
- print reset,"\n"
311
+
312
+
313
+ catalog_item_type_global_access = json_response['globalCatalogItemTypeAccess']
314
+ catalog_item_type_permissions = json_response['catalogItemTypePermissions'] || []
315
+ print cyan
316
+ # print_h2 "catalog_item_type Access: #{get_access_string(json_response['globalCatalogItemTypeAccess'])}", options
317
+ # print "\n"
318
+ if catalog_item_type_global_access == 'custom'
319
+ print_h2 "Catalog Item Type Access", options
320
+ if options[:include_catalog_item_types_access]
321
+ rows = catalog_item_type_permissions.collect do |it|
322
+ {
323
+ name: it['name'],
324
+ access: format_access_string(it['access'], ["none","read","full"]),
325
+ }
326
+ end
327
+ print as_pretty_table(rows, [:name, :access], options)
328
+ else
329
+ print cyan,"Use -b, --catalog-item-type-access to list custom access","\n"
330
+ end
331
+ else
332
+ # print "\n"
333
+ # print cyan,bold,"Catalog Item Type Access: #{get_access_string(json_response['globalCatalogItemTypeAccess'])}",reset,"\n"
334
+ end
335
+
336
+
337
+ persona_permissions = json_response['personaPermissions'] || json_response['personas'] || []
338
+ if options[:include_catalog_item_types_access]
339
+ print_h2 "Persona Access", options
340
+ rows = persona_permissions.collect do |it|
341
+ {
342
+ name: it['name'],
343
+ access: format_access_string(it['access'], ["none","read","full"]),
344
+ }
345
+ end
346
+ print as_pretty_table(rows, [:name, :access], options)
347
+ print reset,"\n"
348
+ end
349
+
350
+ # print reset,"\n"
351
+
298
352
  end
353
+
299
354
  return 0, nil
300
355
  end
301
356
 
@@ -449,6 +504,10 @@ EOT
449
504
  end
450
505
  end
451
506
 
507
+ # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'optionSource' => 'personas', 'description' => 'Default Persona'}], options[:options], @api_client)
508
+ 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)
509
+ role_payload['defaultPersona'] = {'code' => v_prompt['defaultPersona']} unless v_prompt['defaultPersona'].to_s.strip.empty?
510
+
452
511
  payload = {"role" => role_payload}
453
512
  end
454
513
  @roles_interface.setopts(options)
@@ -1267,6 +1326,249 @@ EOT
1267
1326
  end
1268
1327
  end
1269
1328
 
1329
+ def update_global_catalog_item_type_access(args)
1330
+ usage = "Usage: morpheus roles update-global-catalog-item-type-access [name] [full|custom|none]"
1331
+ options = {}
1332
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1333
+ opts.banner = subcommand_usage("[name] [full|custom|none]")
1334
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1335
+ end
1336
+ optparse.parse!(args)
1337
+
1338
+ if args.count < 2
1339
+ puts optparse
1340
+ exit 1
1341
+ end
1342
+ name = args[0]
1343
+ access_value = args[1].to_s.downcase
1344
+ if !['full', 'custom', 'none'].include?(access_value)
1345
+ puts optparse
1346
+ exit 1
1347
+ end
1348
+
1349
+
1350
+ connect(options)
1351
+ begin
1352
+ account = find_account_from_options(options)
1353
+ account_id = account ? account['id'] : nil
1354
+ role = find_role_by_name_or_id(account_id, name)
1355
+ exit 1 if role.nil?
1356
+
1357
+ params = {permissionCode: 'CatalogItemType', access: access_value}
1358
+ @roles_interface.setopts(options)
1359
+ if options[:dry_run]
1360
+ print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
1361
+ return
1362
+ end
1363
+ json_response = @roles_interface.update_permission(account_id, role['id'], params)
1364
+
1365
+ if options[:json]
1366
+ print JSON.pretty_generate(json_response)
1367
+ print "\n"
1368
+ else
1369
+ print_green_success "Role #{role['authority']} global catalog item type access updated"
1370
+ end
1371
+ rescue RestClient::Exception => e
1372
+ print_rest_exception(e, options)
1373
+ exit 1
1374
+ end
1375
+ end
1376
+
1377
+ def update_catalog_item_type_access(args)
1378
+ options = {}
1379
+ catalog_item_type_id = nil
1380
+ access_value = nil
1381
+ do_all = false
1382
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1383
+ opts.banner = subcommand_usage("[name]")
1384
+ opts.on( '--catalog-item-type ID', String, "Catalog Item Type ID or Name" ) do |val|
1385
+ catalog_item_type_id = val
1386
+ end
1387
+ opts.on( nil, '--all', "Update all catalog item types at once." ) do
1388
+ do_all = true
1389
+ end
1390
+ opts.on( '--access VALUE', String, "Access value [full|none]" ) do |val|
1391
+ access_value = val
1392
+ end
1393
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1394
+ opts.footer = "Update role access for an catalog item type or all types.\n" +
1395
+ "[name] is required. This is the name or id of a role.\n" +
1396
+ "--catalog-item-type or --all is required. This is the name or id of a catalog item type.\n" +
1397
+ "--access is required. This is the new access value."
1398
+ end
1399
+ optparse.parse!(args)
1400
+
1401
+ if args.count < 1
1402
+ puts optparse
1403
+ return 1
1404
+ end
1405
+ name = args[0]
1406
+ # support old usage: [name] [catalog_item_type] [access]
1407
+ catalog_item_type_id ||= args[1]
1408
+ access_value ||= args[2]
1409
+
1410
+ if (!catalog_item_type_id && !do_all) || !access_value
1411
+ puts_error optparse
1412
+ return 1
1413
+ end
1414
+
1415
+ access_value = access_value.to_s.downcase
1416
+
1417
+ if !['full', 'none'].include?(access_value)
1418
+ puts optparse
1419
+ return 1
1420
+ end
1421
+
1422
+ connect(options)
1423
+ begin
1424
+ account = find_account_from_options(options)
1425
+ account_id = account ? account['id'] : nil
1426
+ role = find_role_by_name_or_id(account_id, name)
1427
+ return 1 if role.nil?
1428
+
1429
+ role_json = @roles_interface.get(account_id, role['id'])
1430
+ catalog_item_type_global_access = role_json['globalCatalogItemTypeAccess']
1431
+ catalog_item_type_permissions = role_json['catalogItemTypePermissions'] || []
1432
+ if catalog_item_type_global_access != 'custom'
1433
+ print "\n", red, "Global Catalog Item Type Access is currently: #{catalog_item_type_global_access.to_s.capitalize}"
1434
+ print "\n", "You must first set it to Custom via `morpheus roles update-global-catalog-item-type-access \"#{name}\" custom`"
1435
+ print "\n\n", reset
1436
+ return 1
1437
+ end
1438
+
1439
+ # hacky, but support name or code lookup via the list returned in the show payload
1440
+ catalog_item_type = nil
1441
+ if !do_all
1442
+ if catalog_item_type_id.to_s =~ /\A\d{1,}\Z/
1443
+ catalog_item_type = catalog_item_type_permissions.find {|b| b['id'] == catalog_item_type_id.to_i }
1444
+ else
1445
+ catalog_item_type = catalog_item_type_permissions.find {|b| b['name'] == catalog_item_type_id }
1446
+ end
1447
+ if catalog_item_type.nil?
1448
+ print_red_alert "Catalog Item Type not found: '#{catalog_item_type_id}'"
1449
+ return 1
1450
+ end
1451
+ end
1452
+
1453
+ params = {}
1454
+ if do_all
1455
+ params['allCatalogItemTypes'] = true
1456
+ else
1457
+ params['catalogItemTypeId'] = catalog_item_type['id']
1458
+ end
1459
+ params['access'] = access_value
1460
+ @roles_interface.setopts(options)
1461
+ if options[:dry_run]
1462
+ print_dry_run @roles_interface.dry.update_catalog_item_type(account_id, role['id'], params)
1463
+ return
1464
+ end
1465
+ json_response = @roles_interface.update_catalog_item_type(account_id, role['id'], params)
1466
+
1467
+ if options[:json]
1468
+ print JSON.pretty_generate(json_response)
1469
+ print "\n"
1470
+ else
1471
+ if do_all
1472
+ print_green_success "Role #{role['authority']} access updated for all catalog item types"
1473
+ else
1474
+ print_green_success "Role #{role['authority']} access updated for catalog item type #{catalog_item_type['name']}"
1475
+ end
1476
+ end
1477
+ return 0
1478
+ rescue RestClient::Exception => e
1479
+ print_rest_exception(e, options)
1480
+ exit 1
1481
+ end
1482
+ end
1483
+
1484
+ def update_persona_access(args)
1485
+ options = {}
1486
+ persona_id = nil
1487
+ access_value = nil
1488
+ do_all = false
1489
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
1490
+ opts.banner = subcommand_usage("[name] [serviceCatalog|standard]")
1491
+ opts.on( '--persona CODE', String, "Persona Code" ) do |val|
1492
+ persona_id = val
1493
+ end
1494
+ opts.on( nil, '--all', "Update all personas at once." ) do
1495
+ do_all = true
1496
+ end
1497
+ opts.on( '--access VALUE', String, "Access value [full|none]" ) do |val|
1498
+ access_value = val
1499
+ end
1500
+ build_common_options(opts, options, [:json, :dry_run, :remote])
1501
+ opts.footer = "Update role access for an persona or personas.\n" +
1502
+ "[name] is required. This is the name or id of a role.\n" +
1503
+ "--persona or --all is required. This is the code of a persona.\n" +
1504
+ "--access is required. This is the new access value."
1505
+ end
1506
+ optparse.parse!(args)
1507
+
1508
+ if args.count < 1
1509
+ puts optparse
1510
+ return 1
1511
+ end
1512
+ name = args[0]
1513
+ # support old usage: [name] [persona] [access]
1514
+ persona_id ||= args[1]
1515
+ access_value ||= args[2]
1516
+
1517
+ if (!persona_id && !do_all) || !access_value
1518
+ puts_error optparse
1519
+ return 1
1520
+ end
1521
+
1522
+ access_value = access_value.to_s.downcase
1523
+
1524
+ if !['full', 'none'].include?(access_value)
1525
+ puts optparse
1526
+ return 1
1527
+ end
1528
+
1529
+ connect(options)
1530
+ begin
1531
+ account = find_account_from_options(options)
1532
+ account_id = account ? account['id'] : nil
1533
+ role = find_role_by_name_or_id(account_id, name)
1534
+ return 1 if role.nil?
1535
+
1536
+ role_json = @roles_interface.get(account_id, role['id'])
1537
+
1538
+ # no lookup right now, pass the code serviceCatalog|standard
1539
+ persona_code = persona_id
1540
+
1541
+ params = {}
1542
+ if do_all
1543
+ params['allPersonas'] = true
1544
+ else
1545
+ params['personaCode'] = persona_code
1546
+ end
1547
+ params['access'] = access_value
1548
+ @roles_interface.setopts(options)
1549
+ if options[:dry_run]
1550
+ print_dry_run @roles_interface.dry.update_persona(account_id, role['id'], params)
1551
+ return
1552
+ end
1553
+ json_response = @roles_interface.update_persona(account_id, role['id'], params)
1554
+
1555
+ if options[:json]
1556
+ print JSON.pretty_generate(json_response)
1557
+ print "\n"
1558
+ else
1559
+ if do_all
1560
+ print_green_success "Role #{role['authority']} access updated for all personas"
1561
+ else
1562
+ print_green_success "Role #{role['authority']} access updated for persona #{persona_code}"
1563
+ end
1564
+ end
1565
+ return 0
1566
+ rescue RestClient::Exception => e
1567
+ print_rest_exception(e, options)
1568
+ exit 1
1569
+ end
1570
+ end
1571
+
1270
1572
  private
1271
1573
 
1272
1574
  def add_role_option_types