morpheus-cli 3.1.2.1 → 3.2.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/morpheus/api/api_client.rb +6 -2
  3. data/lib/morpheus/api/license_interface.rb +7 -0
  4. data/lib/morpheus/api/monitoring_apps_interface.rb +15 -2
  5. data/lib/morpheus/api/{checks_interface.rb → monitoring_checks_interface.rb} +8 -21
  6. data/lib/morpheus/api/monitoring_groups_interface.rb +23 -2
  7. data/lib/morpheus/api/{incidents_interface.rb → monitoring_incidents_interface.rb} +5 -5
  8. data/lib/morpheus/api/monitoring_interface.rb +4 -4
  9. data/lib/morpheus/api/user_groups_interface.rb +65 -0
  10. data/lib/morpheus/cli.rb +1 -0
  11. data/lib/morpheus/cli/curl_command.rb +9 -7
  12. data/lib/morpheus/cli/dot_file.rb +11 -5
  13. data/lib/morpheus/cli/echo_command.rb +27 -3
  14. data/lib/morpheus/cli/license.rb +109 -20
  15. data/lib/morpheus/cli/login.rb +2 -0
  16. data/lib/morpheus/cli/logout.rb +2 -0
  17. data/lib/morpheus/cli/mixins/monitoring_helper.rb +97 -37
  18. data/lib/morpheus/cli/mixins/print_helper.rb +5 -2
  19. data/lib/morpheus/cli/monitoring_apps_command.rb +564 -9
  20. data/lib/morpheus/cli/monitoring_checks_command.rb +326 -93
  21. data/lib/morpheus/cli/monitoring_contacts_command.rb +2 -2
  22. data/lib/morpheus/cli/monitoring_groups_command.rb +540 -10
  23. data/lib/morpheus/cli/monitoring_incidents_command.rb +88 -56
  24. data/lib/morpheus/cli/remote.rb +6 -0
  25. data/lib/morpheus/cli/roles.rb +1 -1
  26. data/lib/morpheus/cli/set_prompt_command.rb +1 -0
  27. data/lib/morpheus/cli/shell.rb +17 -8
  28. data/lib/morpheus/cli/user_groups_command.rb +574 -0
  29. data/lib/morpheus/cli/users.rb +221 -115
  30. data/lib/morpheus/cli/version.rb +1 -1
  31. data/morpheus-cli.gemspec +1 -2
  32. metadata +11 -8
@@ -75,6 +75,8 @@ class Morpheus::Cli::Login
75
75
  # check to see if we got credentials, or just look at login_result above...
76
76
  creds = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials() # .load_saved_credentials(true)
77
77
 
78
+ # recalcuate echo vars
79
+ Morpheus::Cli::Echo.recalculate_variable_map()
78
80
  # recalculate shell prompt after this change
79
81
  if Morpheus::Cli::Shell.instance
80
82
  Morpheus::Cli::Shell.instance.reinitialize()
@@ -60,6 +60,8 @@ class Morpheus::Cli::Logout
60
60
  puts "#{cyan}Logged out of #{@appliance_name}. Goodbye.#{reset}"
61
61
  end
62
62
  end
63
+ # recalcuate echo vars
64
+ Morpheus::Cli::Echo.recalculate_variable_map()
63
65
  # recalculate shell prompt after this change
64
66
  if Morpheus::Cli::Shell.instance
65
67
  Morpheus::Cli::Shell.instance.reinitialize()
@@ -206,62 +206,73 @@ module Morpheus::Cli::MonitoringHelper
206
206
 
207
207
  # Checks
208
208
 
209
- def format_monitoring_check_status(check, return_color=cyan)
210
- #<morph:statusIcon unknown="${!check.lastRunDate}" muted="${!check.createIncident}" failure="${check.lastCheckStatus == 'error'}" health="${check.health}" class="pull-left"/>
209
+ def format_monitoring_check_status(check, include_msg=false, return_color=cyan)
211
210
  out = ""
212
- muted = !check['createIncident']
213
- status_string = check['lastCheckStatus'].to_s
211
+ unknown = check['lastRunDate'].nil?
214
212
  failure = check['lastCheckStatus'] == 'error'
215
- health = check['health'] # todo: examine at this too?
216
- if failure
217
- out << "#{red}#{status_string.capitalize}#{return_color}"
213
+ health = check['health']
214
+ muted = check['createIncident'] == false
215
+ status_string = check['lastCheckStatus'].to_s # null for groups, ignore?
216
+
217
+ if unknown
218
+ out << "#{white}UNKNOWN#{return_color}"
219
+ elsif failure || health == 0
220
+ if include_msg && check['lastError']
221
+ out << "#{red}ERROR - #{check['lastError']}#{return_color}"
222
+ else
223
+ out << "#{red}ERROR#{return_color}"
224
+ end
225
+ elsif health.to_i >= 10
226
+ out << "#{green}HEALTHY#{return_color}"
218
227
  else
219
- out << "#{cyan}#{status_string.capitalize}#{return_color}"
228
+ out << "#{yellow}WARNING#{return_color}"
220
229
  end
221
230
  if muted
222
- out << "(muted)"
231
+ out << " (MUTED)"
223
232
  end
224
233
  out
225
234
  end
226
235
 
227
236
  def format_monitoring_check_last_metric(check)
228
- #<td class="last-metric-col">${check.lastMetric} ${check.lastMetric ? checkTypes.find{ type -> type.id == check.checkTypeId}?.metricName : ''}</td>
229
- out = ""
230
- out << "#{check['lastMetric']} "
231
- # todo:
232
- out.strip
237
+ if check['lastMetric']
238
+ metric_name = check['checkType'] ? check['checkType']['metricName'] : nil
239
+ if metric_name
240
+ "#{check['lastMetric']} #{metric_name}"
241
+ else
242
+ "#{check['lastMetric']}"
243
+ end
244
+ else
245
+ "N/A"
246
+ end
233
247
  end
234
248
 
235
249
  def format_monitoring_check_type(check)
236
- #<td class="check-type-col"><div class="check-type-icon ${morph.checkTypeCode(id:check.checkTypeId, checkTypes:checkTypes)}"></div></td>
237
- # return get_object_value(check, 'checkType.name') # this works too
238
250
  out = ""
239
- if check && check['checkType'] && check['checkType']['name']
240
- out << check['checkType']['name']
241
- elsif check['checkTypeId']
242
- out << check['checkTypeId'].to_s
243
- elsif !check.empty?
244
- out << check.to_s
251
+ if check['checkType']
252
+ if check['checkType']['code'] == 'mixedCheck' || check['checkType']['code'] == 'mixed'
253
+ out = check['checkType']["name"] || "Mixed"
254
+ else
255
+ out = check['checkType']["name"] || ""
256
+ end
245
257
  end
246
- out.strip! + "WEEEEEE"
258
+ out
247
259
  end
248
260
 
249
- def print_checks_table(incidents, opts={})
261
+ def print_checks_table(checks, opts={})
250
262
  columns = [
251
263
  {"ID" => lambda {|check| check['id'] } },
252
264
  {"STATUS" => lambda {|check| format_monitoring_check_status(check) } },
253
265
  {"NAME" => lambda {|check| check['name'] } },
254
- {"TIME" => lambda {|check| format_local_dt(check['lastRunDate']) } },
266
+ {"TIME" => lambda {|check| check['lastRunDate'] ? format_local_dt(check['lastRunDate']) : "N/A" } },
255
267
  {"AVAILABILITY" => {display_method: lambda {|check| check['availability'] ? "#{check['availability'].to_f.round(3).to_s}%" : "N/A"} }, justify: "center" },
256
268
  {"RESPONSE TIME" => {display_method: lambda {|check| check['lastTimer'] ? "#{check['lastTimer']}ms" : "N/A" } }, justify: "center" },
257
- {"LAST METRIC" => {display_method: lambda {|check| check['lastMetric'] ? "#{check['lastMetric']}" : "N/A" } }, justify: "center" },
258
- {"TYPE" => 'checkType.name'},
259
-
269
+ {"LAST METRIC" => {display_method: lambda {|check| format_monitoring_check_last_metric(check) } }, justify: "center" },
270
+ {"TYPE" => lambda {|check| format_monitoring_check_type(check) } },
260
271
  ]
261
272
  if opts[:include_fields]
262
273
  columns = opts[:include_fields]
263
274
  end
264
- print as_pretty_table(incidents, columns, opts)
275
+ print as_pretty_table(checks, columns, opts)
265
276
  end
266
277
 
267
278
  def print_check_history_table(history_items, opts={})
@@ -372,7 +383,7 @@ module Morpheus::Cli::MonitoringHelper
372
383
 
373
384
  def find_check_group_by_name(name)
374
385
  json_results = monitoring_interface.groups.list({name: name})
375
- groups = json_results["groups"]
386
+ groups = json_results["checkGroups"]
376
387
  if groups.empty?
377
388
  print_red_alert "Check Group not found by name #{name}"
378
389
  exit 1 # return nil
@@ -388,20 +399,37 @@ module Morpheus::Cli::MonitoringHelper
388
399
  end
389
400
  end
390
401
 
402
+ def print_check_groups_table(check_groups, opts={})
403
+ columns = [
404
+ {"ID" => lambda {|check| check['id'] } },
405
+ {"STATUS" => lambda {|check| format_monitoring_check_status(check) } },
406
+ {"NAME" => lambda {|check| check['name'] } },
407
+ {"TIME" => lambda {|check| check['lastRunDate'] ? format_local_dt(check['lastRunDate']) : "N/A" } },
408
+ {"AVAILABILITY" => {display_method: lambda {|check| check['availability'] ? "#{check['availability'].to_f.round(3).to_s}%" : "N/A"} }, justify: "center" },
409
+ {"RESPONSE TIME" => {display_method: lambda {|check| check['lastTimer'] ? "#{check['lastTimer']}ms" : "N/A" } }, justify: "center" },
410
+ # {"LAST METRIC" => {display_method: lambda {|check| format_monitoring_check_last_metric(check) } }, justify: "center" },
411
+ {"TYPE" => lambda {|check| format_monitoring_check_type(check) } },
412
+ ]
413
+ if opts[:include_fields]
414
+ columns = opts[:include_fields]
415
+ end
416
+ print as_pretty_table(check_groups, columns, opts)
417
+ end
418
+
391
419
  # Monitoring apps
392
420
 
393
- def find_app_by_name_or_id(val)
421
+ def find_monitoring_app_by_name_or_id(val)
394
422
  if val.to_s =~ /\A\d{1,}\Z/
395
- return find_app_by_id(val)
423
+ return find_monitoring_app_by_id(val)
396
424
  else
397
- return find_app_by_name(val)
425
+ return find_monitoring_app_by_name(val)
398
426
  end
399
427
  end
400
428
 
401
- def find_app_by_id(id)
429
+ def find_monitoring_app_by_id(id)
402
430
  begin
403
431
  json_response = monitoring_interface.apps.get(id.to_i)
404
- return json_response['app']
432
+ return json_response["monitorApp"] || json_response["app"]
405
433
  rescue RestClient::Exception => e
406
434
  if e.response && e.response.code == 404
407
435
  print_red_alert "Monitor App not found by id #{id}"
@@ -412,9 +440,9 @@ module Morpheus::Cli::MonitoringHelper
412
440
  end
413
441
  end
414
442
 
415
- def find_app_by_name(name)
443
+ def find_monitoring_app_by_name(name)
416
444
  json_results = monitoring_interface.apps.list({name: name})
417
- apps = json_results["apps"]
445
+ apps = json_results["monitorApps"] || json_results["apps"]
418
446
  if apps.empty?
419
447
  print_red_alert "Monitor App not found by name #{name}"
420
448
  exit 1 # return nil
@@ -430,5 +458,37 @@ module Morpheus::Cli::MonitoringHelper
430
458
  end
431
459
  end
432
460
 
461
+ def print_monitoring_apps_table(apps, opts={})
462
+ columns = [
463
+ {"ID" => lambda {|app| app['id'] } },
464
+ {"STATUS" => lambda {|app| format_monitoring_check_status(app) } },
465
+ {"NAME" => lambda {|app| app['name'] } },
466
+ # {"DESCRIPTION" => lambda {|app| app['description'] } },
467
+ {"TIME" => lambda {|app| app['lastRunDate'] ? format_local_dt(app['lastRunDate']) : "N/A" } },
468
+ {"AVAILABILITY" => {display_method: lambda {|app| app['availability'] ? "#{app['availability'].to_f.round(3).to_s}%" : "N/A"} }, justify: "center" },
469
+ {"RESPONSE TIME" => {display_method: lambda {|app| app['lastTimer'] ? "#{app['lastTimer']}ms" : "N/A" } }, justify: "center" },
470
+ #{"LAST METRIC" => {display_method: lambda {|app| app['lastMetric'] ? "#{app['lastMetric']}" : "N/A" } }, justify: "center" },
471
+ {"CHECKS" => lambda {|app|
472
+ checks = app['checks']
473
+ checks_str = ""
474
+ if checks && checks.size > 0
475
+ checks_str = "#{checks.size} #{checks.size == 1 ? 'check' : 'checks'}"
476
+ # checks_str << " [#{checks.join(', ')}]"
477
+ end
478
+ check_groups = app['checkGroups']
479
+ check_groups_str = ""
480
+ if check_groups && check_groups.size > 0
481
+ check_groups_str = "#{check_groups.size} #{check_groups.size == 1 ? 'group' : 'groups'}"
482
+ # check_groups_str << " [#{check_groups.join(', ')}]"
483
+ end
484
+ [checks_str, check_groups_str].reject {|s| s.empty? }.join(", ")
485
+ } },
486
+
487
+ ]
488
+ if opts[:include_fields]
489
+ columns = opts[:include_fields]
490
+ end
491
+ print as_pretty_table(apps, columns, opts)
492
+ end
433
493
 
434
494
  end
@@ -753,9 +753,9 @@ module Morpheus::Cli::PrintHelper
753
753
  # if include_fields
754
754
  # json_fields_for = options[:json_fields_for] || options[:fields_for] || options[:root_field]
755
755
  # if json_fields_for && data[json_fields_for]
756
- # data[json_fields_for] = filtered_data(data[json_fields_for], include_fields)
756
+ # data[json_fields_for] = filter_data(data[json_fields_for], include_fields)
757
757
  # else
758
- # data = filtered_data(data, include_fields)
758
+ # data = filter_data(data, include_fields)
759
759
  # end
760
760
  # end
761
761
  do_pretty = options.key?(:pretty_json) ? options[:pretty_json] : true
@@ -783,6 +783,9 @@ module Morpheus::Cli::PrintHelper
783
783
  if !data
784
784
  return "null" # "No data"
785
785
  end
786
+ # if opts[:include_fields]
787
+ # data = filter_data(data, opts[:include_fields])
788
+ # end
786
789
  begin
787
790
  out << data.to_yaml
788
791
  rescue => err
@@ -5,15 +5,10 @@ class Morpheus::Cli::MonitoringAppsCommand
5
5
  include Morpheus::Cli::CliCommand
6
6
  include Morpheus::Cli::MonitoringHelper
7
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
8
+ set_command_name :'monitor-apps'
13
9
 
14
- def initialize()
15
- # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
- end
10
+ register_subcommands :list, :get, :add, :update, :remove
11
+ register_subcommands :mute, :unmute #, :history, :statistics
17
12
 
18
13
  def connect(opts)
19
14
  @api_client = establish_remote_appliance_connection(opts)
@@ -24,6 +19,566 @@ class Morpheus::Cli::MonitoringAppsCommand
24
19
  handle_subcommand(args)
25
20
  end
26
21
 
27
- # todo: API updates and subcommands
22
+ def list(args)
23
+ options = {}
24
+ params = {}
25
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
26
+ opts.banner = subcommand_usage()
27
+ opts.on('--status LIST', Array, "Filter by status. error,healthy,warning,muted") do |list|
28
+ params['status'] = list
29
+ end
30
+ build_common_options(opts, options, [:list, :last_updated, :json, :yaml, :csv, :fields, :dry_run, :remote])
31
+ end
32
+ optparse.parse!(args)
33
+ connect(options)
34
+ begin
35
+ [:phrase, :offset, :max, :sort, :direction, :lastUpdated].each do |k|
36
+ params[k] = options[k] unless options[k].nil?
37
+ end
38
+
39
+ if options[:dry_run]
40
+ print_dry_run @monitoring_interface.apps.dry.list(params)
41
+ return
42
+ end
43
+
44
+ json_response = @monitoring_interface.apps.list(params)
45
+ if options[:include_fields]
46
+ json_response = {"monitorApps" => filter_data(json_response["monitorApps"], options[:include_fields]) }
47
+ end
48
+ if options[:json]
49
+ puts as_json(json_response, options)
50
+ return 0
51
+ elsif options[:csv]
52
+ puts records_as_csv(json_response['monitorApps'], options)
53
+ return 0
54
+ elsif options[:yaml]
55
+ puts as_yaml(json_response, options)
56
+ return 0
57
+ end
58
+ monitor_apps = json_response['monitorApps']
59
+ title = "Morpheus Monitoring Apps"
60
+ subtitles = []
61
+ # if app
62
+ # subtitles << "App: #{app['name']}".strip
63
+ # end
64
+ # if cloud
65
+ # subtitles << "Cloud: #{cloud['name']}".strip
66
+ # end
67
+ if params[:phrase]
68
+ subtitles << "Search: #{params[:phrase]}".strip
69
+ end
70
+ print_h1 title, subtitles
71
+ if monitor_apps.empty?
72
+ print cyan,"No monitoring apps found.",reset,"\n"
73
+ else
74
+ print_monitoring_apps_table(monitor_apps, options)
75
+ print_results_pagination(json_response, {:label => "monitoring app", :n_label => "monitoring apps"})
76
+ # print_results_pagination(json_response)
77
+ end
78
+ print reset,"\n"
79
+ rescue RestClient::Exception => e
80
+ print_rest_exception(e, options)
81
+ exit 1
82
+ end
83
+ end
84
+
85
+ def get(args)
86
+ options = {}
87
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
88
+ opts.banner = subcommand_usage("[id list]")
89
+ opts.on(nil,'--history', "Display Monitoring App History") do |val|
90
+ options[:show_history] = true
91
+ end
92
+ # opts.on(nil,'--statistics', "Display Statistics") do |val|
93
+ # options[:show_statistics] = true
94
+ # end
95
+ build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
96
+ end
97
+ optparse.parse!(args)
98
+ if args.count < 1
99
+ puts optparse
100
+ exit 1
101
+ end
102
+ connect(options)
103
+ id_list = parse_id_list(args)
104
+ return run_command_for_each_arg(id_list) do |arg|
105
+ _get(arg, options)
106
+ end
107
+ end
108
+
109
+ def _get(id, options)
110
+
111
+ begin
112
+ monitor_app = find_monitoring_app_by_name_or_id(id)
113
+
114
+ if options[:dry_run]
115
+ print_dry_run @monitoring_interface.apps.dry.get(monitor_app['id'])
116
+ return
117
+ end
118
+ json_response = @monitoring_interface.apps.get(monitor_app['id'])
119
+ monitor_app = json_response['monitorApp']
120
+ if options[:include_fields]
121
+ json_response = {"monitorApp" => filter_data(json_response["monitorApp"], options[:include_fields]) }
122
+ end
123
+ if options[:json]
124
+ puts as_json(json_response, options)
125
+ return 0
126
+ elsif options[:yaml]
127
+ puts as_yaml(json_response, options)
128
+ return 0
129
+ elsif options[:csv]
130
+ puts records_as_csv([json_response['monitorApp']], options)
131
+ return 0
132
+ end
133
+
134
+ print_h1 "Monitoring App Details"
135
+ print cyan
136
+ description_cols = {
137
+ "ID" => lambda {|it| it['id'] },
138
+ "Status" => lambda {|it| format_monitoring_check_status(it, true) },
139
+ "Name" => lambda {|it| it['name'] },
140
+ "Description" => lambda {|it| it['description'] },
141
+ "Time" => lambda {|it| format_local_dt(it['lastRunDate']) },
142
+ "Availability" => lambda {|it| it['availability'] ? "#{it['availability'].to_f.round(3).to_s}%" : "N/A"},
143
+ "Response Time" => lambda {|it| it['lastTimer'] ? "#{it['lastTimer']}ms" : "N/A" }
144
+ }
145
+ print_description_list(description_cols, monitor_app)
146
+
147
+ ## Chart Stats
148
+
149
+
150
+ ## Checks in this app
151
+ checks = json_response["checks"]
152
+ if checks && !checks.empty?
153
+ print_h2 "Checks"
154
+ print_checks_table(checks, options)
155
+ else
156
+ # print "\n"
157
+ # puts "No checks in this monitoring app"
158
+ end
159
+
160
+ ## Check Groups in this app
161
+ check_groups = json_response["checkGroups"]
162
+ if check_groups && !check_groups.empty?
163
+ print_h2 "Groups"
164
+ print_check_groups_table(check_groups, options)
165
+ else
166
+ # print "\n"
167
+ # puts "No check groups in this monitoring app"
168
+ end
169
+
170
+ ## Open Incidents
171
+ open_incidents = json_response["openIncidents"]
172
+ if open_incidents && !open_incidents.empty?
173
+ print_h2 "Open Incidents"
174
+ # puts "\n(table coming soon...)\n"
175
+ puts JSON.pretty_generate(open_incidents)
176
+ # todo: move this to MonitoringHelper ?
177
+ # print_incidents_table(issues, options)
178
+ else
179
+ print "\n", cyan
180
+ puts "No open incidents for this monitoring app"
181
+ end
182
+
183
+ ## History (plain old Hash)
184
+ if options[:show_history]
185
+ # history_items = json_response["history"]
186
+ # gotta go get it
187
+ history_json_response = @monitoring_interface.apps.history(monitor_app["id"], {})
188
+ history_items = history_json_response["history"] || history_json_response["events"] || history_json_response["issues"]
189
+ issues = history_items
190
+ if history_items && !history_items.empty?
191
+ print_h2 "History"
192
+ print_check_history_table(history_items, options)
193
+ print_results_pagination(history_json_response, {:label => "event", :n_label => "events"})
194
+ else
195
+ print "\n"
196
+ puts "No history found for this monitoring app"
197
+ end
198
+ end
199
+
200
+ ## Statistics (Hash)
201
+ if options[:show_statistics]
202
+ # todo....
203
+ end
204
+
205
+ print reset,"\n"
206
+
207
+ rescue RestClient::Exception => e
208
+ print_rest_exception(e, options)
209
+ exit 1
210
+ end
211
+ end
212
+
213
+ def history(args)
214
+ options = {}
215
+ params = {}
216
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
217
+ opts.banner = subcommand_usage("[name] [options]")
218
+ # opts.on('--status LIST', Array, "Filter by status. open, closed") do |list|
219
+ # params['status'] = list
220
+ # end
221
+ opts.on('--severity LIST', Array, "Filter by severity. critical, warning, info") do |list|
222
+ params['severity'] = list
223
+ end
224
+ build_common_options(opts, options, [:list, :last_updated, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
225
+ end
226
+ optparse.parse!(args)
227
+ if args.count < 1
228
+ puts optparse
229
+ exit 1
230
+ end
231
+ connect(options)
232
+ begin
233
+ monitor_app = find_monitoring_app_by_name_or_id(args[0])
234
+ return 1 if monitor_app.nil?
235
+
236
+ [:phrase, :offset, :max, :sort, :direction, :lastUpdated].each do |k|
237
+ params[k] = options[k] unless options[k].nil?
238
+ end
239
+ # JD: lastUpdated 500ing, checks don't have that property ? =o Fix it!
240
+
241
+ if options[:dry_run]
242
+ print_dry_run @monitoring_interface.apps.dry.history(monitor_app['id'], params)
243
+ return
244
+ end
245
+
246
+ json_response = @monitoring_interface.apps.history(monitor_app['id'], params)
247
+ if options[:json]
248
+ if options[:include_fields]
249
+ json_response = {"history" => filter_data(json_response["history"], options[:include_fields]) }
250
+ end
251
+ puts as_json(json_response, options)
252
+ return 0
253
+ end
254
+ if options[:csv]
255
+ puts records_as_csv(json_response['history'], options)
256
+ return 0
257
+ end
258
+ history_items = json_response['history']
259
+ title = "Monitoring App History: #{monitor_app['name']}"
260
+ subtitles = []
261
+ if params[:phrase]
262
+ subtitles << "Search: #{params[:phrase]}".strip
263
+ end
264
+ print_h1 title, subtitles
265
+ if history_items.empty?
266
+ print cyan,"No history found.",reset,"\n"
267
+ else
268
+ print_check_history_table(history_items, options)
269
+ print_results_pagination(json_response, {:label => "event", :n_label => "events"})
270
+ end
271
+ print reset,"\n"
272
+ rescue RestClient::Exception => e
273
+ print_rest_exception(e, options)
274
+ exit 1
275
+ end
276
+ end
277
+
278
+ def add(args)
279
+ options = {}
280
+ params = {'inUptime' => true, 'severity' => 'critical'}
281
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
282
+ opts.banner = subcommand_usage("[name]")
283
+ opts.on('--name VALUE', String, "Name") do |val|
284
+ params['name'] = val
285
+ end
286
+ opts.on('--description VALUE', String, "Description") do |val|
287
+ params['description'] = val
288
+ end
289
+ opts.on('--minHappy VALUE', String, "Min Checks. This specifies the minimum number of checks within the app that must be happy to keep the app from becoming unhealthy.") do |val|
290
+ params['minHappy'] = val.to_i
291
+ end
292
+ opts.on('--severity VALUE', String, "Max Severity. Determines the maximum severity level this app can incur on an incident when failing. Default is critical") do |val|
293
+ params['severity'] = val
294
+ end
295
+ opts.on('--inUptime [on|off]', String, "Affects Availability. Default is on.") do |val|
296
+ params['inUptime'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
297
+ end
298
+ opts.on('--checks LIST', Array, "Checks to include in this app, comma separated list of IDs") do |list|
299
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
300
+ params['checks'] = []
301
+ else
302
+ params['checks'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
303
+ end
304
+ end
305
+ opts.on('--checkGroups LIST', Array, "Check Groups to include in this app, comma separated list of IDs") do |list|
306
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
307
+ params['checkGroups'] = []
308
+ else
309
+ params['checkGroups'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
310
+ end
311
+ end
312
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
313
+ opts.footer = "Create a new app of monitoring checks." + "\n" +
314
+ "[name] is required and can be passed as --name instead."
315
+ end
316
+ optparse.parse!(args)
317
+ if args.count > 1
318
+ print_error Morpheus::Terminal.angry_prompt
319
+ puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
320
+ return 1
321
+ end
322
+ # support [name] as first argument
323
+ if args[0]
324
+ params['name'] = args[0]
325
+ end
326
+ connect(options)
327
+ begin
328
+ # construct payload
329
+ payload = nil
330
+ if options[:payload]
331
+ payload = options[:payload]
332
+ else
333
+ # merge -O options into normally parsed options
334
+ params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
335
+ if params['checks']
336
+ params['checks'] = params['checks'].collect {|it| it.to_i }
337
+ end
338
+ if params['checkGroups']
339
+ params['checkGroups'] = params['checkGroups'].collect {|it| it.to_i }
340
+ end
341
+ # todo: prompt?
342
+ payload = {'monitorApp' => params}
343
+ end
344
+ if options[:dry_run]
345
+ print_dry_run @monitoring_interface.apps.dry.create(payload)
346
+ return
347
+ end
348
+ json_response = @monitoring_interface.apps.create(payload)
349
+ if options[:json]
350
+ puts as_json(json_response, options)
351
+ elsif !options[:quiet]
352
+ monitor_app = json_response['monitorApp']
353
+ print_green_success "Added monitoring app #{monitor_app['name']}"
354
+ _get(monitor_app['id'], {})
355
+ end
356
+ return 0
357
+ rescue RestClient::Exception => e
358
+ print_rest_exception(e, options)
359
+ exit 1
360
+ end
361
+ end
362
+
363
+ def update(args)
364
+ options = {}
365
+ params = {}
366
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
367
+ opts.banner = subcommand_usage("[name]")
368
+ opts.on('--name VALUE', String, "Name") do |val|
369
+ params['name'] = val
370
+ end
371
+ opts.on('--description VALUE', String, "Description") do |val|
372
+ params['description'] = val
373
+ end
374
+ opts.on('--minHappy VALUE', String, "Min Checks. This specifies the minimum number of checks within the app that must be happy to keep the app from becoming unhealthy.") do |val|
375
+ params['minHappy'] = val.to_i
376
+ end
377
+ opts.on('--severity VALUE', String, "Max Severity. Determines the maximum severity level this app can incur on an incident when failing. Default is critical") do |val|
378
+ params['severity'] = val
379
+ end
380
+ opts.on('--inUptime [on|off]', String, "Affects Availability. Default is on.") do |val|
381
+ params['inUptime'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
382
+ end
383
+ opts.on('--checks LIST', Array, "Checks to include in this app, comma separated list of IDs") do |list|
384
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
385
+ params['checks'] = []
386
+ else
387
+ params['checks'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
388
+ end
389
+ end
390
+ opts.on('--checkGroups LIST', Array, "Check Groups to include in this app, comma separated list of IDs") do |list|
391
+ if list.size == 1 && list[0] == 'null' # hacky way to clear it
392
+ params['checkGroups'] = []
393
+ else
394
+ params['checkGroups'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
395
+ end
396
+ end
397
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
398
+ opts.footer = "Update a monitoring app." + "\n" +
399
+ "[name] is required. This is the name or id of a monitoring app."
400
+ end
401
+ optparse.parse!(args)
402
+ if args.count != 1
403
+ print_error Morpheus::Terminal.angry_prompt
404
+ puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
405
+ return 1
406
+ end
407
+ connect(options)
408
+ begin
409
+ monitor_app = find_monitoring_app_by_name_or_id(args[0])
410
+ # construct payload
411
+ payload = nil
412
+ if options[:payload]
413
+ payload = options[:payload]
414
+ else
415
+ # merge -O options into normally parsed options
416
+ params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
417
+ if params['checks']
418
+ params['checks'] = params['checks'].collect {|it| it.to_i }
419
+ end
420
+ if params['checkGroups']
421
+ params['checkGroups'] = params['checkGroups'].collect {|it| it.to_i }
422
+ end
423
+ # todo: prompt?
424
+ payload = {'monitorApp' => params}
425
+ end
426
+ if options[:dry_run]
427
+ print_dry_run @monitoring_interface.apps.dry.update(monitor_app["id"], payload)
428
+ return
429
+ end
430
+ json_response = @monitoring_interface.apps.update(monitor_app["id"], payload)
431
+ if options[:json]
432
+ puts as_json(json_response, options)
433
+ elsif !options[:quiet]
434
+ print_green_success "Updated monitoring app #{monitor_app['name']}"
435
+ _get(monitor_app['id'], {})
436
+ end
437
+ return 0
438
+ rescue RestClient::Exception => e
439
+ print_rest_exception(e, options)
440
+ exit 1
441
+ end
442
+ end
443
+
444
+ def mute(args)
445
+ options = {}
446
+ params = {'enabled' => true}
447
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
448
+ opts.banner = subcommand_usage("[name]")
449
+ opts.on(nil, "--disable", "Unmute instead, the same as the unmute command") do
450
+ params['enabled'] = false
451
+ end
452
+ opts.footer = "Mute a monitoring app. This prevents it from creating new incidents." + "\n" +
453
+ "[name] is required. This is the name or id of a monitoring app."
454
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
455
+ end
456
+ optparse.parse!(args)
457
+ if args.count < 1
458
+ puts optparse
459
+ exit 1
460
+ end
461
+ connect(options)
462
+ begin
463
+ monitor_app = find_monitoring_app_by_name_or_id(args[0])
464
+ # construct payload
465
+ payload = nil
466
+ if options[:payload]
467
+ payload = options[:payload]
468
+ else
469
+ payload = params
470
+ end
471
+ if options[:dry_run]
472
+ print_dry_run @monitoring_interface.apps.dry.quarantine(monitor_app["id"], payload)
473
+ return 0
474
+ end
475
+ json_response = @monitoring_interface.apps.quarantine(monitor_app["id"], payload)
476
+ if options[:json]
477
+ puts as_json(json_response, options)
478
+ elsif !options[:quiet]
479
+ if params['enabled']
480
+ print_green_success "Muted app #{monitor_app['name']}"
481
+ else
482
+ print_green_success "Unmuted app #{monitor_app['name']}"
483
+ end
484
+ _get(monitor_app['id'], {})
485
+ end
486
+ return 0
487
+ rescue RestClient::Exception => e
488
+ print_rest_exception(e, options)
489
+ exit 1
490
+ end
491
+ end
492
+
493
+ def unmute(args)
494
+ options = {}
495
+ params = {'enabled' => false}
496
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
497
+ opts.banner = subcommand_usage("[name]")
498
+ build_common_options(opts, options, [:payload, :json, :dry_run, :remote, :quiet])
499
+ opts.footer = "Unmute a monitoring app." + "\n" +
500
+ "[name] is required. This is the name or id of a monitoring app."
501
+ end
502
+ optparse.parse!(args)
503
+ if args.count < 1
504
+ puts optparse
505
+ exit 1
506
+ end
507
+ connect(options)
508
+
509
+ begin
510
+ monitor_app = find_monitoring_app_by_name_or_id(args[0])
511
+ # construct payload
512
+ payload = nil
513
+ if options[:payload]
514
+ payload = options[:payload]
515
+ else
516
+ payload = params
517
+ end
518
+ if options[:dry_run]
519
+ print_dry_run @monitoring_interface.apps.dry.quarantine(monitor_app["id"], payload)
520
+ return 0
521
+ end
522
+ json_response = @monitoring_interface.apps.quarantine(monitor_app["id"], payload)
523
+ if options[:json]
524
+ puts as_json(json_response, options)
525
+ elsif !options[:quiet]
526
+ print_green_success "Unmuted app #{monitor_app['name']}"
527
+ _get(monitor_app['id'], {})
528
+ end
529
+ return 0
530
+ rescue RestClient::Exception => e
531
+ print_rest_exception(e, options)
532
+ exit 1
533
+ end
534
+ end
535
+
536
+ def remove(args)
537
+ options = {}
538
+ params = {}
539
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
540
+ opts.banner = subcommand_usage("[name]")
541
+ build_common_options(opts, options, [:json, :dry_run, :quiet])
542
+ end
543
+ optparse.parse!(args)
544
+ if args.count < 1
545
+ puts optparse
546
+ return 127
547
+ end
548
+ connect(options)
549
+
550
+ begin
551
+ monitor_app = find_monitoring_app_by_name_or_id(args[0])
552
+
553
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to delete monitoring app '#{monitor_app['name']}'?", options)
554
+ return false
555
+ end
556
+
557
+ # payload = {
558
+ # 'monitorApp' => {id: monitor_app["id"]}
559
+ # }
560
+ # payload['monitorApp'].merge!(monitor_app)
561
+ payload = params
562
+
563
+ if options[:dry_run]
564
+ print_dry_run @monitoring_interface.apps.dry.destroy(monitor_app["id"])
565
+ return
566
+ end
567
+
568
+ json_response = @monitoring_interface.apps.destroy(monitor_app["id"])
569
+ if options[:json]
570
+ puts as_json(json_response, options)
571
+ elsif !options[:quiet]
572
+ print_green_success "Deleted check app #{monitor_app['name']}"
573
+ end
574
+ return 0, nil
575
+ rescue RestClient::Exception => e
576
+ print_rest_exception(e, options)
577
+ return 1
578
+ end
579
+ end
580
+
581
+
582
+ private
28
583
 
29
584
  end