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
@@ -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