morpheus-cli 2.10.3 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -0,0 +1,47 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::MonitoringGroupsInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @expires_at = expires_at
9
+ end
10
+
11
+ def get(id, params={})
12
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
13
+ url = "#{@base_url}/api/monitoring/groups/#{id}"
14
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
15
+ opts = {method: :get, url: url, headers: headers}
16
+ execute(opts)
17
+ end
18
+
19
+ def list(params={})
20
+ url = "#{@base_url}/api/monitoring/groups"
21
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
22
+ opts = {method: :get, url: url, headers: headers}
23
+ execute(opts)
24
+ end
25
+
26
+ def create(payload)
27
+ url = "#{@base_url}/api/monitoring/groups"
28
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
29
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
30
+ execute(opts)
31
+ end
32
+
33
+ def update(id, payload)
34
+ url = "#{@base_url}/api/monitoring/groups/#{id}"
35
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
36
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
37
+ execute(opts)
38
+ end
39
+
40
+ def destroy(id)
41
+ url = "#{@base_url}/api/monitoring/groups/#{id}"
42
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
43
+ opts = {method: :delete, url: url, headers: headers}
44
+ execute(opts)
45
+ end
46
+
47
+ end
@@ -0,0 +1,36 @@
1
+ require 'morpheus/api/api_client'
2
+ require 'morpheus/api/checks_interface'
3
+ require 'morpheus/api/incidents_interface'
4
+ require 'morpheus/api/monitoring_contacts_interface'
5
+ require 'morpheus/api/monitoring_groups_interface'
6
+ require 'morpheus/api/monitoring_apps_interface'
7
+
8
+ class Morpheus::MonitoringInterface < Morpheus::APIClient
9
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
10
+ @access_token = access_token
11
+ @refresh_token = refresh_token
12
+ @base_url = base_url
13
+ @expires_at = expires_at
14
+ end
15
+
16
+ def checks
17
+ Morpheus::ChecksInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
18
+ end
19
+
20
+ def incidents
21
+ Morpheus::IncidentsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
22
+ end
23
+
24
+ def contacts
25
+ Morpheus::MonitoringContactsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
26
+ end
27
+
28
+ def groups
29
+ Morpheus::MonitoringGroupsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
30
+ end
31
+
32
+ def apps
33
+ Morpheus::MonitoringAppsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
34
+ end
35
+
36
+ end
@@ -0,0 +1,47 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::OptionTypeListsInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @expires_at = expires_at
9
+ end
10
+
11
+ def get(id)
12
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
13
+ url = "#{@base_url}/api/library/option-type-lists/#{id}"
14
+ headers = { params: {}, authorization: "Bearer #{@access_token}" }
15
+ opts = {method: :get, url: url, headers: headers}
16
+ execute(opts)
17
+ end
18
+
19
+ def list(params={})
20
+ url = "#{@base_url}/api/library/option-type-lists"
21
+ headers = { params: {}, authorization: "Bearer #{@access_token}" }
22
+ headers[:params].merge!(params)
23
+ opts = {method: :get, url: url, headers: headers}
24
+ execute(opts)
25
+ end
26
+
27
+ def create(payload)
28
+ url = "#{@base_url}/api/library/option-type-lists"
29
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
30
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
31
+ execute(opts)
32
+ end
33
+
34
+ def update(id, payload)
35
+ url = "#{@base_url}/api/library/option-type-lists/#{id}"
36
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
37
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
38
+ execute(opts)
39
+ end
40
+
41
+ def destroy(id)
42
+ url = "#{@base_url}/api/library/option-type-lists/#{id}"
43
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
44
+ opts = {method: :delete, url: url, headers: headers}
45
+ execute(opts)
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::OptionTypesInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @expires_at = expires_at
9
+ end
10
+
11
+ def get(id)
12
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
13
+ url = "#{@base_url}/api/library/option-types/#{id}"
14
+ headers = { params: {}, authorization: "Bearer #{@access_token}" }
15
+ opts = {method: :get, url: url, headers: headers}
16
+ execute(opts)
17
+ end
18
+
19
+ def list(params={})
20
+ url = "#{@base_url}/api/library/option-types"
21
+ headers = { params: {}, authorization: "Bearer #{@access_token}" }
22
+ headers[:params].merge!(params)
23
+ opts = {method: :get, url: url, headers: headers}
24
+ execute(opts)
25
+ end
26
+
27
+ def create(payload)
28
+ url = "#{@base_url}/api/library/option-types"
29
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
30
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
31
+ execute(opts)
32
+ end
33
+
34
+ def update(id, payload)
35
+ url = "#{@base_url}/api/library/option-types/#{id}"
36
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
37
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
38
+ execute(opts)
39
+ end
40
+
41
+ def destroy(id)
42
+ url = "#{@base_url}/api/library/option-types/#{id}"
43
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
44
+ opts = {method: :delete, url: url, headers: headers}
45
+ execute(opts)
46
+ end
47
+ end
@@ -13,7 +13,6 @@ class Morpheus::RolesInterface < Morpheus::APIClient
13
13
  url = build_url(account_id, id)
14
14
  headers = { params: {}, authorization: "Bearer #{@access_token}" }
15
15
  execute(method: :get, url: url, headers: headers)
16
- execute(method: :get, url: url, headers: headers)
17
16
  end
18
17
 
19
18
  def list(account_id, options={})
@@ -12,20 +12,30 @@ class Morpheus::SetupInterface < Morpheus::APIClient
12
12
  @base_url = base_url
13
13
  end
14
14
 
15
- def get(options={})
15
+ # no JSON here, just a 200 OK 'NOTHING TO SEE HERE'
16
+ def ping(params={}, timeout=5)
17
+ url = "#{@base_url}/ping"
18
+ headers = {:params => params }
19
+ opts = {method: :get, url: url, headers: headers, timeout: timeout}
20
+ execute(opts, false)
21
+ end
22
+
23
+ def check(params={}, timeout=5)
24
+ url = "#{@base_url}/api/setup/check"
25
+ headers = {:params => params, 'Content-Type' => 'application/json' }
26
+ execute(method: :get, url: url, headers: headers, timeout: timeout)
27
+ end
28
+
29
+ def get(params={}, timeout=30)
16
30
  url = "#{@base_url}/api/setup"
17
- # headers = {:params => {}, authorization: "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
18
- headers = {:params => {}, 'Content-Type' => 'application/json' }
19
- headers[:params].merge!(options)
20
- execute(method: :get, url: url, headers: headers)
31
+ headers = {:params => params, 'Content-Type' => 'application/json' }
32
+ execute(method: :get, url: url, headers: headers, timeout: timeout)
21
33
  end
22
34
 
23
- def init(options={})
35
+ def init(payload={}, timeout=60)
24
36
  url = "#{@base_url}/api/setup/init"
25
- # headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
26
37
  headers = { 'Content-Type' => 'application/json' }
27
- payload = options
28
- execute(method: :post, url: url, timeout: 30, headers: headers, payload: payload.to_json)
38
+ execute(method: :post, url: url, headers: headers, payload: payload.to_json, timeout: timeout)
29
39
  end
30
40
 
31
41
  end
data/lib/morpheus/cli.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "morpheus/cli/version"
2
+ require 'morpheus/cli/command_error'
2
3
  require "morpheus/rest_client"
3
4
  require 'morpheus/formatters'
4
5
  require 'morpheus/logging'
@@ -39,6 +40,8 @@ module Morpheus
39
40
  # utilites
40
41
  require 'morpheus/cli/cli_registry.rb'
41
42
  require 'morpheus/cli/dot_file.rb'
43
+ require 'morpheus/cli/command_error'
44
+
42
45
  load 'morpheus/cli/cli_command.rb'
43
46
  load 'morpheus/cli/option_types.rb'
44
47
  load 'morpheus/cli/credentials.rb'
@@ -81,7 +84,23 @@ module Morpheus
81
84
  load 'morpheus/cli/library.rb'
82
85
  load 'morpheus/cli/version_command.rb'
83
86
  load 'morpheus/cli/alias_command.rb'
84
- # Your new commands goes here...
87
+ # todo: combine checks, incidents, apps, and goups under monitoring?
88
+ # `monitoring apps|groups` still needed,
89
+ # maybe they should go under the apps and groups commands instead?
90
+ # load 'morpheus/cli/monitoring_command.rb'
91
+ load 'morpheus/cli/monitoring_incidents_command.rb'
92
+ load 'morpheus/cli/monitoring_checks_command.rb'
93
+ load 'morpheus/cli/monitoring_contacts_command.rb'
94
+ load 'morpheus/cli/monitoring_groups_command.rb'
95
+ load 'morpheus/cli/monitoring_apps_command.rb'
96
+
97
+ # nice to have commands
98
+ load 'morpheus/cli/curl_command.rb'
99
+ load 'morpheus/cli/set_prompt_command.rb'
100
+ load 'morpheus/cli/man_command.rb' # please implement me
101
+
102
+
103
+ # Your new commands go here...
85
104
 
86
105
  end
87
106
 
@@ -52,7 +52,12 @@ class Morpheus::Cli::Accounts
52
52
  print JSON.pretty_generate(json_response)
53
53
  print "\n"
54
54
  else
55
- print "\n" ,cyan, bold, "Morpheus Accounts\n","==================", reset, "\n\n"
55
+ title = "Morpheus Accounts"
56
+ subtitles = []
57
+ if params[:phrase]
58
+ subtitles << "Search: #{params[:phrase]}".strip
59
+ end
60
+ print_h1 title, subtitles
56
61
  if accounts.empty?
57
62
  puts yellow,"No accounts found.",reset
58
63
  else
@@ -95,7 +100,7 @@ class Morpheus::Cli::Accounts
95
100
  print JSON.pretty_generate({account: account})
96
101
  print "\n"
97
102
  else
98
- print "\n" ,cyan, bold, "Account Details\n","==================", reset, "\n\n"
103
+ print_h1 "Account Details"
99
104
  print cyan
100
105
  puts "ID: #{account['id']}"
101
106
  puts "Name: #{account['name']}"
@@ -112,7 +117,7 @@ class Morpheus::Cli::Accounts
112
117
  status_state = "#{red}INACTIVE#{cyan}"
113
118
  end
114
119
  puts "Status: #{status_state}"
115
- print "\n" ,cyan, bold, "Account Instance Limits\n","==================", reset, "\n\n"
120
+ print_h2 "Account Instance Limits"
116
121
  print cyan
117
122
  puts "Max Storage (bytes): #{account['instanceLimits'] ? account['instanceLimits']['maxStorage'] : 0}"
118
123
  puts "Max Memory (bytes): #{account['instanceLimits'] ? account['instanceLimits']['maxMemory'] : 0}"
@@ -54,9 +54,14 @@ class Morpheus::Cli::AppTemplates
54
54
  print JSON.pretty_generate(json_response)
55
55
  print "\n"
56
56
  else
57
- print "\n" ,cyan, bold, "Morpheus App Templates\n","==================", reset, "\n\n"
57
+ title = "Morpheus App Templates"
58
+ subtitles = []
59
+ if params[:phrase]
60
+ subtitles << "Search: #{params[:phrase]}".strip
61
+ end
62
+ print_h1 title, subtitles
58
63
  if app_templates.empty?
59
- puts yellow,"No app templates found.",reset
64
+ print cyan,"No app templates found.",reset,"\n"
60
65
  else
61
66
  print_app_templates_table(app_templates)
62
67
  print_results_pagination(json_response)
@@ -103,12 +108,15 @@ class Morpheus::Cli::AppTemplates
103
108
  print JSON.pretty_generate(json_response)
104
109
  print "\n"
105
110
  else
106
- print "\n" ,cyan, bold, "App Template Details\n","==================", reset, "\n\n"
111
+ print_h1 "App Template Details"
107
112
  print cyan
108
- puts "ID: #{app_template['id']}"
109
- puts "Name: #{app_template['name']}"
110
- #puts "Category: #{app_template['category']}"
111
- puts "Account: #{app_template['account'] ? app_template['account']['name'] : ''}"
113
+ description_cols = {
114
+ "ID" => 'id',
115
+ "Name" => 'name',
116
+ "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' }
117
+ }
118
+ print_description_list(description_cols, app_template)
119
+
112
120
  instance_type_names = (app_template['instanceTypes'] || []).collect {|it| it['name'] }
113
121
  #puts "Instance Types: #{instance_type_names.join(', ')}"
114
122
  config = app_template['config']['tierView']
@@ -722,9 +730,9 @@ class Morpheus::Cli::AppTemplates
722
730
  print JSON.pretty_generate(json_response)
723
731
  print "\n"
724
732
  else
725
- print "\n" ,cyan, bold, "Tiers\n","==================", reset, "\n\n"
733
+ print_h1 "Available Tiers"
726
734
  if tiers.empty?
727
- puts yellow,"No tiers found.",reset
735
+ print yellow,"No tiers found.",reset,"\n"
728
736
  else
729
737
  rows = tiers.collect do |tier|
730
738
  {
@@ -766,9 +774,9 @@ class Morpheus::Cli::AppTemplates
766
774
  print JSON.pretty_generate(json_response)
767
775
  print "\n"
768
776
  else
769
- print "\n" ,cyan, bold, "Instance Types\n","==================", reset, "\n\n"
777
+ print_h1 "Available Instance Types"
770
778
  if instance_types.empty?
771
- puts yellow,"No instance types found.",reset
779
+ print yellow,"No instance types found.",reset,"\n"
772
780
  else
773
781
  rows = instance_types.collect do |instance_type|
774
782
  {
@@ -60,11 +60,23 @@ class Morpheus::Cli::Apps
60
60
  return
61
61
  end
62
62
  apps = json_response['apps']
63
- print "\n" ,cyan, bold, "Morpheus Apps\n","==================", reset, "\n\n"
63
+ title = "Morpheus Apps"
64
+ subtitles = []
65
+ # if group
66
+ # subtitles << "Group: #{group['name']}".strip
67
+ # end
68
+ # if cloud
69
+ # subtitles << "Cloud: #{cloud['name']}".strip
70
+ # end
71
+ if params[:phrase]
72
+ subtitles << "Search: #{params[:phrase]}".strip
73
+ end
74
+ print_h1 title, subtitles
64
75
  if apps.empty?
65
- puts yellow,"No apps currently configured.",reset
76
+ print cyan,"No apps found.",reset,"\n"
66
77
  else
67
78
  print_apps_table(apps)
79
+ print_results_pagination(json_response)
68
80
  end
69
81
  print reset,"\n"
70
82
  rescue RestClient::Exception => e
@@ -150,21 +162,22 @@ class Morpheus::Cli::Apps
150
162
  print JSON.pretty_generate(json_response)
151
163
  return
152
164
  end
153
- print "\n" ,cyan, bold, "App Details\n","==================", reset, "\n\n"
165
+ print_h1 "App Details"
154
166
  print cyan
155
- puts "ID: #{app['id']}"
156
- puts "Name: #{app['name']}"
157
- puts "Description: #{app['description']}"
158
- puts "Account: #{app['account'] ? app['account']['name'] : ''}"
159
- # puts "Group: #{app['siteId']}"
167
+ description_cols = {
168
+ "ID" => 'id',
169
+ "Name" => 'name',
170
+ "Description" => 'description',
171
+ # "Group" => lambda {|it| it['group'] ? it['group']['name'] : it['siteId'] },
172
+ "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
173
+ "Status" => lambda {|it| format_app_status(it) }
174
+ }
175
+ print_description_list(description_cols, app)
176
+
160
177
  stats = app['stats']
161
- if ((stats['maxMemory'].to_i != 0) || (stats['maxStorage'].to_i != 0))
162
- print "\n"
163
- # print cyan, "Memory: \t#{Filesize.from("#{stats['usedMemory']} B").pretty} / #{Filesize.from("#{stats['maxMemory']} B").pretty}\n"
164
- # print cyan, "Storage: \t#{Filesize.from("#{stats['usedStorage']} B").pretty} / #{Filesize.from("#{stats['maxStorage']} B").pretty}\n\n",reset
178
+ if app['instanceCount'].to_i > 0
179
+ print_h2 "App Usage"
165
180
  print_stats_usage(stats, {include: [:memory, :storage]})
166
- else
167
- #print yellow, "No stat data.", reset
168
181
  end
169
182
 
170
183
  app_tiers = app['appTiers']
@@ -172,13 +185,14 @@ class Morpheus::Cli::Apps
172
185
  puts yellow, "This app is empty", reset
173
186
  else
174
187
  app_tiers.each do |app_tier|
175
- print "\n" ,cyan, bold, "Tier: #{app_tier['tier']['name']}\n","==================", reset, "\n\n"
188
+ print_h2 "Tier: #{app_tier['tier']['name']}\n"
176
189
  print cyan
177
190
  instances = (app_tier['appInstances'] || []).collect {|it| it['instance']}
178
191
  if instances.empty?
179
192
  puts yellow, "This tier is empty", reset
180
193
  else
181
194
  instance_table = instances.collect do |instance|
195
+ # JD: fix bug here, status is not returned because withStats: false !?
182
196
  status_string = instance['status'].to_s
183
197
  if status_string == 'running'
184
198
  status_string = "#{green}#{status_string.upcase}#{cyan}"
@@ -628,11 +642,13 @@ class Morpheus::Cli::Apps
628
642
  end
629
643
  json_response = @apps_interface.security_groups(app['id'])
630
644
  securityGroups = json_response['securityGroups']
631
- print "\n" ,cyan, bold, "Morpheus Security Groups for App: #{app['name']}\n","==================", reset, "\n\n"
632
- print cyan, "Firewall Enabled=#{json_response['firewallEnabled']}\n\n"
645
+ print_h1 "Morpheus Security Groups for App: #{app['name']}"
646
+ print cyan
647
+ print_description_list({"Firewall Enabled" => lambda {|it| format_boolean it['firewallEnabled'] } }, json_response)
633
648
  if securityGroups.empty?
634
- puts yellow,"No security groups currently applied.",reset
649
+ print yellow,"\n","No security groups currently applied.",reset,"\n"
635
650
  else
651
+ print "\n"
636
652
  securityGroups.each do |securityGroup|
637
653
  print cyan, "= #{securityGroup['id']} (#{securityGroup['name']}) - (#{securityGroup['description']})\n"
638
654
  end
@@ -734,30 +750,18 @@ class Morpheus::Cli::Apps
734
750
  end
735
751
 
736
752
  def print_apps_table(apps, opts={})
753
+ output = ""
737
754
  table_color = opts[:color] || cyan
738
755
  rows = apps.collect do |app|
739
756
  instances_str = (app['instanceCount'].to_i == 1) ? "1 Instance" : "#{app['instanceCount']} Instances"
740
757
  containers_str = (app['containerCount'].to_i == 1) ? "1 Container" : "#{app['containerCount']} Containers"
741
- status_string = app['status']
742
- if app['instanceCount'].to_i == 0
743
- # show this instead of WARNING
744
- status_string = "#{white}EMPTY#{table_color}"
745
- elsif status_string == 'running'
746
- status_string = "#{green}#{status_string.upcase}#{table_color}"
747
- elsif status_string == 'stopped' or status_string == 'failed'
748
- status_string = "#{red}#{status_string.upcase}#{table_color}"
749
- elsif status_string == 'unknown'
750
- status_string = "#{white}#{status_string.upcase}#{table_color}"
751
- else
752
- status_string = "#{yellow}#{status_string.upcase}#{table_color}"
753
- end
754
758
  {
755
759
  id: app['id'],
756
760
  name: app['name'],
757
761
  instances: instances_str,
758
762
  containers: containers_str,
759
763
  account: app['account'] ? app['account']['name'] : nil,
760
- status: status_string,
764
+ status: format_app_status(app, table_color),
761
765
  #dateCreated: format_local_dt(app['dateCreated'])
762
766
  }
763
767
  end
@@ -774,10 +778,21 @@ class Morpheus::Cli::Apps
774
778
  print reset
775
779
  end
776
780
 
777
- def generate_id(len=16)
778
- id = ""
779
- len.times { id << (1 + rand(9)).to_s }
780
- id
781
+ def format_app_status(app, return_color=cyan)
782
+ out = ""
783
+ status_string = app['status']
784
+ if app['instanceCount'].to_i == 0
785
+ # show this instead of WARNING
786
+ out << "#{white}EMPTY#{return_color}"
787
+ elsif status_string == 'running'
788
+ out << "#{green}#{status_string.upcase}#{return_color}"
789
+ elsif status_string == 'stopped' or status_string == 'failed'
790
+ out << "#{red}#{status_string.upcase}#{return_color}"
791
+ elsif status_string == 'unknown'
792
+ out << "#{white}#{status_string.upcase}#{return_color}"
793
+ else
794
+ out << "#{yellow}#{status_string.upcase}#{return_color}"
795
+ end
796
+ out
781
797
  end
782
-
783
798
  end