morpheus-cli 4.2.8 → 4.2.10

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api.rb +1 -1
  4. data/lib/morpheus/api/activity_interface.rb +9 -0
  5. data/lib/morpheus/api/api_client.rb +83 -27
  6. data/lib/morpheus/api/apps_interface.rb +21 -0
  7. data/lib/morpheus/api/dashboard_interface.rb +5 -21
  8. data/lib/morpheus/api/instances_interface.rb +3 -10
  9. data/lib/morpheus/api/invoice_line_items_interface.rb +14 -0
  10. data/lib/morpheus/api/invoices_interface.rb +7 -12
  11. data/lib/morpheus/api/library_layouts_interface.rb +8 -0
  12. data/lib/morpheus/api/ping_interface.rb +20 -0
  13. data/lib/morpheus/api/projects_interface.rb +33 -0
  14. data/lib/morpheus/api/setup_interface.rb +19 -36
  15. data/lib/morpheus/api/user_settings_interface.rb +0 -6
  16. data/lib/morpheus/api/whoami_interface.rb +4 -8
  17. data/lib/morpheus/benchmarking.rb +16 -26
  18. data/lib/morpheus/cli.rb +10 -5
  19. data/lib/morpheus/cli/access_token_command.rb +5 -8
  20. data/lib/morpheus/cli/activity_command.rb +146 -0
  21. data/lib/morpheus/cli/apps.rb +312 -121
  22. data/lib/morpheus/cli/archives_command.rb +1 -1
  23. data/lib/morpheus/cli/auth_command.rb +4 -11
  24. data/lib/morpheus/cli/blueprints_command.rb +196 -137
  25. data/lib/morpheus/cli/change_password_command.rb +1 -1
  26. data/lib/morpheus/cli/cli_command.rb +225 -72
  27. data/lib/morpheus/cli/cli_registry.rb +2 -2
  28. data/lib/morpheus/cli/cloud_datastores_command.rb +1 -1
  29. data/lib/morpheus/cli/clouds.rb +5 -20
  30. data/lib/morpheus/cli/clusters.rb +4 -28
  31. data/lib/morpheus/cli/commands/standard/alias_command.rb +2 -9
  32. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +2 -0
  33. data/lib/morpheus/cli/commands/standard/curl_command.rb +2 -3
  34. data/lib/morpheus/cli/commands/standard/history_command.rb +3 -6
  35. data/lib/morpheus/cli/commands/standard/man_command.rb +10 -7
  36. data/lib/morpheus/cli/commands/standard/ssl_verification_command.rb +10 -9
  37. data/lib/morpheus/cli/containers_command.rb +3 -3
  38. data/lib/morpheus/cli/credentials.rb +13 -16
  39. data/lib/morpheus/cli/error_handler.rb +18 -12
  40. data/lib/morpheus/cli/errors.rb +45 -0
  41. data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
  42. data/lib/morpheus/cli/execution_request_command.rb +4 -4
  43. data/lib/morpheus/cli/groups.rb +84 -132
  44. data/lib/morpheus/cli/hosts.rb +6 -16
  45. data/lib/morpheus/cli/instances.rb +100 -183
  46. data/lib/morpheus/cli/invoices_command.rb +505 -71
  47. data/lib/morpheus/cli/library_layouts_command.rb +254 -166
  48. data/lib/morpheus/cli/library_option_lists_command.rb +0 -87
  49. data/lib/morpheus/cli/library_option_types_command.rb +0 -96
  50. data/lib/morpheus/cli/license.rb +3 -0
  51. data/lib/morpheus/cli/login.rb +17 -37
  52. data/lib/morpheus/cli/logout.rb +9 -5
  53. data/lib/morpheus/cli/mixins/accounts_helper.rb +83 -7
  54. data/lib/morpheus/cli/mixins/operations_helper.rb +41 -0
  55. data/lib/morpheus/cli/mixins/option_source_helper.rb +255 -0
  56. data/lib/morpheus/cli/mixins/print_helper.rb +18 -4
  57. data/lib/morpheus/cli/mixins/provisioning_helper.rb +222 -13
  58. data/lib/morpheus/cli/mixins/remote_helper.rb +139 -0
  59. data/lib/morpheus/cli/monitoring_checks_command.rb +11 -3
  60. data/lib/morpheus/cli/network_groups_command.rb +8 -2
  61. data/lib/morpheus/cli/option_types.rb +1 -1
  62. data/lib/morpheus/cli/ping.rb +252 -0
  63. data/lib/morpheus/cli/price_sets_command.rb +16 -27
  64. data/lib/morpheus/cli/prices_command.rb +34 -27
  65. data/lib/morpheus/cli/processes_command.rb +81 -7
  66. data/lib/morpheus/cli/projects_command.rb +607 -0
  67. data/lib/morpheus/cli/recent_activity_command.rb +87 -65
  68. data/lib/morpheus/cli/remote.rb +965 -974
  69. data/lib/morpheus/cli/reports_command.rb +3 -15
  70. data/lib/morpheus/cli/roles.rb +8 -31
  71. data/lib/morpheus/cli/service_plans_command.rb +25 -31
  72. data/lib/morpheus/cli/setup.rb +392 -0
  73. data/lib/morpheus/cli/shell.rb +144 -56
  74. data/lib/morpheus/cli/subnets_command.rb +71 -11
  75. data/lib/morpheus/cli/tasks.rb +3 -3
  76. data/lib/morpheus/cli/user_sources_command.rb +4 -4
  77. data/lib/morpheus/cli/users.rb +135 -109
  78. data/lib/morpheus/cli/version.rb +1 -1
  79. data/lib/morpheus/cli/whitelabel_settings_command.rb +7 -7
  80. data/lib/morpheus/cli/whoami.rb +90 -129
  81. data/lib/morpheus/cli/wiki_command.rb +2 -14
  82. data/lib/morpheus/ext/rest_client.rb +36 -0
  83. data/lib/morpheus/formatters.rb +42 -5
  84. data/lib/morpheus/rest_client.rb +0 -10
  85. data/lib/morpheus/terminal.rb +41 -1
  86. data/lib/morpheus/util.rb +24 -0
  87. metadata +16 -3
  88. data/lib/morpheus/cli/command_error.rb +0 -22
@@ -355,93 +355,6 @@ class Morpheus::Cli::LibraryOptionListsCommand
355
355
 
356
356
  private
357
357
 
358
- def find_instance_type_by_name_or_id(val)
359
- if val.to_s =~ /\A\d{1,}\Z/
360
- return find_instance_type_by_id(val)
361
- else
362
- return find_instance_type_by_name(val)
363
- end
364
- end
365
-
366
- def find_instance_type_by_id(id)
367
- begin
368
- json_response = @library_instance_types_interface.get(id.to_i)
369
- return json_response['instanceType']
370
- rescue RestClient::Exception => e
371
- if e.response && e.response.code == 404
372
- print_red_alert "Instance Type not found by id #{id}"
373
- else
374
- raise e
375
- end
376
- end
377
- end
378
-
379
- def find_instance_type_by_name(name)
380
- json_response = @library_instance_types_interface.list({name: name.to_s})
381
- instance_types = json_response['instanceTypes']
382
- if instance_types.empty?
383
- print_red_alert "Instance Type not found by name #{name}"
384
- return nil
385
- elsif instance_types.size > 1
386
- print_red_alert "#{instance_types.size} instance types found by name #{name}"
387
- print_instance_types_table(instance_types, {color: red})
388
- print_red_alert "Try using ID instead"
389
- print reset,"\n"
390
- return nil
391
- else
392
- return instance_types[0]
393
- end
394
- end
395
-
396
- def print_instance_types_table(instance_types, opts={})
397
- columns = [
398
- {"ID" => lambda {|instance_type| instance_type['id'] } },
399
- {"NAME" => lambda {|instance_type| instance_type['name'] } },
400
- {"CODE" => lambda {|instance_type| instance_type['code'] } },
401
- {"TECHNOLOGY" => lambda {|instance_type| format_instance_type_technology(instance_type) } },
402
- {"CATEGORY" => lambda {|instance_type| instance_type['category'].to_s.capitalize } },
403
- {"FEATURED" => lambda {|instance_type| format_boolean instance_type['featured'] } },
404
- {"OWNER" => lambda {|instance_type| instance_type['account'] ? instance_type['account']['name'] : '' } },
405
- ]
406
- if opts[:include_fields]
407
- columns = opts[:include_fields]
408
- end
409
- print as_pretty_table(instance_types, columns, opts)
410
- end
411
-
412
- def format_instance_type_technology(instance_type)
413
- if instance_type
414
- instance_type['provisionTypeCode'].to_s.capitalize
415
- else
416
- ""
417
- end
418
- end
419
-
420
- def add_instance_type_option_types
421
- [
422
- {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
423
- {'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => true, 'displayOrder' => 2, 'description' => 'Useful shortcode for provisioning naming schemes and export reference.'},
424
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 3},
425
- {'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'select', 'optionSource' => 'categories', 'required' => true, 'displayOrder' => 4},
426
- {'fieldName' => 'logo', 'fieldLabel' => 'Icon File', 'type' => 'text', 'displayOrder' => 5},
427
- {'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'displayOrder' => 6},
428
- {'fieldName' => 'environmentPrefix', 'fieldLabel' => 'Environment Prefix', 'type' => 'text', 'displayOrder' => 7, 'description' => 'Used for exportable environment variables when tying instance types together in app contexts. If not specified a name will be generated.'},
429
- {'fieldName' => 'hasSettings', 'fieldLabel' => 'Enable Settings', 'type' => 'checkbox', 'displayOrder' => 8},
430
- {'fieldName' => 'hasAutoScale', 'fieldLabel' => 'Enable Scaling (Horizontal)', 'type' => 'checkbox', 'displayOrder' => 9},
431
- {'fieldName' => 'hasDeployment', 'fieldLabel' => 'Supports Deployments', 'type' => 'checkbox', 'displayOrder' => 10, 'description' => 'Requires a data volume be configured on each version. Files will be copied into this location.'}
432
- ]
433
- end
434
-
435
- def update_instance_type_option_types(instance_type=nil)
436
- opts = add_instance_type_option_types
437
- opts = opts.reject {|it| ["logo"].include? it['fieldName'] }
438
- if instance_type
439
- opts = add_instance_type_option_types
440
- opts.find {|opt| opt['fieldName'] == 'name'}['defaultValue'] = instance_type['name']
441
- end
442
- opts
443
- end
444
-
445
358
  def find_option_type_list_by_name_or_id(val)
446
359
  if val.to_s =~ /\A\d{1,}\Z/
447
360
  return find_option_type_list_by_id(val)
@@ -289,102 +289,6 @@ class Morpheus::Cli::LibraryOptionTypesCommand
289
289
 
290
290
  private
291
291
 
292
- def find_instance_type_by_name_or_id(val)
293
- if val.to_s =~ /\A\d{1,}\Z/
294
- return find_instance_type_by_id(val)
295
- else
296
- return find_instance_type_by_name(val)
297
- end
298
- end
299
-
300
- def find_instance_type_by_id(id)
301
- begin
302
- json_response = @library_instance_types_interface.get(id.to_i)
303
- return json_response['instanceType']
304
- rescue RestClient::Exception => e
305
- if e.response && e.response.code == 404
306
- print_red_alert "Instance Type not found by id #{id}"
307
- else
308
- raise e
309
- end
310
- end
311
- end
312
-
313
- def find_instance_type_by_name(name)
314
- json_response = @library_instance_types_interface.list({name: name.to_s})
315
- instance_types = json_response['instanceTypes']
316
- if instance_types.empty?
317
- print_red_alert "Instance Type not found by name #{name}"
318
- return nil
319
- elsif instance_types.size > 1
320
- print_red_alert "#{instance_types.size} instance types found by name #{name}"
321
- print_instance_types_table(instance_types, {color: red})
322
- print_red_alert "Try using ID instead"
323
- print reset,"\n"
324
- return nil
325
- else
326
- return instance_types[0]
327
- end
328
- end
329
-
330
- def print_instance_types_table(instance_types, opts={})
331
- columns = [
332
- {"ID" => lambda {|instance_type| instance_type['id'] } },
333
- {"NAME" => lambda {|instance_type| instance_type['name'] } },
334
- {"CODE" => lambda {|instance_type| instance_type['code'] } },
335
- {"TECHNOLOGY" => lambda {|instance_type| format_instance_type_technology(instance_type) } },
336
- {"CATEGORY" => lambda {|instance_type| instance_type['category'].to_s.capitalize } },
337
- {"FEATURED" => lambda {|instance_type| format_boolean instance_type['featured'] } },
338
- {"OWNER" => lambda {|instance_type| instance_type['account'] ? instance_type['account']['name'] : '' } },
339
- ]
340
- if opts[:include_fields]
341
- columns = opts[:include_fields]
342
- end
343
- print as_pretty_table(instance_types, columns, opts)
344
- end
345
-
346
- def format_instance_type_technology(instance_type)
347
- if instance_type
348
- instance_type['provisionTypeCode'].to_s.capitalize
349
- else
350
- ""
351
- end
352
- end
353
-
354
- def add_instance_type_option_types
355
- [
356
- {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
357
- {'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => true, 'displayOrder' => 2, 'description' => 'Useful shortcode for provisioning naming schemes and export reference.'},
358
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 3},
359
- {'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'select', 'optionSource' => 'categories', 'required' => true, 'displayOrder' => 4},
360
- {'fieldName' => 'logo', 'fieldLabel' => 'Icon File', 'type' => 'text', 'displayOrder' => 5},
361
- {'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'displayOrder' => 6},
362
- {'fieldName' => 'environmentPrefix', 'fieldLabel' => 'Environment Prefix', 'type' => 'text', 'displayOrder' => 7, 'description' => 'Used for exportable environment variables when tying instance types together in app contexts. If not specified a name will be generated.'},
363
- {'fieldName' => 'hasSettings', 'fieldLabel' => 'Enable Settings', 'type' => 'checkbox', 'displayOrder' => 8},
364
- {'fieldName' => 'hasAutoScale', 'fieldLabel' => 'Enable Scaling (Horizontal)', 'type' => 'checkbox', 'displayOrder' => 9},
365
- {'fieldName' => 'hasDeployment', 'fieldLabel' => 'Supports Deployments', 'type' => 'checkbox', 'displayOrder' => 10, 'description' => 'Requires a data volume be configured on each version. Files will be copied into this location.'}
366
- ]
367
- end
368
-
369
- def update_instance_type_option_types(instance_type=nil)
370
- opts = add_instance_type_option_types
371
- opts = opts.reject {|it| ["logo"].include? it['fieldName'] }
372
- if instance_type
373
- opts = add_instance_type_option_types
374
- opts.find {|opt| opt['fieldName'] == 'name'}['defaultValue'] = instance_type['name']
375
- end
376
- opts
377
- end
378
-
379
- def load_balance_protocols
380
- [
381
- {'name' => 'None', 'value' => ''},
382
- {'name' => 'HTTP', 'value' => 'HTTP'},
383
- {'name' => 'HTTPS', 'value' => 'HTTPS'},
384
- {'name' => 'TCP', 'value' => 'TCP'}
385
- ]
386
- end
387
-
388
292
  # finders are in LibraryHelper
389
293
 
390
294
  # lol
@@ -9,6 +9,9 @@ class Morpheus::Cli::License
9
9
  register_subcommands :get, :install, :uninstall, :test
10
10
  # deprecated
11
11
  register_subcommands :decode, :apply
12
+
13
+ set_subcommands_hidden :decode, :apply
14
+
12
15
  #alias_subcommand :details, :get
13
16
 
14
17
  def initialize()
@@ -14,7 +14,7 @@ class Morpheus::Cli::Login
14
14
  end
15
15
 
16
16
  def connect(opts)
17
- #@api_client = establish_remote_appliance_connection(opts)
17
+ # @api_client = establish_remote_appliance_connection({:skip_verify_access_token => true, :skip_login => true}.merge(opts))
18
18
  end
19
19
 
20
20
  def usage
@@ -47,47 +47,27 @@ class Morpheus::Cli::Login
47
47
  options[:remote_token] = val
48
48
  end
49
49
  build_common_options(opts, options, [:json, :dry_run, :remote, :quiet], [:remote_username, :remote_password, :remote_token])
50
- opts.footer = "Login to a remote appliance with a username and password or an access token.\n" +
51
- "[username] is required .\n" +
52
- "[password] is required.\n" +
53
- "Logging in with username and password will make an authentication api request to obtain an access token.\n" +
54
- "The --token option can be used to login with an existing token instead of username and password.\n" +
55
- "Using --token makes a whoami api request to validate the token.\n" +
56
- "If successful, the access token will be saved with the active session for the remote appliance.\n" +
57
- "This command will first logout any active session before attempting to login.\n" +
58
- "The --test option can be used for testing credentials without updating your active session."
50
+ opts.footer = <<-EOT
51
+ Login to a remote appliance with a username and password or using an access token.
52
+ Logging in with username and password will make an authentication api request to obtain an access token.
53
+ The --token option can be used to login with a valid access token instead of username and password.
54
+ The specified token will be verified by making a whoami api request
55
+ If successful, the access token will be saved with the active session for the remote appliance.
56
+ This command will first logout any active session before attempting authorization.
57
+ The --test option is available for testing credentials without updating your active session, neithing logging you out or in.
58
+ EOT
59
59
 
60
60
  end
61
61
  optparse.parse!(args)
62
- if args.count > 2
63
- print_error Morpheus::Terminal.angry_prompt
64
- puts_error "#{command_name} list expects 0-2 arguments and received #{args.count}: #{args}\n#{optparse}"
65
- return 1
66
- end
62
+ verify_args!(args:args, max:2, optparse:optparse)
67
63
  username = args[0] if args[0]
68
64
  password = args[1] if args[1]
69
65
 
70
66
  # connect(options)
71
- if options[:remote]
72
- appliance = Morpheus::Cli::Remote.appliances[options[:remote].to_sym]
73
- if appliance
74
- @appliance_name, @appliance_url = options[:remote].to_sym, appliance[:host]
75
- else
76
- @appliance_name, @appliance_url = nil, nil
77
- end
78
- if !@appliance_name
79
- print_error red, "You have no appliance named '#{options[:remote]}' configured. See the `remote list` command.", reset, "\n"
80
- return 1
81
- end
82
- elsif options[:remote_url]
83
- # --remote-url
84
- @appliance_name, @appliance_url = nil, appliance[:remote_url]
85
- else
86
- @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
87
- if !@appliance_name
88
- print_error yellow, "Please specify a remote appliance with -r or see the command `remote use`", reset, "\n"
89
- return 1
90
- end
67
+ @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
68
+
69
+ if @remote_appliance[:authenticated]
70
+ puts "You will be automatically logged out of your current session as '#{@remote_appliance[:username]}'"
91
71
  end
92
72
 
93
73
  begin
@@ -124,9 +104,9 @@ class Morpheus::Cli::Login
124
104
  # Login Success!
125
105
  if !options[:quiet]
126
106
  if options[:test_only]
127
- print green,"Success! Credentials verified for #{wallet['username']}.", reset, "\n"
107
+ print green,"Success! Test Credentials verified for #{wallet['username']}", reset, "\n"
128
108
  else
129
- print green,"Success! Logged in to #{@appliance_name} as #{wallet['username']}.", reset, "\n"
109
+ print green,"Success! Logged in as #{wallet['username']}", reset, "\n"
130
110
  end
131
111
  end
132
112
  return 0 # , nil
@@ -15,8 +15,8 @@ class Morpheus::Cli::Logout
15
15
  @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
16
  end
17
17
 
18
- def connect(opts)
19
- #@api_client = establish_remote_appliance_connection(opts)
18
+ def connect(options)
19
+ @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
20
20
  end
21
21
 
22
22
  def usage
@@ -32,12 +32,16 @@ class Morpheus::Cli::Logout
32
32
  optparse = Morpheus::Cli::OptionParser.new do |opts|
33
33
  opts.banner = usage
34
34
  build_common_options(opts, options, [:remote, :quiet])
35
+ opts.footer = <<-EOT
36
+ Logout of a remote appliance.
37
+ This clears your credentials so that you will need to login again.
38
+ EOT
35
39
  end
36
40
  optparse.parse!(args)
37
- # connect(options)
41
+ verify_args!(args:args,count:0,optpare:optparse)
42
+ connect(options)
38
43
  # establish @appliance_name, @appliance_url,
39
- @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true}))
40
-
44
+ #@api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
41
45
  begin
42
46
  if !@appliance_name
43
47
  print_error Morpheus::Terminal.angry_prompt
@@ -317,6 +317,8 @@ module Morpheus::Cli::AccountsHelper
317
317
  #print reset if table_color
318
318
  end
319
319
 
320
+ ## These user access formatted methods should probably move up to PrintHelper to be more ubiquitous.
321
+
320
322
  def format_user_role_names(user)
321
323
  role_names = ""
322
324
  if user && user['roles']
@@ -327,15 +329,89 @@ module Morpheus::Cli::AccountsHelper
327
329
  role_names
328
330
  end
329
331
 
330
- def get_access_string(val)
331
- val ||= 'none'
332
- if val == 'none'
333
- "#{white}#{val.to_s.capitalize}#{cyan}"
334
- # elsif val == 'read'
335
- # "#{cyan}#{val.to_s.capitalize}#{cyan}"
332
+ def get_access_color(access)
333
+ access ||= 'none'
334
+ if access == 'none'
335
+ # maybe reset instead of white?
336
+ white
337
+ elsif access == 'read'
338
+ cyan
339
+ else
340
+ green
341
+ end
342
+ end
343
+
344
+ def get_access_string(access, return_color=cyan)
345
+ get_access_color(access) + access + return_color
346
+ # access ||= 'none'
347
+ # if access == 'none'
348
+ # "#{white}#{access.to_s}#{return_color}"
349
+ # elsif access == 'read'
350
+ # "#{cyan}#{access.to_s.capitalize}#{return_color}"
351
+ # else
352
+ # "#{green}#{access.to_s}#{return_color}"
353
+ # end
354
+ end
355
+
356
+ # this outputs a string that matches the length of all available access levels
357
+ # for outputting in a grid that looks like this:
358
+ #
359
+ # none
360
+ # full
361
+ # full
362
+ # user
363
+ # read
364
+ # full
365
+ # none
366
+ #
367
+ # Examples: format_permission_access("read")
368
+ # format_permission_access("custom", "full,custom,none")
369
+ def format_access_string(access, access_levels=nil, return_color=cyan)
370
+ access = access.to_s.downcase.strip
371
+ if access.empty?
372
+ access = "none"
373
+ end
374
+ if access_levels.nil?
375
+ access_levels = ["none","read","user","full"]
376
+ elsif access_levels.is_a?(Array)
377
+ # access_levels = access_levels
336
378
  else
337
- "#{green}#{val.to_s.capitalize}#{cyan}"
379
+ # parse values like "full,custom,none"
380
+ access_levels = [access_levels].flatten.collect {|it| it.strip.split(",") }.flatten.collect {|it| it.strip }.compact
381
+ end
382
+ # build padded string that contains access eg. 'full' or ' read'
383
+ access_levels_string = access_levels.join(",")
384
+ padded_value = ""
385
+ access_levels.each do |a|
386
+ # handle some unusual access values
387
+ # print custom, and provision where 'user' normally is at index 1
388
+ if (access == "custom" || access == "provision") && a == "user"
389
+ padded_value << access
390
+ else
391
+ if access == a
392
+ padded_value << access
393
+ else
394
+ padded_value << " " * a.size
395
+ end
396
+ end
397
+ end
398
+ # no matching access was found, so just print it in one slot
399
+ if padded_value == ""
400
+ padded_value = " " * access_levels[0].to_s.size
401
+ padded_value << access
402
+ end
403
+ # strip any extra whitespace off the end
404
+ if padded_value.size > access_levels_string.size
405
+ padded_value = padded_value.rstrip
338
406
  end
407
+ # ok build out string
408
+ out = ""
409
+ access_color = get_access_color(access)
410
+ out << access_color if access_color
411
+ out << padded_value
412
+ out << reset if access_color
413
+ out << return_color if return_color
414
+ return out
339
415
  end
340
416
 
341
417
  end
@@ -0,0 +1,41 @@
1
+ require 'morpheus/cli/mixins/print_helper'
2
+
3
+ # Mixin for Morpheus::Cli command classes
4
+ # Provides common methods for working with Operations.
5
+ # This includes the Dashboard, Activity, and more... (coming soon)
6
+ module Morpheus::Cli::OperationsHelper
7
+
8
+ def self.included(klass)
9
+ klass.send :include, Morpheus::Cli::PrintHelper
10
+ end
11
+
12
+ def format_activity_severity(severity, return_color=cyan)
13
+ out = ""
14
+ status_string = severity
15
+ if status_string == 'critical'
16
+ out << "#{red}#{status_string.capitalize}#{return_color}"
17
+ elsif status_string == 'warning'
18
+ out << "#{yellow}#{status_string.capitalize}#{return_color}"
19
+ elsif status_string == 'info'
20
+ out << "#{cyan}#{status_string.capitalize}#{return_color}"
21
+ else
22
+ out << "#{cyan}#{status_string}#{return_color}"
23
+ end
24
+ out
25
+ end
26
+
27
+ def format_activity_display_object(item)
28
+ out = ""
29
+ if item['name']
30
+ out << item['name']
31
+ end
32
+ if item['objectType']
33
+ out << " (#{item['objectType']} #{item['objectId']})"
34
+ end
35
+ if item['deleted']
36
+ out << " [deleted]"
37
+ end
38
+ out
39
+ end
40
+
41
+ end