forked from sensu/sensu-community-plugins
/
sensu.rb
executable file
·139 lines (127 loc) · 4.33 KB
/
sensu.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env ruby
#
##################
# Sensu Remediator
##################
#
# This plugin reads configuration from a check definition
# and triggers appropriate remediation actions (defined as
# other checks) via the Sensu API, when the occurrences and
# severities reach certain values.
#
# The severities should be a list of integers.
#
# The occurrences should be an array of Integers, or strings,
# where the strings are dash seperated integers or plus
# suffixed integers.
#
# By default, the remediation checks will be triggered on the
# the client where the check is failing. An array of
# subscriptions may be specified via a 'trigger_on' property
# of the 'remediation' dictionary.
#
# Example:
#
# {
# "checks": {
# "check_something": {
# "command": "ps aux | grep cron",
# "interval": 60,
# "subscribers": ["application_server"],
# "handler": ["debug", "irc", "remediator"],
# "remediation": {
# "light_remediation": {
# "occurrences": [1, 2],
# "severities": [1]
# },
# "medium_remediation": {
# "occurrences": ["3-10"],
# "severities": [1]
# },
# "heavy_remediation": {
# "occurrences": ["1+"],
# "severities": [2]
# }
# }
# },
# "light_remediation": {
# "command": "/bin/something",
# "subscribers": [],
# "handler": ["debug", "irc"],
# "publish": false,
# },
# "medium_remediation": {
# "command": "/bin/something_else",
# "subscribers": [],
# "handler": ["debug", "irc"],
# "publish": false,
# },
# "heavy_remediation": {
# "command": "sudo reboot",
# "subscribers": [],
# "handler": ["debug", "irc"],
# "publish": false,
# }
# }
# }
# ===
#
# Copyright 2012 Nick Stielau <nick.stielau@gamil.com>
#
# Released under the same terms as Sensu (the MIT license); see LICENSE
# for details.
require 'rubygems' if RUBY_VERSION < '1.9.0'
require 'sensu-handler'
class Remediator < Sensu::Handler
# Override filter_repeated from Sensu::Handler.
# Remediations are not alerts.
def filter_repeated; end
def handle
client = @event['client']['name']
remediations = @event['check']['remediation']
occurrences = @event['occurrences']
severity = @event['check']['status'].to_i
puts "REMEDIATION: Evaluating remediation: #{client} #{remediations.inspect} #=#{occurrences} sev=#{severity}"
remediation_checks = parse_remediations(remediations, occurrences, severity)
subscribers = remediations['trigger_on'] ? [remediations['trigger_on']].flatten : [client]
remediation_checks.each do |remediation_check|
puts "REMEDIATION: Triggering remediation check '#{remediation_check}' for #{[client].inspect}"
response = trigger_remediation(remediation_check, subscribers)
puts "REMEDIATION: Recieved API Response (#{response.code}): #{response.body}, exiting."
end
end
# Examine the defined remediations and return an array of
# checks that should be triggered given the current occurrence
# count and severity.
def parse_remediations(remediations, occurrences, severity)
remediations_to_trigger = []
remediations.each do |check, conditions|
# Check for remediations matching the current occurrence count
(conditions["occurrences"] || []).each do |value|
if value.is_a?(Integer)
next unless occurrences == value
elsif value.to_s.match(/^\d+$/)
parsed_value = $~.to_a.first.to_i
next unless occurrences == parsed_value
elsif value.to_s.match(/^(\d+)-(\d+)$/)
range = Range.new($~.to_a[1].to_i, $~.to_a[2].to_i).to_a
next unless range.include?(occurrences)
elsif value.to_s.match(/^(\d+)\+$/)
puts "REMEDIATION: Matchdata: #{$~.inspect}"
range = Range.new($~.to_a[1].to_i, 9999).to_a
next unless range.include?(occurrences)
end
end
# Check remediations matching the current severity
next unless (conditions["severities"] || []).include?(severity)
remediations_to_trigger << check
end
remediations_to_trigger
end
# Issue a check via the API
def trigger_remediation(check, subscribers)
api_request(:POST, '/checks/request') do |req|
req.body = JSON.dump({"check" => check, "subscribers" => subscribers})
end
end
end