morpheus-cli 5.0.0 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Dockerfile +1 -1
  4. data/lib/morpheus/api/api_client.rb +16 -0
  5. data/lib/morpheus/api/billing_interface.rb +1 -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/invoices_interface.rb +12 -3
  11. data/lib/morpheus/api/search_interface.rb +13 -0
  12. data/lib/morpheus/api/servers_interface.rb +14 -0
  13. data/lib/morpheus/api/service_catalog_interface.rb +89 -0
  14. data/lib/morpheus/api/usage_interface.rb +18 -0
  15. data/lib/morpheus/cli.rb +6 -2
  16. data/lib/morpheus/cli/apps.rb +3 -23
  17. data/lib/morpheus/cli/budgets_command.rb +389 -319
  18. data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
  19. data/lib/morpheus/cli/cli_command.rb +51 -10
  20. data/lib/morpheus/cli/commands/standard/curl_command.rb +26 -13
  21. data/lib/morpheus/cli/commands/standard/history_command.rb +9 -3
  22. data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
  23. data/lib/morpheus/cli/containers_command.rb +0 -24
  24. data/lib/morpheus/cli/cypher_command.rb +6 -2
  25. data/lib/morpheus/cli/dashboard_command.rb +260 -20
  26. data/lib/morpheus/cli/deploy.rb +199 -90
  27. data/lib/morpheus/cli/deployments.rb +341 -28
  28. data/lib/morpheus/cli/deploys.rb +206 -41
  29. data/lib/morpheus/cli/error_handler.rb +7 -0
  30. data/lib/morpheus/cli/forgot_password.rb +133 -0
  31. data/lib/morpheus/cli/groups.rb +1 -1
  32. data/lib/morpheus/cli/health_command.rb +59 -2
  33. data/lib/morpheus/cli/hosts.rb +271 -39
  34. data/lib/morpheus/cli/instances.rb +228 -129
  35. data/lib/morpheus/cli/invoices_command.rb +100 -20
  36. data/lib/morpheus/cli/jobs_command.rb +94 -92
  37. data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
  38. data/lib/morpheus/cli/library_option_types_command.rb +10 -5
  39. data/lib/morpheus/cli/logs_command.rb +9 -6
  40. data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
  41. data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -2
  42. data/lib/morpheus/cli/mixins/print_helper.rb +13 -27
  43. data/lib/morpheus/cli/mixins/provisioning_helper.rb +108 -5
  44. data/lib/morpheus/cli/option_types.rb +271 -22
  45. data/lib/morpheus/cli/remote.rb +35 -10
  46. data/lib/morpheus/cli/reports_command.rb +99 -30
  47. data/lib/morpheus/cli/roles.rb +193 -155
  48. data/lib/morpheus/cli/search_command.rb +182 -0
  49. data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
  50. data/lib/morpheus/cli/setup.rb +1 -1
  51. data/lib/morpheus/cli/shell.rb +33 -11
  52. data/lib/morpheus/cli/tasks.rb +29 -32
  53. data/lib/morpheus/cli/usage_command.rb +64 -11
  54. data/lib/morpheus/cli/version.rb +1 -1
  55. data/lib/morpheus/cli/virtual_images.rb +429 -254
  56. data/lib/morpheus/cli/whoami.rb +6 -6
  57. data/lib/morpheus/cli/workflows.rb +33 -40
  58. data/lib/morpheus/formatters.rb +75 -18
  59. data/lib/morpheus/terminal.rb +6 -2
  60. metadata +10 -4
  61. data/lib/morpheus/cli/mixins/catalog_helper.rb +0 -66
@@ -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
@@ -595,7 +597,7 @@ EOT
595
597
  if args.count != 0
596
598
  raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
597
599
  end
598
- connect(options) # needed?
600
+ #connect(options) # needed?
599
601
  _check_all_appliances(options)
600
602
  end
601
603
 
@@ -826,6 +828,12 @@ EOT
826
828
  options[:do_offline] = true
827
829
  end
828
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
829
837
  end
830
838
  optparse.parse!(args)
831
839
  id_list = nil
@@ -843,7 +851,16 @@ EOT
843
851
 
844
852
  def _get(appliance_name, options)
845
853
  exit_code, err = 0, nil
846
-
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
847
864
  appliance = load_remote_by_name(appliance_name)
848
865
  appliance_name = appliance[:name]
849
866
  appliance_url = appliance[:url]
@@ -1039,15 +1056,14 @@ EOT
1039
1056
  end
1040
1057
  build_common_options(opts, options, [:quiet])
1041
1058
  opts.footer = <<-EOT
1042
- [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.
1043
1060
  Start using a remote, making it the active (current) remote appliance.
1044
1061
  This switches the remote context of your client configuration for all subsequent commands.
1045
- So rely on 'remote use' with caution.
1046
1062
  It is important to always be aware of the context your commands are running in.
1047
1063
  The command `remote current` will return the current remote information.
1048
- 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.
1049
1065
 
1050
- 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.
1051
1067
  For example, add the following to your .morpheusrc file:
1052
1068
 
1053
1069
  # set your shell prompt to display the current username and remote
@@ -1155,13 +1171,22 @@ EOT
1155
1171
  end
1156
1172
  optparse.parse!(args)
1157
1173
  verify_args!(args:args, count:0, optparse:optparse)
1158
- 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
1159
1184
 
1160
1185
  # this does the same thing
1161
1186
  #return _get("current", options)
1162
-
1163
- # appliance = load_remote_by_name("current")
1164
- appliance = @remote_appliance
1187
+ appliance = current_appliance
1188
+ #appliance = load_remote_by_name("current")
1189
+ #appliance = @remote_appliance
1165
1190
  exit_code, err = 0, nil
1166
1191
  if appliance.nil?
1167
1192
  raise_command_error "no current remote appliance, see command `remote add`."
@@ -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}"
@@ -211,56 +211,70 @@ EOT
211
211
  print cyan,"Use --permissions to list permissions","\n"
212
212
  end
213
213
 
214
+ has_group_access = true
215
+ has_cloud_access = true
214
216
  print_h2 "Global Access", options
215
- puts as_pretty_table([json_response], [
216
- {"Groups" => lambda {|it| get_access_string(it['globalSiteAccess']) } },
217
- {"Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) } },
218
- {"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) } },
219
- {"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) } },
220
- {"Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) } },
221
- ], options)
222
-
223
- #print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
224
- print cyan
225
- if json_response['globalSiteAccess'] == 'custom'
226
- print_h2 "Group Access", options
227
- if options[:include_group_access]
228
- rows = json_response['sites'].collect do |it|
229
- {
230
- name: it['name'],
231
- access: format_access_string(it['access'], ["none","read","full"]),
232
- }
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"
233
248
  end
234
- print as_pretty_table(rows, [:name, :access], options)
249
+ print reset,"\n"
235
250
  else
236
- 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"
237
253
  end
238
- print reset,"\n"
239
- else
240
- # print "\n"
241
- # print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
242
254
  end
243
255
 
244
- print cyan
245
- #puts "Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}"
246
- #print "\n"
247
- if json_response['globalZoneAccess'] == 'custom'
248
- print_h2 "Cloud Access", options
249
- if options[:include_cloud_access]
250
- rows = json_response['zones'].collect do |it|
251
- {
252
- name: it['name'],
253
- access: format_access_string(it['access'], ["none","read","full"]),
254
- }
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"
255
272
  end
256
- print as_pretty_table(rows, [:name, :access], options)
273
+ print reset,"\n"
257
274
  else
258
- 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"
259
277
  end
260
- print reset,"\n"
261
- else
262
- # print "\n"
263
- # print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
264
278
  end
265
279
 
266
280
  print cyan
@@ -326,7 +340,7 @@ EOT
326
340
  end
327
341
  print as_pretty_table(rows, [:name, :access], options)
328
342
  else
329
- print cyan,"Use -b, --catalog-item-type-access to list custom access","\n"
343
+ print cyan,"Use --catalog-item-type-access to list custom access","\n"
330
344
  end
331
345
  else
332
346
  # print "\n"
@@ -335,7 +349,8 @@ EOT
335
349
 
336
350
 
337
351
  persona_permissions = json_response['personaPermissions'] || json_response['personas'] || []
338
- if options[:include_catalog_item_types_access]
352
+ # if options[:include_personas_access]
353
+ if persona_permissions
339
354
  print_h2 "Persona Access", options
340
355
  rows = persona_permissions.collect do |it|
341
356
  {
@@ -552,7 +567,7 @@ EOT
552
567
  options = {}
553
568
  params = {}
554
569
  optparse = Morpheus::Cli::OptionParser.new do |opts|
555
- opts.banner = subcommand_usage("[name] [options]")
570
+ opts.banner = subcommand_usage("[role] [options]")
556
571
  build_option_type_options(opts, options, update_role_option_types)
557
572
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
558
573
  end
@@ -630,7 +645,7 @@ EOT
630
645
  def remove(args)
631
646
  options = {}
632
647
  optparse = Morpheus::Cli::OptionParser.new do |opts|
633
- opts.banner = subcommand_usage("[name]")
648
+ opts.banner = subcommand_usage("[role]")
634
649
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
635
650
  end
636
651
  optparse.parse!(args)
@@ -770,41 +785,46 @@ EOT
770
785
  group_name = nil
771
786
  access_value = nil
772
787
  do_all = false
788
+ allowed_access_values = ['full', 'read', 'none']
773
789
  optparse = Morpheus::Cli::OptionParser.new do |opts|
774
- opts.banner = subcommand_usage("[name]")
790
+ opts.banner = subcommand_usage("[role] [group] [access]")
775
791
  opts.on( '-g', '--group GROUP', "Group name or id" ) do |val|
776
792
  group_name = val
777
793
  end
778
794
  opts.on( nil, '--all', "Update all groups at once." ) do
779
795
  do_all = true
780
796
  end
781
- 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|
782
798
  access_value = val
783
799
  end
784
800
  build_common_options(opts, options, [:json, :dry_run, :remote])
785
801
  opts.footer = "Update role access for a group or all groups.\n" +
786
- "[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" +
787
803
  "--group or --all is required. This is the name or id of a group.\n" +
788
- "--access is required. This is the new access value."
804
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
789
805
  end
790
806
  optparse.parse!(args)
791
- if args.count < 1
792
- puts optparse
793
- return 1
794
- end
795
- name = args[0]
796
- # support old usage: [name] [group] [access]
797
- group_name ||= args[1]
798
- access_value ||= args[2]
799
807
 
800
- if (!group_name && !do_all) || !access_value
801
- puts optparse
802
- 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)
803
824
  end
804
-
805
825
  access_value = access_value.to_s.downcase
806
-
807
- 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)
808
828
  puts optparse
809
829
  return 1
810
830
  end
@@ -915,6 +935,7 @@ EOT
915
935
  cloud_name = nil
916
936
  access_value = nil
917
937
  do_all = false
938
+ allowed_access_values = ['full', 'read', 'none']
918
939
  optparse = Morpheus::Cli::OptionParser.new do |opts|
919
940
  opts.banner = subcommand_usage("[name]")
920
941
  opts.on( '-c', '--cloud CLOUD', "Cloud name or id" ) do |val|
@@ -924,7 +945,7 @@ EOT
924
945
  opts.on( nil, '--all', "Update all clouds at once." ) do
925
946
  do_all = true
926
947
  end
927
- 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|
928
949
  access_value = val
929
950
  end
930
951
  opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
@@ -932,32 +953,34 @@ EOT
932
953
  end
933
954
  build_common_options(opts, options, [:json, :dry_run, :remote])
934
955
  opts.footer = "Update role access for a cloud or all clouds.\n" +
935
- "[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" +
936
957
  "--cloud or --all is required. This is the name or id of a cloud.\n" +
937
- "--access is required. This is the new access value."
958
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
938
959
  end
939
960
  optparse.parse!(args)
940
961
 
941
- if args.count < 1
942
- puts optparse
943
- return 1
944
- end
962
+ # usage: update-cloud-access [role] [access] --all
963
+ # update-cloud-access [role] [cloud] [access]
945
964
  name = args[0]
946
- # support old usage: [name] [cloud] [access]
947
- cloud_name ||= args[1]
948
- access_value ||= args[2]
949
-
950
- if (!cloud_name && !do_all) || !access_value
951
- puts optparse
952
- 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)
953
978
  end
954
- puts "cloud_name is : #{cloud_name}"
955
- puts "access_value is : #{access_value}"
956
979
  access_value = access_value.to_s.downcase
957
-
958
- if !['full', 'none'].include?(access_value)
980
+ if !allowed_access_values.include?(access_value)
981
+ raise_command_error("invalid access value: #{access_value}", optparse)
959
982
  puts optparse
960
- exit 1
983
+ return 1
961
984
  end
962
985
 
963
986
  connect(options)
@@ -1025,10 +1048,10 @@ EOT
1025
1048
  end
1026
1049
 
1027
1050
  def update_global_instance_type_access(args)
1028
- 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]"
1029
1052
  options = {}
1030
1053
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1031
- opts.banner = subcommand_usage("[name] [full|custom|none]")
1054
+ opts.banner = subcommand_usage("[role] [full|custom|none]")
1032
1055
  build_common_options(opts, options, [:json, :dry_run, :remote])
1033
1056
  end
1034
1057
  optparse.parse!(args)
@@ -1077,22 +1100,23 @@ EOT
1077
1100
  instance_type_name = nil
1078
1101
  access_value = nil
1079
1102
  do_all = false
1103
+ allowed_access_values = ['full', 'none']
1080
1104
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1081
- opts.banner = subcommand_usage("[name]")
1105
+ opts.banner = subcommand_usage("[role] [type] [access]")
1082
1106
  opts.on( '--instance-type INSTANCE_TYPE', String, "Instance Type name" ) do |val|
1083
1107
  instance_type_name = val
1084
1108
  end
1085
1109
  opts.on( nil, '--all', "Update all instance types at once." ) do
1086
1110
  do_all = true
1087
1111
  end
1088
- 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|
1089
1113
  access_value = val
1090
1114
  end
1091
1115
  build_common_options(opts, options, [:json, :dry_run, :remote])
1092
1116
  opts.footer = "Update role access for an instance type or all instance types.\n" +
1093
- "[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" +
1094
1118
  "--instance-type or --all is required. This is the name of an instance type.\n" +
1095
- "--access is required. This is the new access value."
1119
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1096
1120
  end
1097
1121
  optparse.parse!(args)
1098
1122
 
@@ -1101,7 +1125,7 @@ EOT
1101
1125
  return 1
1102
1126
  end
1103
1127
  name = args[0]
1104
- # support old usage: [name] [instance-type] [access]
1128
+ # support old usage: [role] [instance-type] [access]
1105
1129
  instance_type_name ||= args[1]
1106
1130
  access_value ||= args[2]
1107
1131
 
@@ -1170,10 +1194,10 @@ EOT
1170
1194
  end
1171
1195
 
1172
1196
  def update_global_blueprint_access(args)
1173
- 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]"
1174
1198
  options = {}
1175
1199
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1176
- opts.banner = subcommand_usage("[name] [full|custom|none]")
1200
+ opts.banner = subcommand_usage("[role] [full|custom|none]")
1177
1201
  build_common_options(opts, options, [:json, :dry_run, :remote])
1178
1202
  end
1179
1203
  optparse.parse!(args)
@@ -1222,42 +1246,46 @@ EOT
1222
1246
  blueprint_id = nil
1223
1247
  access_value = nil
1224
1248
  do_all = false
1249
+ allowed_access_values = ['full', 'none']
1225
1250
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1226
- opts.banner = subcommand_usage("[name]")
1251
+ opts.banner = subcommand_usage("[role] [blueprint] [access]")
1227
1252
  opts.on( '--blueprint ID', String, "Blueprint ID or Name" ) do |val|
1228
1253
  blueprint_id = val
1229
1254
  end
1230
1255
  opts.on( nil, '--all', "Update all blueprints at once." ) do
1231
1256
  do_all = true
1232
1257
  end
1233
- 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|
1234
1259
  access_value = val
1235
1260
  end
1236
1261
  build_common_options(opts, options, [:json, :dry_run, :remote])
1237
1262
  opts.footer = "Update role access for an blueprint or all blueprints.\n" +
1238
- "[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" +
1239
1264
  "--blueprint or --all is required. This is the name or id of a blueprint.\n" +
1240
- "--access is required. This is the new access value."
1265
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1241
1266
  end
1242
1267
  optparse.parse!(args)
1243
1268
 
1244
- if args.count < 1
1245
- puts optparse
1246
- return 1
1247
- end
1269
+ # usage: update-blueprint-access [role] [access] --all
1270
+ # update-blueprint-access [role] [blueprint] [access]
1248
1271
  name = args[0]
1249
- # support old usage: [name] [blueprint] [access]
1250
- blueprint_id ||= args[1]
1251
- access_value ||= args[2]
1252
-
1253
- if (!blueprint_id && !do_all) || !access_value
1254
- puts_error optparse
1255
- 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)
1256
1285
  end
1257
-
1258
1286
  access_value = access_value.to_s.downcase
1259
-
1260
- if !['full', 'none'].include?(access_value)
1287
+ if !allowed_access_values.include?(access_value)
1288
+ raise_command_error("invalid access value: #{access_value}", optparse)
1261
1289
  puts optparse
1262
1290
  return 1
1263
1291
  end
@@ -1327,10 +1355,10 @@ EOT
1327
1355
  end
1328
1356
 
1329
1357
  def update_global_catalog_item_type_access(args)
1330
- usage = "Usage: morpheus roles update-global-catalog-item-type-access [name] [full|custom|none]"
1358
+ usage = "Usage: morpheus roles update-global-catalog-item-type-access [role] [full|custom|none]"
1331
1359
  options = {}
1332
1360
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1333
- opts.banner = subcommand_usage("[name] [full|custom|none]")
1361
+ opts.banner = subcommand_usage("[role] [full|custom|none]")
1334
1362
  build_common_options(opts, options, [:json, :dry_run, :remote])
1335
1363
  end
1336
1364
  optparse.parse!(args)
@@ -1379,42 +1407,46 @@ EOT
1379
1407
  catalog_item_type_id = nil
1380
1408
  access_value = nil
1381
1409
  do_all = false
1410
+ allowed_access_values = ['full', 'none']
1382
1411
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1383
- opts.banner = subcommand_usage("[name]")
1412
+ opts.banner = subcommand_usage("[role] [catalog-item-type] [access]")
1384
1413
  opts.on( '--catalog-item-type ID', String, "Catalog Item Type ID or Name" ) do |val|
1385
1414
  catalog_item_type_id = val
1386
1415
  end
1387
1416
  opts.on( nil, '--all', "Update all catalog item types at once." ) do
1388
1417
  do_all = true
1389
1418
  end
1390
- opts.on( '--access VALUE', String, "Access value [full|none]" ) do |val|
1419
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
1391
1420
  access_value = val
1392
1421
  end
1393
1422
  build_common_options(opts, options, [:json, :dry_run, :remote])
1394
1423
  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" +
1424
+ "[role] is required. This is the name or id of a role.\n" +
1396
1425
  "--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."
1426
+ "--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
1398
1427
  end
1399
1428
  optparse.parse!(args)
1400
1429
 
1401
- if args.count < 1
1402
- puts optparse
1403
- return 1
1404
- end
1430
+ # usage: update-catalog_item_type-access [role] [access] --all
1431
+ # update-catalog_item_type-access [role] [catalog-item-type] [access]
1405
1432
  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
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)
1413
1446
  end
1414
-
1415
1447
  access_value = access_value.to_s.downcase
1416
-
1417
- if !['full', 'none'].include?(access_value)
1448
+ if !allowed_access_values.include?(access_value)
1449
+ raise_command_error("invalid access value: #{access_value}", optparse)
1418
1450
  puts optparse
1419
1451
  return 1
1420
1452
  end
@@ -1484,44 +1516,49 @@ EOT
1484
1516
  def update_persona_access(args)
1485
1517
  options = {}
1486
1518
  persona_id = nil
1519
+ name = nil
1487
1520
  access_value = nil
1488
1521
  do_all = false
1522
+ allowed_access_values = ['full', 'none']
1489
1523
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1490
- opts.banner = subcommand_usage("[name] [serviceCatalog|standard]")
1524
+ opts.banner = subcommand_usage("[role] [persona] [access]")
1491
1525
  opts.on( '--persona CODE', String, "Persona Code" ) do |val|
1492
1526
  persona_id = val
1493
1527
  end
1494
1528
  opts.on( nil, '--all', "Update all personas at once." ) do
1495
1529
  do_all = true
1496
1530
  end
1497
- opts.on( '--access VALUE', String, "Access value [full|none]" ) do |val|
1531
+ opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
1498
1532
  access_value = val
1499
1533
  end
1500
1534
  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."
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)}"
1505
1539
  end
1506
1540
  optparse.parse!(args)
1507
1541
 
1508
- if args.count < 1
1509
- puts optparse
1510
- return 1
1511
- end
1542
+ # usage: update-persona-access [role] [access] --all
1543
+ # update-persona-access [role] [persona] [access]
1512
1544
  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
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)
1520
1558
  end
1521
-
1522
1559
  access_value = access_value.to_s.downcase
1523
-
1524
- if !['full', 'none'].include?(access_value)
1560
+ if !allowed_access_values.include?(access_value)
1561
+ raise_command_error("invalid access value: #{access_value}", optparse)
1525
1562
  puts optparse
1526
1563
  return 1
1527
1564
  end
@@ -1573,12 +1610,13 @@ EOT
1573
1610
 
1574
1611
  def add_role_option_types
1575
1612
  [
1576
- {'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
1577
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
1578
- {'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user', 'displayOrder' => 3},
1579
- {'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4},
1580
- {'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},
1581
- {'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'}
1582
1620
  ]
1583
1621
  end
1584
1622