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
@@ -275,7 +275,7 @@ module Morpheus::Cli::ProvisioningHelper
275
275
  payload['networkInterfaces'] = network_interfaces
276
276
  end
277
277
  rescue RestClient::Exception => e
278
- print_yellow_warning "Unable to load network options. Proceeding..."
278
+ print yellow,"Unable to load network options. Proceeding...",reset,"\n"
279
279
  print_rest_exception(e, options) if Morpheus::Logging.debug?
280
280
  end
281
281
  end
@@ -0,0 +1,29 @@
1
+ require 'morpheus/cli/cli_command'
2
+ require 'morpheus/cli/mixins/monitoring_helper'
3
+
4
+ class Morpheus::Cli::MonitoringAppsCommand
5
+ include Morpheus::Cli::CliCommand
6
+ include Morpheus::Cli::MonitoringHelper
7
+
8
+ set_command_name :'check-apps'
9
+ register_subcommands :list, :get, :add, :update, :remove, :quarantine, :history, :statistics
10
+ set_default_subcommand :list
11
+
12
+ set_command_hidden # remove me when implemented
13
+
14
+ def initialize()
15
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
+ end
17
+
18
+ def connect(opts)
19
+ @api_client = establish_remote_appliance_connection(opts)
20
+ @monitoring_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).monitoring
21
+ end
22
+
23
+ def handle(args)
24
+ handle_subcommand(args)
25
+ end
26
+
27
+ # todo: API updates and subcommands
28
+
29
+ end
@@ -0,0 +1,427 @@
1
+ require 'morpheus/cli/cli_command'
2
+ require 'morpheus/cli/mixins/monitoring_helper'
3
+
4
+ class Morpheus::Cli::MonitoringChecksCommand
5
+ include Morpheus::Cli::CliCommand
6
+ include Morpheus::Cli::MonitoringHelper
7
+
8
+ set_command_name :checks # :'monitoring-checks'
9
+ register_subcommands :list, :get, :update, :remove, :quarantine, :history #, :statistics
10
+ set_default_subcommand :list
11
+
12
+ def initialize()
13
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
14
+ end
15
+
16
+ def connect(opts)
17
+ @api_client = establish_remote_appliance_connection(opts)
18
+ @monitoring_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).monitoring
19
+ end
20
+
21
+ def handle(args)
22
+ handle_subcommand(args)
23
+ end
24
+
25
+ def list(args)
26
+ options = {}
27
+ params = {}
28
+ optparse = OptionParser.new do|opts|
29
+ opts.banner = subcommand_usage()
30
+ opts.on('--status LIST', Array, "Filter by status. open, closed") do |list|
31
+ params['status'] = list
32
+ end
33
+ opts.on('--severity LIST', Array, "Filter by severity. critical, warning, info") do |list|
34
+ params['severity'] = list
35
+ end
36
+ build_common_options(opts, options, [:list, :last_updated, :json, :csv, :fields, :json, :dry_run])
37
+ end
38
+ optparse.parse!(args)
39
+ connect(options)
40
+ begin
41
+ [:phrase, :offset, :max, :sort, :direction, :lastUpdated].each do |k|
42
+ params[k] = options[k] unless options[k].nil?
43
+ end
44
+ # JD: lastUpdated 500ing, checks don't have that property ? =o Fix it!
45
+
46
+ if options[:dry_run]
47
+ print_dry_run @monitoring_interface.checks.dry.list(params)
48
+ return
49
+ end
50
+
51
+ json_response = @monitoring_interface.checks.list(params)
52
+ if options[:json]
53
+ if options[:include_fields]
54
+ json_response = {"checks" => filter_data(json_response["checks"], options[:include_fields]) }
55
+ end
56
+ puts as_json(json_response, options)
57
+ return 0
58
+ end
59
+ if options[:csv]
60
+ puts records_as_csv(json_response['checks'], options)
61
+ return 0
62
+ end
63
+ checks = json_response['checks']
64
+ title = "Morpheus Checks"
65
+ subtitles = []
66
+ # if group
67
+ # subtitles << "Group: #{group['name']}".strip
68
+ # end
69
+ # if cloud
70
+ # subtitles << "Cloud: #{cloud['name']}".strip
71
+ # end
72
+ if params[:phrase]
73
+ subtitles << "Search: #{params[:phrase]}".strip
74
+ end
75
+ print_h1 title, subtitles
76
+ if checks.empty?
77
+ print cyan,"No checks found.",reset,"\n"
78
+ else
79
+ print_checks_table(checks, options)
80
+ print_results_pagination(json_response, {:label => "check", :n_label => "checks"})
81
+ end
82
+ print reset,"\n"
83
+ rescue RestClient::Exception => e
84
+ print_rest_exception(e, options)
85
+ exit 1
86
+ end
87
+ end
88
+
89
+ def get(args)
90
+ options = {}
91
+ optparse = OptionParser.new do|opts|
92
+ opts.banner = subcommand_usage("[id list]")
93
+ opts.on(nil,'--history', "Display Check History") do |val|
94
+ options[:show_history] = true
95
+ end
96
+ # opts.on(nil,'--statistics', "Display Statistics") do |val|
97
+ # options[:show_statistics] = true
98
+ # end
99
+ build_common_options(opts, options, [:json, :csv, :fields, :dry_run, :remote])
100
+ end
101
+ optparse.parse!(args)
102
+ if args.count < 1
103
+ puts optparse
104
+ exit 1
105
+ end
106
+ connect(options)
107
+ id_list = parse_id_list(args)
108
+ return run_command_for_each_arg(id_list) do |arg|
109
+ _get(arg, options)
110
+ end
111
+ end
112
+
113
+ def _get(id, options)
114
+
115
+ begin
116
+ check = find_check_by_name_or_id(id)
117
+
118
+ if options[:dry_run]
119
+ print_dry_run @monitoring_interface.checks.dry.get(check['id'])
120
+ return
121
+ end
122
+ json_response = @monitoring_interface.checks.get(check['id'])
123
+ check = json_response['check']
124
+
125
+ if options[:json]
126
+ if options[:include_fields]
127
+ json_response = {"check" => filter_data(json_response["check"], options[:include_fields]) }
128
+ end
129
+ puts as_json(json_response, options)
130
+ return 0
131
+ elsif options[:csv]
132
+ puts records_as_csv([json_response['check']], options)
133
+ return 0
134
+ end
135
+
136
+ print_h1 "Check Details"
137
+ print cyan
138
+ description_cols = {
139
+ "ID" => lambda {|it| it['id'] },
140
+ "Status" => lambda {|it| format_monitoring_check_status(it) },
141
+ "Name" => lambda {|it| it['name'] },
142
+ "Time" => lambda {|it| format_local_dt(it['lastRunDate']) },
143
+ "Availability" => lambda {|it| it['availability'] ? "#{it['availability'].to_f.round(3).to_s}%" : "N/A"},
144
+ "Response Time" => lambda {|it| it['lastTimer'] ? "#{it['lastTimer']}ms" : "N/A" },
145
+ "Last Metric" => lambda {|it| it['lastMetric'] ? "#{it['lastMetric']}" : "N/A" },
146
+ "Type" => 'checkType.name'
147
+ }
148
+ print_description_list(description_cols, check)
149
+
150
+ ## Chart Stats
151
+
152
+
153
+ ## Activity
154
+
155
+ ## Groups
156
+
157
+ check_groups = json_response["groups"]
158
+ if check_groups && !check_groups.empty?
159
+ print_h2 "Check Groups"
160
+ print as_pretty_table(check_groups, [:id, {"Check Group" => :name}], options)
161
+ else
162
+ # print "\n"
163
+ # puts "This check is not in any check groups."
164
+ end
165
+
166
+ ## Open Incidents
167
+
168
+ open_incidents = json_response["openIncidents"]
169
+ if open_incidents && !open_incidents.empty?
170
+ print_h2 "Open Incidents"
171
+ # puts "\n(table coming soon...)\n"
172
+ puts print JSON.pretty_generate(open_incidents)
173
+ # todo: move this to MonitoringHelper ?
174
+ # print_incidents_table(issues, options)
175
+ else
176
+ print "\n"
177
+ puts "No open incidents for this check"
178
+ end
179
+
180
+ ## History (plain old Hash)
181
+ if options[:show_history]
182
+ # history_items = json_response["history"]
183
+ # gotta go get it
184
+ history_json_response = @monitoring_interface.checks.history(check["id"], {})
185
+ history_items = history_json_response["history"] || history_json_response["events"] || history_json_response["issues"]
186
+ issues = history_items
187
+ if history_items && !history_items.empty?
188
+ print_h2 "History"
189
+ print_check_history_table(history_items, options)
190
+ print_results_pagination(history_json_response, {:label => "event", :n_label => "events"})
191
+ else
192
+ print "\n"
193
+ puts "No history found for this check"
194
+ end
195
+ end
196
+
197
+ ## Statistics (Hash)
198
+ if options[:show_statistics]
199
+ # todo....
200
+ end
201
+
202
+ print reset,"\n"
203
+
204
+ rescue RestClient::Exception => e
205
+ print_rest_exception(e, options)
206
+ exit 1
207
+ end
208
+ end
209
+
210
+ def history(args)
211
+ options = {}
212
+ params = {}
213
+ optparse = OptionParser.new do|opts|
214
+ opts.banner = subcommand_usage("[id] [options]")
215
+ # opts.on('--status LIST', Array, "Filter by status. open, closed") do |list|
216
+ # params['status'] = list
217
+ # end
218
+ opts.on('--severity LIST', Array, "Filter by severity. critical, warning, info") do |list|
219
+ params['severity'] = list
220
+ end
221
+ build_common_options(opts, options, [:list, :last_updated, :json, :csv, :fields, :json, :dry_run])
222
+ end
223
+ optparse.parse!(args)
224
+ if args.count < 1
225
+ puts optparse
226
+ exit 1
227
+ end
228
+ connect(options)
229
+ begin
230
+ check = find_check_by_name_or_id(args[0])
231
+ # return false if check.nil?
232
+
233
+ [:phrase, :offset, :max, :sort, :direction, :lastUpdated].each do |k|
234
+ params[k] = options[k] unless options[k].nil?
235
+ end
236
+ # JD: lastUpdated 500ing, checks don't have that property ? =o Fix it!
237
+
238
+ if options[:dry_run]
239
+ print_dry_run @monitoring_interface.checks.dry.history(check['id'], params)
240
+ return
241
+ end
242
+
243
+ json_response = @monitoring_interface.checks.history(check['id'], params)
244
+ if options[:json]
245
+ if options[:include_fields]
246
+ json_response = {"history" => filter_data(json_response["history"], options[:include_fields]) }
247
+ end
248
+ puts as_json(json_response, options)
249
+ return 0
250
+ end
251
+ if options[:csv]
252
+ puts records_as_csv(json_response['history'], options)
253
+ return 0
254
+ end
255
+ history_items = json_response['history']
256
+ title = "Check History: #{check['id']}: #{check['displayName'] || check['name']}"
257
+ subtitles = []
258
+ if params[:phrase]
259
+ subtitles << "Search: #{params[:phrase]}".strip
260
+ end
261
+ print_h1 title, subtitles
262
+ if history_items.empty?
263
+ print cyan,"No history found.",reset,"\n"
264
+ else
265
+ print_check_history_table(history_items, options)
266
+ print_results_pagination(json_response, {:label => "event", :n_label => "events"})
267
+ end
268
+ print reset,"\n"
269
+ rescue RestClient::Exception => e
270
+ print_rest_exception(e, options)
271
+ exit 1
272
+ end
273
+ end
274
+
275
+ def update(args)
276
+ options = {}
277
+ params = {}
278
+ optparse = OptionParser.new do|opts|
279
+ opts.banner = subcommand_usage("[id]")
280
+ build_common_options(opts, options, [:json, :dry_run, :quiet])
281
+ end
282
+ optparse.parse!(args)
283
+ if args.count < 1
284
+ puts optparse
285
+ exit 1
286
+ end
287
+ connect(options)
288
+
289
+ begin
290
+ check = find_check_by_name_or_id(args[0])
291
+
292
+ if params.empty?
293
+ print_red_alert "Specify atleast one option to update"
294
+ puts optparse
295
+ exit 1
296
+ end
297
+
298
+ payload = {
299
+ 'check' => {id: check["id"]}
300
+ }
301
+ payload['check'].merge!(params)
302
+
303
+ if options[:dry_run]
304
+ print_dry_run @monitoring_interface.checks.dry.update(check["id"], payload)
305
+ return
306
+ end
307
+
308
+ json_response = @monitoring_interface.checks.update(check["id"], payload)
309
+ if options[:json]
310
+ puts as_json(json_response, options)
311
+ elsif !options[:quiet]
312
+ print_green_success "Updated check #{check['id']}"
313
+ _get(check['id'], {})
314
+ end
315
+
316
+ rescue RestClient::Exception => e
317
+ print_rest_exception(e, options)
318
+ exit 1
319
+ end
320
+ end
321
+
322
+
323
+ def quarantine(args)
324
+ options = {}
325
+ params = {'enabled' => true}
326
+ optparse = OptionParser.new do|opts|
327
+ opts.banner = subcommand_usage("[id list]")
328
+ # this one is a bit weird.. it's a way to toggle incident.inUptime
329
+ # opts.on("--enabled BOOL", String, "Quarantine can be removed with --enabled false") do |val|
330
+ # params['enabled'] = ['on','true'].include?(val.to_s.downcase)
331
+ # end
332
+ opts.on("-d", "--disabled", "Disable Quarantine instead") do
333
+ params['enabled'] = false
334
+ end
335
+ build_common_options(opts, options, [:json, :dry_run, :quiet])
336
+ end
337
+ optparse.parse!(args)
338
+ if args.count < 1
339
+ puts optparse
340
+ exit 1
341
+ end
342
+ connect(options)
343
+
344
+ begin
345
+ check = find_check_by_name_or_id(args[0])
346
+
347
+ if params.empty?
348
+ print_red_alert "Specify atleast one option to update"
349
+ puts optparse
350
+ exit 1
351
+ end
352
+
353
+ # payload = {
354
+ # 'check' => {id: check["id"]}
355
+ # }
356
+ # payload['check'].merge!(check)
357
+ payload = params
358
+
359
+ if options[:dry_run]
360
+ print_dry_run @monitoring_interface.checks.dry.update(check["id"], payload)
361
+ return
362
+ end
363
+
364
+ json_response = @monitoring_interface.checks.update(check["id"], payload)
365
+ if options[:json]
366
+ puts as_json(json_response, options)
367
+ elsif !options[:quiet]
368
+ print_green_success "Quarantined check #{check['id']}"
369
+ _get(check['id'], {})
370
+ end
371
+
372
+ rescue RestClient::Exception => e
373
+ print_rest_exception(e, options)
374
+ exit 1
375
+ end
376
+ end
377
+
378
+ def remove(args)
379
+ options = {}
380
+ optparse = OptionParser.new do|opts|
381
+ opts.banner = subcommand_usage("[id]")
382
+ build_common_options(opts, options, [:json, :dry_run, :quiet])
383
+ end
384
+ optparse.parse!(args)
385
+ if args.count < 1
386
+ puts optparse
387
+ return 127
388
+ end
389
+ connect(options)
390
+
391
+ begin
392
+ check = find_check_by_name_or_id(args[0])
393
+
394
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to delete check '#{check['name']}'?", options)
395
+ return false
396
+ end
397
+
398
+ # payload = {
399
+ # 'check' => {id: check["id"]}
400
+ # }
401
+ # payload['check'].merge!(check)
402
+ payload = params
403
+
404
+ if options[:dry_run]
405
+ print_dry_run @monitoring_interface.checks.dry.destroy(check["id"])
406
+ return
407
+ end
408
+
409
+ json_response = @monitoring_interface.checks.destroy(check["id"])
410
+ if options[:json]
411
+ puts as_json(json_response, options)
412
+ elsif !options[:quiet]
413
+ print_green_success "Deleted check #{check['id']}"
414
+ end
415
+ return 0, nil
416
+ rescue RestClient::Exception => e
417
+ print_rest_exception(e, options)
418
+ return 1
419
+ end
420
+ end
421
+
422
+
423
+ private
424
+
425
+
426
+
427
+ end