morpheus-cli 2.10.3 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/bin/morpheus +5 -96
  3. data/lib/morpheus/api/api_client.rb +23 -1
  4. data/lib/morpheus/api/checks_interface.rb +106 -0
  5. data/lib/morpheus/api/incidents_interface.rb +102 -0
  6. data/lib/morpheus/api/monitoring_apps_interface.rb +47 -0
  7. data/lib/morpheus/api/monitoring_contacts_interface.rb +47 -0
  8. data/lib/morpheus/api/monitoring_groups_interface.rb +47 -0
  9. data/lib/morpheus/api/monitoring_interface.rb +36 -0
  10. data/lib/morpheus/api/option_type_lists_interface.rb +47 -0
  11. data/lib/morpheus/api/option_types_interface.rb +47 -0
  12. data/lib/morpheus/api/roles_interface.rb +0 -1
  13. data/lib/morpheus/api/setup_interface.rb +19 -9
  14. data/lib/morpheus/cli.rb +20 -1
  15. data/lib/morpheus/cli/accounts.rb +8 -3
  16. data/lib/morpheus/cli/app_templates.rb +19 -11
  17. data/lib/morpheus/cli/apps.rb +52 -37
  18. data/lib/morpheus/cli/cli_command.rb +229 -53
  19. data/lib/morpheus/cli/cli_registry.rb +48 -40
  20. data/lib/morpheus/cli/clouds.rb +55 -26
  21. data/lib/morpheus/cli/command_error.rb +12 -0
  22. data/lib/morpheus/cli/credentials.rb +68 -26
  23. data/lib/morpheus/cli/curl_command.rb +98 -0
  24. data/lib/morpheus/cli/dashboard_command.rb +2 -7
  25. data/lib/morpheus/cli/deployments.rb +4 -4
  26. data/lib/morpheus/cli/deploys.rb +1 -2
  27. data/lib/morpheus/cli/dot_file.rb +5 -8
  28. data/lib/morpheus/cli/error_handler.rb +179 -15
  29. data/lib/morpheus/cli/groups.rb +21 -13
  30. data/lib/morpheus/cli/hosts.rb +220 -110
  31. data/lib/morpheus/cli/instance_types.rb +2 -2
  32. data/lib/morpheus/cli/instances.rb +257 -167
  33. data/lib/morpheus/cli/key_pairs.rb +15 -9
  34. data/lib/morpheus/cli/library.rb +673 -27
  35. data/lib/morpheus/cli/license.rb +2 -2
  36. data/lib/morpheus/cli/load_balancers.rb +4 -4
  37. data/lib/morpheus/cli/log_level_command.rb +6 -4
  38. data/lib/morpheus/cli/login.rb +17 -3
  39. data/lib/morpheus/cli/logout.rb +25 -11
  40. data/lib/morpheus/cli/man_command.rb +388 -0
  41. data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
  42. data/lib/morpheus/cli/mixins/monitoring_helper.rb +434 -0
  43. data/lib/morpheus/cli/mixins/print_helper.rb +620 -112
  44. data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -1
  45. data/lib/morpheus/cli/monitoring_apps_command.rb +29 -0
  46. data/lib/morpheus/cli/monitoring_checks_command.rb +427 -0
  47. data/lib/morpheus/cli/monitoring_contacts_command.rb +373 -0
  48. data/lib/morpheus/cli/monitoring_groups_command.rb +29 -0
  49. data/lib/morpheus/cli/monitoring_incidents_command.rb +711 -0
  50. data/lib/morpheus/cli/option_types.rb +10 -1
  51. data/lib/morpheus/cli/recent_activity_command.rb +2 -5
  52. data/lib/morpheus/cli/remote.rb +874 -134
  53. data/lib/morpheus/cli/roles.rb +54 -27
  54. data/lib/morpheus/cli/security_group_rules.rb +2 -2
  55. data/lib/morpheus/cli/security_groups.rb +23 -19
  56. data/lib/morpheus/cli/set_prompt_command.rb +50 -0
  57. data/lib/morpheus/cli/shell.rb +222 -157
  58. data/lib/morpheus/cli/tasks.rb +19 -15
  59. data/lib/morpheus/cli/users.rb +27 -17
  60. data/lib/morpheus/cli/version.rb +1 -1
  61. data/lib/morpheus/cli/virtual_images.rb +28 -13
  62. data/lib/morpheus/cli/whoami.rb +131 -52
  63. data/lib/morpheus/cli/workflows.rb +24 -9
  64. data/lib/morpheus/formatters.rb +195 -3
  65. data/lib/morpheus/logging.rb +86 -0
  66. data/lib/morpheus/terminal.rb +371 -0
  67. data/scripts/generate_morpheus_commands_help.morpheus +60 -0
  68. metadata +21 -2
@@ -45,9 +45,9 @@ class Morpheus::Cli::Tasks
45
45
  print JSON.pretty_generate(json_response)
46
46
  else
47
47
  tasks = json_response['tasks']
48
- print "\n" ,cyan, bold, "Morpheus Tasks\n","==================", reset, "\n\n"
48
+ print_h1 "Morpheus Tasks"
49
49
  if tasks.empty?
50
- puts yellow,"No tasks currently configured.",reset
50
+ puts cyan,"No tasks found.",reset,"\n"
51
51
  else
52
52
  print cyan
53
53
  tasks_table_data = tasks.collect do |task|
@@ -94,16 +94,20 @@ class Morpheus::Cli::Tasks
94
94
  print "\n"
95
95
  else
96
96
  #print "\n", cyan, "Task #{task['name']} - #{task['taskType']['name']}\n\n"
97
- print "\n" ,cyan, bold, "Task Details\n","==================", reset, "\n\n"
97
+ print_h1 "Task Details"
98
98
  print cyan
99
- puts "ID: #{task['id']}"
100
- puts "Name: #{task['name']}"
101
- puts "Type: #{task['taskType']['name']}"
102
- #puts "Description: #{workflow['description']}"
103
- # print "\n", cyan, "Config:\n"
99
+ description_cols = {
100
+ "ID" => 'id',
101
+ "Name" => 'name',
102
+ "Type" => lambda {|it| it['taskType']['name'] },
103
+ }
104
+ print_description_list(description_cols, task)
105
+
106
+ # JD: uhh, the api should NOT be returning passwords!!
104
107
  task_type['optionTypes'].sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i }.each do |optionType|
105
108
  if optionType['fieldLabel'].to_s.downcase == 'script'
106
- print cyan,bold,"Script:","\n",reset,bright_black,"#{task['taskOptions'][optionType['fieldName']]}","\n",reset
109
+ print_h2 "Script"
110
+ print reset,bright_black,"#{task['taskOptions'][optionType['fieldName']]}","\n",reset
107
111
  else
108
112
  print cyan,("#{optionType['fieldLabel']} : " + (optionType['type'] == 'password' ? "#{task['taskOptions'][optionType['fieldName']] ? '************' : ''}" : "#{task['taskOptions'][optionType['fieldName']] || optionType['defaultValue']}")),"\n"
109
113
  end
@@ -195,18 +199,18 @@ class Morpheus::Cli::Tasks
195
199
  end
196
200
  json_response = @tasks_interface.task_types()
197
201
  if options[:json]
198
- print JSON.pretty_generate(json_response)
202
+ print JSON.pretty_generate(json_response),"\n"
199
203
  else
200
204
  task_types = json_response['taskTypes']
201
- print "\n" ,cyan, bold, "Morpheus Task Types\n","==================", reset, "\n\n"
205
+ print_h1 "Morpheus Task Types"
202
206
  if task_types.nil? || task_types.empty?
203
- puts yellow,"No task types currently exist on this appliance. This could be a seed issue.",reset
207
+ print yellow,"No task types currently exist on this appliance. This could be a seed issue.",reset,"\n"
204
208
  else
205
209
  print cyan
206
210
  tasks_table_data = task_types.collect do |task_type|
207
211
  {name: task_type['name'], id: task_type['id'], code: task_type['code'], description: task_type['description']}
208
212
  end
209
- tp tasks_table_data, :id, :name, :code, :description
213
+ tp tasks_table_data, :id, :name, :code
210
214
  end
211
215
 
212
216
  print reset,"\n"
@@ -248,7 +252,7 @@ class Morpheus::Cli::Tasks
248
252
  end
249
253
  json_response = @tasks_interface.create(payload)
250
254
  if options[:json]
251
- print JSON.pretty_generate(json_response)
255
+ print JSON.pretty_generate(json_response),"\n"
252
256
  elsif !options[:quiet]
253
257
  print "\n", cyan, "Task #{json_response['task']['name']} created successfully", reset, "\n\n"
254
258
  list([])
@@ -284,7 +288,7 @@ class Morpheus::Cli::Tasks
284
288
  end
285
289
  json_response = @tasks_interface.destroy(task['id'])
286
290
  if options[:json]
287
- print JSON.pretty_generate(json_response)
291
+ print JSON.pretty_generate(json_response),"\n"
288
292
  elsif !options[:quiet]
289
293
  print "\n", cyan, "Task #{task['name']} removed", reset, "\n\n"
290
294
  end
@@ -63,8 +63,10 @@ class Morpheus::Cli::Users
63
63
  if account
64
64
  subtitles << "Account: #{account['name']}".strip
65
65
  end
66
- subtitle = subtitles.join(', ')
67
- print "\n" ,cyan, bold, title, (subtitle.empty? ? "" : " - #{subtitle}"), "\n", "==================", reset, "\n\n"
66
+ if params[:phrase]
67
+ subtitles << "Search: #{params[:phrase]}".strip
68
+ end
69
+ print_h1 title, subtitles
68
70
  if users.empty?
69
71
  puts yellow,"No users found.",reset
70
72
  else
@@ -146,26 +148,34 @@ class Morpheus::Cli::Users
146
148
  print "\n"
147
149
  end
148
150
  else
149
- print "\n" ,cyan, bold, "User Details\n","==================", reset, "\n\n"
151
+ print_h1 "User Details"
150
152
  print cyan
151
- puts "ID: #{user['id']}"
152
- puts "Account: #{user['account'] ? user['account']['name'] : nil}"
153
- puts "First Name: #{user['firstName']}"
154
- puts "Last Name: #{user['lastName']}"
155
- puts "Username: #{user['username']}"
156
- puts "Email: #{user['email']}"
157
- puts "Role: #{format_user_role_names(user)}"
158
- puts "Date Created: #{format_local_dt(user['dateCreated'])}"
159
- puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
160
- print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
153
+ description_cols = {
154
+ "ID" => 'id',
155
+ "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
156
+ # "First" => 'firstName',
157
+ # "Last" => 'lastName',
158
+ # "Name" => 'displayName',
159
+ "Name" => lambda {|it| it['firstName'] ? it['displayName'] : '' },
160
+ "Username" => 'username',
161
+ "Email" => 'email',
162
+ "Role" => lambda {|it| format_user_role_names(it) },
163
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
164
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
165
+ }
166
+ print_description_list(description_cols, user)
167
+
168
+ print_h2 "User Instance Limits"
161
169
  print cyan
162
- puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
163
- puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
164
- puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
170
+ print_description_list({
171
+ "Max Storage" => lambda {|it| (it && it['maxStorage'].to_i != 0) ? Filesize.from("#{it['maxStorage']} B").pretty : "no limit" },
172
+ "Max Memory" => lambda {|it| (it && it['maxMemory'].to_i != 0) ? Filesize.from("#{it['maxMemory']} B").pretty : "no limit" },
173
+ "CPU Count" => lambda {|it| (it && it['maxCpu'].to_i != 0) ? it['maxCpu'] : "no limit" }
174
+ }, user['instanceLimits'])
165
175
 
166
176
  if options[:include_feature_access] && user_feature_permissions
167
177
  if user_feature_permissions
168
- print "\n" ,cyan, bold, "Feature Permissions\n","==================", reset, "\n\n"
178
+ print_h2 "Feature Permissions"
169
179
  print cyan
170
180
  rows = user_feature_permissions.collect do |code, access|
171
181
  {code: code, access: get_access_string(access) }
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "2.10.3"
4
+ VERSION = "2.11.0"
5
5
  end
6
6
  end
@@ -67,9 +67,20 @@ class Morpheus::Cli::VirtualImages
67
67
  print JSON.pretty_generate(json_response)
68
68
  else
69
69
  images = json_response['virtualImages']
70
- print "\n" ,cyan, bold, "Morpheus Virtual Images\n","=======================", reset, "\n\n"
70
+ title = "Morpheus Virtual Images"
71
+ subtitles = []
72
+ if options[:imageType]
73
+ subtitles << "Image Type: #{options[:imageType]}".strip
74
+ end
75
+ if options[:filterType]
76
+ subtitles << "Image Type: #{options[:filterType]}".strip
77
+ end
78
+ if params[:phrase]
79
+ subtitles << "Search: #{params[:phrase]}".strip
80
+ end
81
+ print_h1 title, subtitles
71
82
  if images.empty?
72
- puts yellow,"No virtual images currently exist.",reset
83
+ print yellow,"No virtual images found.",reset,"\n"
73
84
  else
74
85
  print cyan
75
86
  image_table_data = images.collect do |image|
@@ -122,15 +133,19 @@ class Morpheus::Cli::VirtualImages
122
133
  else
123
134
  image_type = virtual_image_type_for_name_or_code(image['imageType'])
124
135
  image_type_display = image_type ? "#{image_type['name']}" : image['imageType']
125
- print "\n" ,cyan, bold, "Virtual Image Details\n","==================", reset, "\n\n"
136
+ print_h1 "Virtual Image Details"
126
137
  print cyan
127
- puts "ID: #{image['id']}"
128
- puts "Name: #{image['name']}"
129
- puts "Type: #{image_type_display}"
130
- #puts "Date Created: #{format_local_dt(image['dateCreated'])}"
131
- #puts "Last Updated: #{format_local_dt(image['lastUpdated'])}"
138
+ description_cols = {
139
+ "ID" => 'id',
140
+ "Name" => 'name',
141
+ "Type" => lambda {|it| image_type_display },
142
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
143
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
144
+ }
145
+ print_description_list(description_cols, image)
146
+
132
147
  if image_files
133
- puts "Files:"
148
+ print_h2 "Files"
134
149
  image_files.each {|image_file|
135
150
  pretty_filesize = Filesize.from("#{image_file['size']} B").pretty
136
151
  print cyan," = #{image_file['name']} [#{pretty_filesize}]", "\n"
@@ -216,9 +231,9 @@ class Morpheus::Cli::VirtualImages
216
231
  print JSON.pretty_generate(json_response)
217
232
  else
218
233
  image_types = json_response['virtualImageTypes']
219
- print "\n" ,cyan, bold, "Morpheus Virtual Image Types\n","============================", reset, "\n\n"
234
+ print_h1 "Morpheus Virtual Image Types"
220
235
  if image_types.nil? || image_types.empty?
221
- puts yellow,"No image types currently exist on this appliance. This could be a seed issue.",reset
236
+ print yellow,"No image types currently exist on this appliance. This could be a seed issue.",reset,"\n"
222
237
  else
223
238
  print cyan
224
239
  lb_table_data = image_types.collect do |lb_type|
@@ -227,7 +242,7 @@ class Morpheus::Cli::VirtualImages
227
242
  tp lb_table_data, :name, :code
228
243
  end
229
244
 
230
- print reset,"\n\n"
245
+ print reset,"\n"
231
246
  end
232
247
  rescue RestClient::Exception => e
233
248
  print_rest_exception(e, options)
@@ -513,7 +528,7 @@ class Morpheus::Cli::VirtualImages
513
528
  if image_type_code == 'ami'
514
529
  tmp_option_types << {'fieldName' => 'externalId', 'fieldLabel' => 'AMI id', 'type' => 'text', 'required' => false, 'displayOrder' => 10}
515
530
  tmp_option_types << {'fieldName' => 'imageFile', 'fieldLabel' => 'Image File', 'type' => 'file', 'required' => true, 'displayOrder' => 10}
516
- elsif image_type_code == 'vmware'
531
+ elsif image_type_code == 'vmware' || image_type_code == 'vmdk'
517
532
  tmp_option_types << {'fieldContext' => 'virtualImageFiles', 'fieldName' => 'imageFile', 'fieldLabel' => 'OVF File', 'type' => 'file', 'required' => true, 'displayOrder' => 10}
518
533
  tmp_option_types << {'fieldContext' => 'virtualImageFiles', 'fieldName' => 'imageDescriptorFile', 'fieldLabel' => 'VMDK File', 'type' => 'file', 'required' => false, 'displayOrder' => 10}
519
534
  elsif image_type_code == 'pxe'
@@ -22,9 +22,14 @@ class Morpheus::Cli::Whoami
22
22
  end
23
23
 
24
24
  def connect(opts)
25
- @api_client = establish_remote_appliance_connection(opts)
26
- @groups_interface = @api_client.groups
27
- @active_group_id = Morpheus::Cli::Groups.active_group
25
+ #@api_client = establish_remote_appliance_connection(opts)
26
+ # begin
27
+ @api_client = establish_remote_appliance_connection(opts.merge({:no_prompt => true, :skip_verify_access_token => true}))
28
+ @groups_interface = @api_client.groups
29
+ @active_group_id = Morpheus::Cli::Groups.active_group
30
+ # rescue Morpheus::Cli::CommandError => err
31
+ # puts_error err
32
+ # end
28
33
  end
29
34
 
30
35
  def handle(args)
@@ -33,11 +38,17 @@ class Morpheus::Cli::Whoami
33
38
 
34
39
  def show(args)
35
40
  options = {}
41
+ username_only = false
42
+ access_token_only = false
36
43
  optparse = OptionParser.new do|opts|
37
44
  opts.banner = usage
38
- opts.on(nil,'--feature-access', "Display Feature Access") do |val|
45
+ opts.on( '-n', '--name', "Print only your username." ) do
46
+ username_only = true
47
+ end
48
+ opts.on('-f','--feature-access', "Display Feature Access") do
39
49
  options[:include_feature_access] = true
40
50
  end
51
+ # these are things that morpheus users get has to display...
41
52
  # opts.on(nil,'--group-access', "Display Group Access") do
42
53
  # options[:include_group_access] = true
43
54
  # end
@@ -47,61 +58,112 @@ class Morpheus::Cli::Whoami
47
58
  # opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
48
59
  # options[:include_instance_type_access] = true
49
60
  # end
50
- opts.on(nil,'--all-access', "Display All Access Lists") do
51
- options[:include_feature_access] = true
52
- options[:include_group_access] = true
53
- options[:include_cloud_access] = true
54
- options[:include_instance_type_access] = true
61
+ # opts.on('-a','--all-access', "Display All Access Lists") do
62
+ # options[:include_feature_access] = true
63
+ # options[:include_group_access] = true
64
+ # options[:include_cloud_access] = true
65
+ # options[:include_instance_type_access] = true
66
+ # end
67
+ opts.on('-t','--token-only', "Print your access token only") do
68
+ access_token_only = true
55
69
  end
56
- build_common_options(opts, options, [:json, :remote, :dry_run]) # todo: support :remote too
70
+ build_common_options(opts, options, [:json, :remote, :dry_run])
57
71
  end
58
72
  optparse.parse!(args)
59
- # todo: check to see if they have credentials instead of just trying to connect (and prompting)
60
73
  connect(options)
61
74
  begin
62
- json_response = load_whoami()
63
- group = nil
75
+ # check to see if they have credentials instead of just trying to connect (and prompting)
76
+
77
+ if !@appliance_name
78
+ # never gets here..
79
+ #raise_command_error "Please specify a Morpheus Appliance with -r or see the command `remote use`"
80
+ print yellow,"Please specify a Morpheus Appliance with -r or see `remote use`.#{reset}\n"
81
+ return 1
82
+ end
83
+
84
+
85
+ creds = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
86
+
87
+ if !creds
88
+ if options[:quiet]
89
+ return 1
90
+ elsif access_token_only
91
+ puts_error "(logged out)" # stderr probably
92
+ return 1
93
+ else
94
+ print yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
95
+ print yellow,"Use the 'login' command.",reset,"\n"
96
+ return 1
97
+ end
98
+ end
99
+
100
+
101
+ load_whoami()
102
+
103
+ user = @current_user # from load_whoami() meh
104
+
105
+
106
+ if access_token_only
107
+ if options[:quiet]
108
+ return 1
109
+ end
110
+ if !@access_token
111
+ print yellow,"\n","No access token. Please login",reset,"\n"
112
+ return false
113
+ end
114
+ print cyan,@access_token.to_s,reset,"\n"
115
+ return 0
116
+ end
117
+
118
+ if username_only
119
+ if options[:quiet]
120
+ return 1
121
+ end
122
+ if !user
123
+ puts "(logged out)" # "(anonymous)" || ""
124
+ return 1
125
+ end
126
+ print cyan,user['username'].to_s,reset,"\n"
127
+ return 0
128
+ end
129
+
130
+
131
+ active_group = nil
64
132
  begin
65
- group = @active_group_id ? find_group_by_name_or_id(@active_group_id) : nil # via InfrastructureHelper mixin
133
+ active_group = @active_group_id ? find_group_by_name_or_id(@active_group_id) : nil # via InfrastructureHelper mixin
66
134
  rescue => err
67
135
  if options[:debug]
68
136
  print red,"Unable to determine active group: #{err}\n",reset
69
137
  end
70
138
  end
139
+
71
140
  if options[:json]
72
141
  print JSON.pretty_generate(json_response)
73
142
  print "\n"
74
143
  else
75
- user = @current_user
76
144
  if !user
77
- puts yellow,"No active session. Please login",reset
145
+ print yellow,"\n","No active session. Please login",reset,"\n"
78
146
  exit 1
79
147
  end
80
148
 
81
- # todo: impersonate command and show that info here
82
-
83
- print "\n" ,cyan, bold, "Current User\n","==================", reset, "\n\n"
149
+ print_h1 "Current User"
84
150
  print cyan
85
- # if @is_master_account
86
- puts "ID: #{user['id']}"
87
- puts "Account: #{user['account'] ? user['account']['name'] : nil}" + (@is_master_account ? " (Master Account)" : "")
88
- # end
89
- puts "First Name: #{user['firstName']}"
90
- puts "Last Name: #{user['lastName']}"
91
- puts "Username: #{user['username']}"
92
- puts "Email: #{user['email']}"
93
- puts "Role: #{format_user_role_names(user)}"
94
- # puts "Date Created: #{format_local_dt(user['dateCreated'])}"
95
- # puts "Last Updated: #{format_local_dt(user['lastUpdated'])}"
96
- # print "\n" ,cyan, bold, "User Instance Limits\n","==================", reset, "\n\n"
151
+ print_description_list({
152
+ "ID" => 'id',
153
+ "Account" => lambda {|it| (it['account'] ? it['account']['name'] : '') + (@is_master_account ? " (Master Account)" : '') },
154
+ # "First Name" => 'firstName',
155
+ # "Last Name" => 'lastName',
156
+ # "Name" => 'displayName',
157
+ "Name" => lambda {|it| it['firstName'] ? it['displayName'] : '' },
158
+ "Username" => 'username',
159
+ "Email" => 'email',
160
+ "Role" => lambda {|it| format_user_role_names(it) }
161
+ }, user)
97
162
  print cyan
98
- # puts "Max Storage (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxStorage'] : 0}"
99
- # puts "Max Memory (bytes): #{user['instanceLimits'] ? user['instanceLimits']['maxMemory'] : 0}"
100
- # puts "CPU Count: #{user['instanceLimits'] ? user['instanceLimits']['maxCpu'] : 0}"
101
163
 
102
164
  if options[:include_feature_access]
103
165
  if @user_permissions
104
- print "\n" ,cyan, bold, "Feature Permissions\n","==================", reset, "\n\n"
166
+ print_h2 "Feature Permissions"
105
167
  print cyan
106
168
  rows = @user_permissions.collect do |code, access|
107
169
  {code: code, access: get_access_string(access) }
@@ -112,29 +174,47 @@ class Morpheus::Cli::Whoami
112
174
  end
113
175
  end
114
176
 
115
- print "\n" ,cyan, bold, "Remote Appliance\n","==================", reset, "\n\n"
116
- print cyan
117
- if @appliance_name
118
- puts "Name: #{@appliance_name}"
119
- end
120
- if @appliance_url
121
- puts "Url: #{@appliance_url}"
122
- end
123
- if @appliance_build_verison
124
- puts "Build Version: #{@appliance_build_verison}"
125
- end
177
+ print_h1 "Remote Appliance"
126
178
  print cyan
179
+ appliance_data = {
180
+ 'name' => @appliance_name,
181
+ 'url' => @appliance_url,
182
+ 'buildVersion' => @appliance_build_verison
183
+ }
184
+ print_description_list({
185
+ "Name" => 'name',
186
+ "Url" => 'url',
187
+ "Version" => 'buildVersion'
188
+ }, appliance_data)
127
189
 
128
- if group
129
- print "\n" ,cyan, bold, "Active Group\n","==================", reset, "\n\n"
190
+ if active_group
130
191
  print cyan
131
- print "ID: #{group['id']}\n"
132
- print "Name: #{group['name']}\n"
192
+ # print_h1 "Active Group"
193
+ # print cyan
194
+ # print_description_list({
195
+ # "ID" => 'id',
196
+ # "Name" => 'name'
197
+ # }, active_group)
198
+ print cyan, "\n# => Currently using group #{active_group['name']}\n", reset
133
199
  else
134
- print "\n"
200
+ print "\n", reset
135
201
  print "No active group. See `groups use`\n",reset
136
202
  end
137
203
 
204
+ # save pertinent session info to the appliance
205
+ begin
206
+ now = Time.now.to_i
207
+ app_map = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
208
+ app_map[:username] = user['username']
209
+ app_map[:authenticated] = true
210
+ app_map[:status] = 'ready'
211
+ app_map[:build_version] = @appliance_build_verison if @appliance_build_verison
212
+ app_map[:last_success_at] = now
213
+ ::Morpheus::Cli::Remote.save_remote(@appliance_name, app_map)
214
+ rescue => err
215
+ puts "failed to save remote appliance info"
216
+ end
217
+
138
218
  print reset,"\n"
139
219
  end
140
220
  rescue RestClient::Exception => e
@@ -149,5 +229,4 @@ class Morpheus::Cli::Whoami
149
229
  end
150
230
  end
151
231
 
152
-
153
232
  end