flapjack 0.7.26 → 0.7.27
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.
- checksums.yaml +15 -0
- data/CHANGELOG.md +5 -0
- data/features/notification_rules.feature +59 -30
- data/features/steps/events_steps.rb +30 -13
- data/flapjack.gemspec +1 -0
- data/lib/flapjack/data/notification.rb +3 -1
- data/lib/flapjack/data/notification_rule.rb +23 -4
- data/lib/flapjack/gateways/api/contact_methods.rb +4 -4
- data/lib/flapjack/notifier.rb +8 -17
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/data/notification_rule_spec.rb +2 -0
- data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +2 -0
- metadata +7 -56
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NmQ1OTFiN2UxMTM0NDU5ZWNjNWFkNGYzYzNiNGVmMDE0MjM5NTcwZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDhlNTI1NmFmY2IzNGVjMTAwMzAzYWFmYmRjYTU0ZWQ5NjM3MDA0NQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzZlYzRlMzRmMjJjZmNkMzNhMmYzYjkxYzNkNjNlZGRmMTQ5OWNmNDU4MGM1
|
10
|
+
NzBmZWJhNTA0Yjk0YmM4YWE5N2IyMmRlOGNjYTkzNTJmNDM3Y2I2NjZjZDg3
|
11
|
+
MjNhMjA0ZGJiOThhY2NlNTA3MjVkMDNiYzE4ZWVkN2U3Nzc3NjE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzkwYWNkYjU0NzcyZTFmMmJjMGI2YTk3ZjYxMmI0MDQzNzc2N2Y0YzA5NTU4
|
14
|
+
NGFjNjJhZDcxNjA0YzYzZjI5ZjY0NzkyNTYxMThjMDgyYjI2MWI5YTQyM2Vi
|
15
|
+
MDNhNDY3YjI1NTcxNjc5MTZhOWNmMjA1MzgyZDQ2MjJkNzg3ZTk=
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## Flapjack Changelog
|
2
2
|
|
3
|
+
# 0.7.27 - 2013-09-19
|
4
|
+
- Feature: Treat UNKNOWN separately to CRITICAL in notification rules gh-295 (@jessereynolds)
|
5
|
+
- Bug: License missing from gemspec gh-313 (@jessereynolds)
|
6
|
+
- Bug: fix ack after ack deletion gh-308 (@ali-graham)
|
7
|
+
|
3
8
|
# 0.7.26 - 2013-09-16
|
4
9
|
- Bug: last critical notification is empty in web UI gh-306 (@ali-graham)
|
5
10
|
- Bug: Ending unscheduled maintenance in Web UI is broken gh-307 (@jessereynolds)
|
@@ -8,6 +8,7 @@ Feature: Notification rules on a per contact basis
|
|
8
8
|
| 2 | Imani | Farooq | imani@example.com | +61400000002 | Europe/Moscow |
|
9
9
|
| 3 | Vera | Дурейко | vera@example.com | +61400000003 | Europe/Paris |
|
10
10
|
| 4 | Lucia | Moretti | lucia@example.com | +61400000004 | Europe/Rome |
|
11
|
+
| 5 | Wang Fang | Wong | fang@example.com | +61400000005 | Asia/Shanghai |
|
11
12
|
|
12
13
|
And the following entities exist:
|
13
14
|
| id | name | contacts |
|
@@ -34,32 +35,36 @@ Feature: Notification rules on a per contact basis
|
|
34
35
|
| 15 | 60 |
|
35
36
|
|
36
37
|
And user 1 has the following notification rules:
|
37
|
-
| entities |
|
38
|
-
| |
|
39
|
-
| foo |
|
40
|
-
| bar |
|
41
|
-
| baz |
|
38
|
+
| entities | unknown_media | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
39
|
+
| | | email | sms,email | true | true | |
|
40
|
+
| foo | | email | sms,email | | | 8-18 weekdays |
|
41
|
+
| bar | email | | sms,email | true | | |
|
42
|
+
| baz | | email | sms,email | | | |
|
42
43
|
|
43
44
|
And user 2 has the following notification rules:
|
44
|
-
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole |
|
45
|
-
| | | email | email | | |
|
46
|
-
| | | sms | sms | | |
|
47
|
-
| bar | | email | email,sms | | |
|
48
|
-
| bar | wags | | | true | true |
|
45
|
+
| entities | tags | warning_media | critical_media | warning_blackhole | critical_blackhole |
|
46
|
+
| | | email | email | | |
|
47
|
+
| | | sms | sms | | |
|
48
|
+
| bar | | email | email,sms | | |
|
49
|
+
| bar | wags | | | true | true |
|
49
50
|
|
50
51
|
And user 3 has the following notification rules:
|
51
|
-
| entities |
|
52
|
-
| |
|
53
|
-
| baz |
|
54
|
-
| buf |
|
55
|
-
| buf |
|
56
|
-
| bar |
|
52
|
+
| entities | warning_media | critical_media | warning_blackhole | critical_blackhole |
|
53
|
+
| | email | email | | |
|
54
|
+
| baz | sms | sms | | |
|
55
|
+
| buf | email | email | | |
|
56
|
+
| buf | sms | sms | | |
|
57
|
+
| bar | email | email | true | true |
|
57
58
|
|
58
59
|
And user 4 has the following notification rules:
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
| tags | warning_media | critical_media | time_restrictions |
|
61
|
+
| | | | |
|
62
|
+
| xyz, disk, util | sms | sms | |
|
63
|
+
| xyz, ping | sms,email | sms,email | 8-18 weekdays |
|
64
|
+
|
65
|
+
And user 5 has the following notification rules:
|
66
|
+
| unknown_media | critical_media |
|
67
|
+
| email | email, sms |
|
63
68
|
|
64
69
|
@time_restrictions @time
|
65
70
|
Scenario: Alerts only during specified time restrictions
|
@@ -239,22 +244,20 @@ Feature: Notification rules on a per contact basis
|
|
239
244
|
|
240
245
|
@intervals @time
|
241
246
|
Scenario: Problem directly after Recovery should alert despite notification intervals with unknown
|
242
|
-
Given the check is check 'ping' on entity '
|
247
|
+
Given the check is check 'ping' on entity 'bar'
|
243
248
|
And the check is in an ok state
|
244
249
|
When an unknown event is received
|
245
250
|
And 1 minute passes
|
246
251
|
And an unknown event is received
|
247
252
|
Then 1 email alert should be queued for malak@example.com
|
248
|
-
And 1 sms alert should be queued for +61400000001
|
249
253
|
When an ok event is received
|
250
254
|
Then 2 email alert should be queued for malak@example.com
|
251
|
-
And 2 sms alerts should be queued for +61400000001
|
252
255
|
When 1 minute passes
|
253
256
|
And an unknown event is received
|
254
257
|
And 1 minute passes
|
255
258
|
And an unknown event is received
|
256
259
|
Then 3 email alerts should be queued for malak@example.com
|
257
|
-
And
|
260
|
+
And 0 sms alerts should be queued for +61400000001
|
258
261
|
|
259
262
|
@time
|
260
263
|
Scenario: Contact with only entity specific rules should not be notified for other entities they are a contact for
|
@@ -327,26 +330,31 @@ Feature: Notification rules on a per contact basis
|
|
327
330
|
Then 2 email alert should be queued for malak@example.com
|
328
331
|
And 2 sms alert should be queued for +61400000001
|
329
332
|
|
333
|
+
@time
|
330
334
|
Scenario: Unknown event during unscheduled maintenance
|
331
|
-
Given the check is check 'ping' on entity '
|
335
|
+
Given the check is check 'ping' on entity 'bar'
|
332
336
|
And the check is in an ok state
|
333
337
|
When an unknown event is received
|
334
338
|
And 1 minute passes
|
335
339
|
And an unknown event is received
|
336
340
|
Then 1 email alert should be queued for malak@example.com
|
337
|
-
And 1 sms alert should be queued for +61400000001
|
338
341
|
When 6 minutes passes
|
339
342
|
And an acknowledgement event is received
|
340
343
|
Then 2 email alerts should be queued for malak@example.com
|
341
|
-
And 2 sms alerts should be queued for +61400000001
|
342
344
|
When 6 minutes passes
|
343
345
|
And an unknown event is received
|
344
346
|
Then 2 email alerts should be queued for malak@example.com
|
345
|
-
And 2 sms alerts should be queued for +61400000001
|
346
347
|
When 1 minute passes
|
347
348
|
And an unknown event is received
|
348
349
|
Then 2 email alerts should be queued for malak@example.com
|
349
|
-
|
350
|
+
|
351
|
+
Scenario: Unknown events alert only specified media
|
352
|
+
Given the check is check 'ping' on entity 'baz'
|
353
|
+
And the check is in an ok state
|
354
|
+
When an unknown event is received
|
355
|
+
And 1 minute passes
|
356
|
+
And an unknown event is received
|
357
|
+
Then 0 sms alerts should be queued for +61400000001
|
350
358
|
|
351
359
|
@time
|
352
360
|
Scenario: A blackhole rule on an entity should override another matching entity specific rule
|
@@ -399,4 +407,25 @@ Feature: Notification rules on a per contact basis
|
|
399
407
|
When a critical event is received
|
400
408
|
Then 3 sms alerts should be queued for +61400000004
|
401
409
|
|
402
|
-
|
410
|
+
# tests that notifications are sent as acknowledgement clears the notification intervals
|
411
|
+
@time
|
412
|
+
Scenario: an second acknowledgement is created after the first is deleted (gh-308)
|
413
|
+
Given the check is check 'ping' on entity 'baz'
|
414
|
+
And the check is in an ok state
|
415
|
+
When a critical event is received
|
416
|
+
And 1 minute passes
|
417
|
+
And a critical event is received
|
418
|
+
Then 1 email alert should be queued for malak@example.com
|
419
|
+
When 1 minute passes
|
420
|
+
And an acknowledgement event is received
|
421
|
+
Then unscheduled maintenance should be generated
|
422
|
+
And 2 email alerts should be queued for malak@example.com
|
423
|
+
When 1 minute passes
|
424
|
+
And the unscheduled maintenance is ended
|
425
|
+
And 1 minute passes
|
426
|
+
And a critical event is received
|
427
|
+
Then 3 email alerts should be queued for malak@example.com
|
428
|
+
When 1 minute passes
|
429
|
+
And an acknowledgement event is received
|
430
|
+
Then unscheduled maintenance should be generated
|
431
|
+
And 4 email alerts should be queued for malak@example.com
|
@@ -72,6 +72,11 @@ def set_warning_state(entity, check)
|
|
72
72
|
:timestamp => (Time.now.to_i - (60*60*24)))
|
73
73
|
end
|
74
74
|
|
75
|
+
def end_unscheduled_maintenance(entity, check)
|
76
|
+
entity_check = Flapjack::Data::EntityCheck.for_entity_name(entity, check, :redis => @redis)
|
77
|
+
entity_check.end_unscheduled_maintenance(Time.now.to_i)
|
78
|
+
end
|
79
|
+
|
75
80
|
def submit_ok(entity, check)
|
76
81
|
event = {
|
77
82
|
'type' => 'service',
|
@@ -261,6 +266,12 @@ When /^a test .*is received(?: for check '([\w\.\-]+)' on entity '([\w\.\-]+)')?
|
|
261
266
|
drain_events
|
262
267
|
end
|
263
268
|
|
269
|
+
When /^the unscheduled maintenance is ended(?: for check '([\w\.\-]+)' on entity '([\w\.\-]+)')?$/ do |check, entity|
|
270
|
+
check ||= @check
|
271
|
+
entity ||= @entity
|
272
|
+
end_unscheduled_maintenance(entity, check)
|
273
|
+
end
|
274
|
+
|
264
275
|
# TODO logging is a side-effect, should test for notification generation itself
|
265
276
|
Then /^a notification should not be generated(?: for check '([\w\.\-]+)' on entity '([\w\.\-]+)')?$/ do |check, entity|
|
266
277
|
check ||= @check
|
@@ -278,10 +289,10 @@ Then /^a notification should be generated(?: for check '([\w\.\-]+)' on entity '
|
|
278
289
|
found.should be_true
|
279
290
|
end
|
280
291
|
|
281
|
-
Then /^scheduled maintenance should be generated(?: for check '([\w\.\-]+)' on entity '([\w\.\-]+)')?$/ do |check, entity|
|
292
|
+
Then /^(un)?scheduled maintenance should be generated(?: for check '([\w\.\-]+)' on entity '([\w\.\-]+)')?$/ do |unsched, check, entity|
|
282
293
|
check ||= @check
|
283
294
|
entity ||= @entity
|
284
|
-
@redis.get("#{entity}:#{check}
|
295
|
+
@redis.get("#{entity}:#{check}:#{unsched || ''}scheduled_maintenance").should_not be_nil
|
285
296
|
end
|
286
297
|
|
287
298
|
Then /^show me the (\w+ )*log$/ do |adjective|
|
@@ -336,6 +347,8 @@ end
|
|
336
347
|
|
337
348
|
Given /^user (\d+) has the following notification rules:$/ do |contact_id, rules|
|
338
349
|
contact = Flapjack::Data::Contact.find_by_id(contact_id, :redis => @redis)
|
350
|
+
timezone = contact.timezone
|
351
|
+
|
339
352
|
# delete any autogenerated rules, and do it using redis directly so no new
|
340
353
|
# ones will be created
|
341
354
|
contact.notification_rules.each do |nr|
|
@@ -343,27 +356,31 @@ Given /^user (\d+) has the following notification rules:$/ do |contact_id, rules
|
|
343
356
|
@redis.del("notification_rule:#{nr.id}")
|
344
357
|
end
|
345
358
|
rules.hashes.each do |rule|
|
346
|
-
entities = rule['entities'].split(',').map
|
347
|
-
tags = rule['tags'].split(',').map
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
rule['time_restrictions'].split(',').map { |x|
|
359
|
+
entities = rule['entities'] ? rule['entities'].split(',').map { |x| x.strip } : []
|
360
|
+
tags = rule['tags'] ? rule['tags'].split(',').map { |x| x.strip } : []
|
361
|
+
unknown_media = rule['unknown_media'] ? rule['unknown_media'].split(',').map { |x| x.strip } : []
|
362
|
+
warning_media = rule['warning_media'] ? rule['warning_media'].split(',').map { |x| x.strip } : []
|
363
|
+
critical_media = rule['critical_media'] ? rule['critical_media'].split(',').map { |x| x.strip } : []
|
364
|
+
unknown_blackhole = rule['unknown_blackhole'] ? (rule['unknown_blackhole'].downcase == 'true') : false
|
365
|
+
warning_blackhole = rule['warning_blackhole'] ? (rule['warning_blackhole'].downcase == 'true') : false
|
366
|
+
critical_blackhole = rule['critical_blackhole'] ? (rule['critical_blackhole'].downcase == 'true') : false
|
367
|
+
time_restrictions = rule['time_restrictions'] ? rule['time_restrictions'].split(',').map { |x|
|
368
|
+
x.strip
|
369
|
+
}.inject([]) { |memo, time_restriction|
|
355
370
|
case time_restriction
|
356
371
|
when '8-18 weekdays'
|
357
372
|
weekdays_8_18 = IceCube::Schedule.new(timezone.local(2013,2,1,8,0,0), :duration => 60 * 60 * 10)
|
358
373
|
weekdays_8_18.add_recurrence_rule(IceCube::Rule.weekly.day(:monday, :tuesday, :wednesday, :thursday, :friday))
|
359
|
-
|
374
|
+
memo << icecube_schedule_to_time_restriction(weekdays_8_18, timezone)
|
360
375
|
end
|
361
|
-
|
376
|
+
} : []
|
362
377
|
rule_data = {:contact_id => contact_id,
|
363
378
|
:entities => entities,
|
364
379
|
:tags => tags,
|
380
|
+
:unknown_media => unknown_media,
|
365
381
|
:warning_media => warning_media,
|
366
382
|
:critical_media => critical_media,
|
383
|
+
:unknown_blackhole => unknown_blackhole,
|
367
384
|
:warning_blackhole => warning_blackhole,
|
368
385
|
:critical_blackhole => critical_blackhole,
|
369
386
|
:time_restrictions => time_restrictions}
|
data/flapjack.gemspec
CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |gem|
|
|
7
7
|
gem.description = "Flapjack is distributed monitoring notification system that provides a scalable method for processing streams of events from Nagios and deciding who should be notified"
|
8
8
|
gem.summary = "Intelligent, scalable, distributed monitoring notification system."
|
9
9
|
gem.homepage = "http://flapjack-project.com/"
|
10
|
+
gem.license = 'MIT'
|
10
11
|
|
11
12
|
# see http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
|
12
13
|
# following a middle road here, not shipping it with the gem :)
|
@@ -34,10 +34,12 @@ module Flapjack
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.severity_for_event(event, max_notified_severity)
|
37
|
-
if ([event.state, max_notified_severity] & ['critical', '
|
37
|
+
if ([event.state, max_notified_severity] & ['critical', 'test_notifications']).any?
|
38
38
|
'critical'
|
39
39
|
elsif [event.state, max_notified_severity].include?('warning')
|
40
40
|
'warning'
|
41
|
+
elsif [event.state, max_notified_severity].include?('unknown')
|
42
|
+
'unknown'
|
41
43
|
else
|
42
44
|
'ok'
|
43
45
|
end
|
@@ -13,7 +13,8 @@ module Flapjack
|
|
13
13
|
extend Flapjack::Utility
|
14
14
|
|
15
15
|
attr_accessor :id, :contact_id, :entities, :tags, :time_restrictions,
|
16
|
-
:
|
16
|
+
:unknown_media, :warning_media, :critical_media,
|
17
|
+
:unknown_blackhole, :warning_blackhole, :critical_blackhole
|
17
18
|
|
18
19
|
def self.exists_with_id?(rule_id, options = {})
|
19
20
|
raise "Redis connection not set" unless redis = options[:redis]
|
@@ -70,8 +71,8 @@ module Flapjack
|
|
70
71
|
|
71
72
|
def to_json(*args)
|
72
73
|
self.class.hashify(:id, :contact_id, :tags, :entities,
|
73
|
-
:time_restrictions, :warning_media, :critical_media,
|
74
|
-
:warning_blackhole, :critical_blackhole) {|k|
|
74
|
+
:time_restrictions, :unknown_media, :warning_media, :critical_media,
|
75
|
+
:unknown_blackhole, :warning_blackhole, :critical_blackhole) {|k|
|
75
76
|
[k, self.send(k)]
|
76
77
|
}.to_json
|
77
78
|
end
|
@@ -89,12 +90,15 @@ module Flapjack
|
|
89
90
|
end
|
90
91
|
|
91
92
|
def blackhole?(severity)
|
92
|
-
('
|
93
|
+
('unknown'.eql?(severity.downcase) && @unknown_blackhole) ||
|
94
|
+
('warning'.eql?(severity.downcase) && @warning_blackhole) ||
|
93
95
|
('critical'.eql?(severity.downcase) && @critical_blackhole)
|
94
96
|
end
|
95
97
|
|
96
98
|
def media_for_severity(severity)
|
97
99
|
case severity
|
100
|
+
when 'unknown'
|
101
|
+
@unknown_media
|
98
102
|
when 'warning'
|
99
103
|
@warning_media
|
100
104
|
when 'critical'
|
@@ -123,6 +127,7 @@ module Flapjack
|
|
123
127
|
logger = options[:logger]
|
124
128
|
|
125
129
|
# make some assumptions about the incoming data
|
130
|
+
rule_data[:unknown_blackhole] = rule_data[:unknown_blackhole] || false
|
126
131
|
rule_data[:warning_blackhole] = rule_data[:warning_blackhole] || false
|
127
132
|
rule_data[:critical_blackhole] = rule_data[:critical_blackhole] || false
|
128
133
|
if rule_data[:tags].is_a?(Array)
|
@@ -141,8 +146,10 @@ module Flapjack
|
|
141
146
|
:entities => Oj.dump(rule_data[:entities]),
|
142
147
|
:tags => Oj.dump(tag_data),
|
143
148
|
:time_restrictions => Oj.dump(rule_data[:time_restrictions]),
|
149
|
+
:unknown_media => Oj.dump(rule_data[:unknown_media]),
|
144
150
|
:warning_media => Oj.dump(rule_data[:warning_media]),
|
145
151
|
:critical_media => Oj.dump(rule_data[:critical_media]),
|
152
|
+
:unknown_blackhole => rule_data[:unknown_blackhole],
|
146
153
|
:warning_blackhole => rule_data[:warning_blackhole],
|
147
154
|
:critical_blackhole => rule_data[:critical_blackhole],
|
148
155
|
}
|
@@ -245,6 +252,12 @@ module Flapjack
|
|
245
252
|
"time restrictions are invalid",
|
246
253
|
|
247
254
|
# TODO should the media types be checked against a whitelist?
|
255
|
+
proc { !d.has_key?(:unknown_media) ||
|
256
|
+
( d[:unknown_media].nil? ||
|
257
|
+
d[:unknown_media].is_a?(Array) &&
|
258
|
+
d[:unknown_media].all? {|et| et.is_a?(String)} ) } =>
|
259
|
+
"unknown_media must be a list of strings",
|
260
|
+
|
248
261
|
proc { !d.has_key?(:warning_media) ||
|
249
262
|
( d[:warning_media].nil? ||
|
250
263
|
d[:warning_media].is_a?(Array) &&
|
@@ -257,6 +270,10 @@ module Flapjack
|
|
257
270
|
d[:critical_media].all? {|et| et.is_a?(String)} ) } =>
|
258
271
|
"critical_media must be a list of strings",
|
259
272
|
|
273
|
+
proc { !d.has_key?(:unknown_blackhole) ||
|
274
|
+
[TrueClass, FalseClass].include?(d[:unknown_blackhole].class) } =>
|
275
|
+
"unknown_blackhole must be true or false",
|
276
|
+
|
260
277
|
proc { !d.has_key?(:warning_blackhole) ||
|
261
278
|
[TrueClass, FalseClass].include?(d[:warning_blackhole].class) } =>
|
262
279
|
"warning_blackhole must be true or false",
|
@@ -289,8 +306,10 @@ module Flapjack
|
|
289
306
|
@tags = tags ? Flapjack::Data::TagSet.new(tags) : nil
|
290
307
|
@entities = Oj.load(rule_data['entities'] || '')
|
291
308
|
@time_restrictions = Oj.load(rule_data['time_restrictions'] || '')
|
309
|
+
@unknown_media = Oj.load(rule_data['unknown_media'] || '')
|
292
310
|
@warning_media = Oj.load(rule_data['warning_media'] || '')
|
293
311
|
@critical_media = Oj.load(rule_data['critical_media'] || '')
|
312
|
+
@unknown_blackhole = ((rule_data['unknown_blackhole'] || 'false').downcase == 'true')
|
294
313
|
@warning_blackhole = ((rule_data['warning_blackhole'] || 'false').downcase == 'true')
|
295
314
|
@critical_blackhole = ((rule_data['critical_blackhole'] || 'false').downcase == 'true')
|
296
315
|
end
|
@@ -143,8 +143,8 @@ module Flapjack
|
|
143
143
|
contact = find_contact(params[:contact_id])
|
144
144
|
|
145
145
|
rule_data = hashify(:entities, :tags,
|
146
|
-
:warning_media, :critical_media, :time_restrictions,
|
147
|
-
:warning_blackhole, :critical_blackhole) {|k| [k, params[k]]}
|
146
|
+
:unknown_media, :warning_media, :critical_media, :time_restrictions,
|
147
|
+
:unknown_blackhole, :warning_blackhole, :critical_blackhole) {|k| [k, params[k]]}
|
148
148
|
|
149
149
|
rule_or_errors = contact.add_notification_rule(rule_data, :logger => logger)
|
150
150
|
|
@@ -166,8 +166,8 @@ module Flapjack
|
|
166
166
|
contact = find_contact(rule.contact_id)
|
167
167
|
|
168
168
|
rule_data = hashify(:entities, :tags,
|
169
|
-
:warning_media, :critical_media, :time_restrictions,
|
170
|
-
:warning_blackhole, :critical_blackhole) {|k| [k, params[k]]}
|
169
|
+
:unknown_media, :warning_media, :critical_media, :time_restrictions,
|
170
|
+
:unknown_blackhole, :warning_blackhole, :critical_blackhole) {|k| [k, params[k]]}
|
171
171
|
|
172
172
|
errors = rule.update(rule_data, :logger => logger)
|
173
173
|
|
data/lib/flapjack/notifier.rb
CHANGED
@@ -123,22 +123,14 @@ module Flapjack
|
|
123
123
|
|
124
124
|
contact = message.contact
|
125
125
|
|
126
|
-
if notification.ok?
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
:check => event_id,
|
135
|
-
:state => 'critical',
|
136
|
-
:delete => true)
|
137
|
-
contact.update_sent_alert_keys(
|
138
|
-
:media => media_type,
|
139
|
-
:check => event_id,
|
140
|
-
:state => 'unknown',
|
141
|
-
:delete => true)
|
126
|
+
if notification.ok? || (notification.state == 'acknowledgement')
|
127
|
+
['warning', 'critical', 'unknown'].each do |alert_state|
|
128
|
+
contact.update_sent_alert_keys(
|
129
|
+
:media => media_type,
|
130
|
+
:check => event_id,
|
131
|
+
:state => alert_state,
|
132
|
+
:delete => true)
|
133
|
+
end
|
142
134
|
else
|
143
135
|
contact.update_sent_alert_keys(
|
144
136
|
:media => media_type,
|
@@ -146,7 +138,6 @@ module Flapjack
|
|
146
138
|
:state => notification.state)
|
147
139
|
end
|
148
140
|
|
149
|
-
|
150
141
|
contents_tags = contents['tags']
|
151
142
|
contents['tags'] = contents_tags.is_a?(Set) ? contents_tags.to_a : contents_tags
|
152
143
|
|
data/lib/flapjack/version.rb
CHANGED
@@ -17,8 +17,10 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
17
17
|
:tags => ["database","physical"],
|
18
18
|
:entities => ["foo-app-01.example.com"],
|
19
19
|
:time_restrictions => [ weekdays_8_18 ],
|
20
|
+
:unknown_media => [],
|
20
21
|
:warning_media => ["email"],
|
21
22
|
:critical_media => ["sms", "email"],
|
23
|
+
:unknown_blackhole => false,
|
22
24
|
:warning_blackhole => false,
|
23
25
|
:critical_blackhole => false
|
24
26
|
}
|
@@ -40,8 +40,10 @@ describe 'Flapjack::Gateways::API::ContactMethods', :sinatra => true, :logger =>
|
|
40
40
|
"tags" => ["database","physical"],
|
41
41
|
"entities" => ["foo-app-01.example.com"],
|
42
42
|
"time_restrictions" => nil,
|
43
|
+
"unknown_media" => ["jabber"],
|
43
44
|
"warning_media" => ["email"],
|
44
45
|
"critical_media" => ["sms", "email"],
|
46
|
+
"unknown_blackhole" => false,
|
45
47
|
"warning_blackhole" => false,
|
46
48
|
"critical_blackhole" => false
|
47
49
|
}
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flapjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
5
|
-
prerelease:
|
4
|
+
version: 0.7.27
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Lindsay Holmwood
|
@@ -11,12 +10,11 @@ authors:
|
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date: 2013-09-
|
13
|
+
date: 2013-09-19 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: dante
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
18
|
requirements:
|
21
19
|
- - ! '>='
|
22
20
|
- !ruby/object:Gem::Version
|
@@ -24,7 +22,6 @@ dependencies:
|
|
24
22
|
type: :runtime
|
25
23
|
prerelease: false
|
26
24
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
25
|
requirements:
|
29
26
|
- - ! '>='
|
30
27
|
- !ruby/object:Gem::Version
|
@@ -32,7 +29,6 @@ dependencies:
|
|
32
29
|
- !ruby/object:Gem::Dependency
|
33
30
|
name: oj
|
34
31
|
requirement: !ruby/object:Gem::Requirement
|
35
|
-
none: false
|
36
32
|
requirements:
|
37
33
|
- - ! '>='
|
38
34
|
- !ruby/object:Gem::Version
|
@@ -40,7 +36,6 @@ dependencies:
|
|
40
36
|
type: :runtime
|
41
37
|
prerelease: false
|
42
38
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
39
|
requirements:
|
45
40
|
- - ! '>='
|
46
41
|
- !ruby/object:Gem::Version
|
@@ -48,7 +43,6 @@ dependencies:
|
|
48
43
|
- !ruby/object:Gem::Dependency
|
49
44
|
name: eventmachine
|
50
45
|
requirement: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
46
|
requirements:
|
53
47
|
- - ~>
|
54
48
|
- !ruby/object:Gem::Version
|
@@ -56,7 +50,6 @@ dependencies:
|
|
56
50
|
type: :runtime
|
57
51
|
prerelease: false
|
58
52
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
none: false
|
60
53
|
requirements:
|
61
54
|
- - ~>
|
62
55
|
- !ruby/object:Gem::Version
|
@@ -64,7 +57,6 @@ dependencies:
|
|
64
57
|
- !ruby/object:Gem::Dependency
|
65
58
|
name: hiredis
|
66
59
|
requirement: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
60
|
requirements:
|
69
61
|
- - ! '>='
|
70
62
|
- !ruby/object:Gem::Version
|
@@ -72,7 +64,6 @@ dependencies:
|
|
72
64
|
type: :runtime
|
73
65
|
prerelease: false
|
74
66
|
version_requirements: !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
67
|
requirements:
|
77
68
|
- - ! '>='
|
78
69
|
- !ruby/object:Gem::Version
|
@@ -80,7 +71,6 @@ dependencies:
|
|
80
71
|
- !ruby/object:Gem::Dependency
|
81
72
|
name: em-synchrony
|
82
73
|
requirement: !ruby/object:Gem::Requirement
|
83
|
-
none: false
|
84
74
|
requirements:
|
85
75
|
- - ~>
|
86
76
|
- !ruby/object:Gem::Version
|
@@ -88,7 +78,6 @@ dependencies:
|
|
88
78
|
type: :runtime
|
89
79
|
prerelease: false
|
90
80
|
version_requirements: !ruby/object:Gem::Requirement
|
91
|
-
none: false
|
92
81
|
requirements:
|
93
82
|
- - ~>
|
94
83
|
- !ruby/object:Gem::Version
|
@@ -96,7 +85,6 @@ dependencies:
|
|
96
85
|
- !ruby/object:Gem::Dependency
|
97
86
|
name: em-http-request
|
98
87
|
requirement: !ruby/object:Gem::Requirement
|
99
|
-
none: false
|
100
88
|
requirements:
|
101
89
|
- - ! '>='
|
102
90
|
- !ruby/object:Gem::Version
|
@@ -104,7 +92,6 @@ dependencies:
|
|
104
92
|
type: :runtime
|
105
93
|
prerelease: false
|
106
94
|
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
108
95
|
requirements:
|
109
96
|
- - ! '>='
|
110
97
|
- !ruby/object:Gem::Version
|
@@ -112,7 +99,6 @@ dependencies:
|
|
112
99
|
- !ruby/object:Gem::Dependency
|
113
100
|
name: redis
|
114
101
|
requirement: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
102
|
requirements:
|
117
103
|
- - ! '>='
|
118
104
|
- !ruby/object:Gem::Version
|
@@ -120,7 +106,6 @@ dependencies:
|
|
120
106
|
type: :runtime
|
121
107
|
prerelease: false
|
122
108
|
version_requirements: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
109
|
requirements:
|
125
110
|
- - ! '>='
|
126
111
|
- !ruby/object:Gem::Version
|
@@ -128,7 +113,6 @@ dependencies:
|
|
128
113
|
- !ruby/object:Gem::Dependency
|
129
114
|
name: em-resque
|
130
115
|
requirement: !ruby/object:Gem::Requirement
|
131
|
-
none: false
|
132
116
|
requirements:
|
133
117
|
- - ! '>='
|
134
118
|
- !ruby/object:Gem::Version
|
@@ -136,7 +120,6 @@ dependencies:
|
|
136
120
|
type: :runtime
|
137
121
|
prerelease: false
|
138
122
|
version_requirements: !ruby/object:Gem::Requirement
|
139
|
-
none: false
|
140
123
|
requirements:
|
141
124
|
- - ! '>='
|
142
125
|
- !ruby/object:Gem::Version
|
@@ -144,7 +127,6 @@ dependencies:
|
|
144
127
|
- !ruby/object:Gem::Dependency
|
145
128
|
name: resque
|
146
129
|
requirement: !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
130
|
requirements:
|
149
131
|
- - ~>
|
150
132
|
- !ruby/object:Gem::Version
|
@@ -152,7 +134,6 @@ dependencies:
|
|
152
134
|
type: :runtime
|
153
135
|
prerelease: false
|
154
136
|
version_requirements: !ruby/object:Gem::Requirement
|
155
|
-
none: false
|
156
137
|
requirements:
|
157
138
|
- - ~>
|
158
139
|
- !ruby/object:Gem::Version
|
@@ -160,7 +141,6 @@ dependencies:
|
|
160
141
|
- !ruby/object:Gem::Dependency
|
161
142
|
name: sinatra
|
162
143
|
requirement: !ruby/object:Gem::Requirement
|
163
|
-
none: false
|
164
144
|
requirements:
|
165
145
|
- - ! '>='
|
166
146
|
- !ruby/object:Gem::Version
|
@@ -168,7 +148,6 @@ dependencies:
|
|
168
148
|
type: :runtime
|
169
149
|
prerelease: false
|
170
150
|
version_requirements: !ruby/object:Gem::Requirement
|
171
|
-
none: false
|
172
151
|
requirements:
|
173
152
|
- - ! '>='
|
174
153
|
- !ruby/object:Gem::Version
|
@@ -176,7 +155,6 @@ dependencies:
|
|
176
155
|
- !ruby/object:Gem::Dependency
|
177
156
|
name: rack-fiber_pool
|
178
157
|
requirement: !ruby/object:Gem::Requirement
|
179
|
-
none: false
|
180
158
|
requirements:
|
181
159
|
- - ! '>='
|
182
160
|
- !ruby/object:Gem::Version
|
@@ -184,7 +162,6 @@ dependencies:
|
|
184
162
|
type: :runtime
|
185
163
|
prerelease: false
|
186
164
|
version_requirements: !ruby/object:Gem::Requirement
|
187
|
-
none: false
|
188
165
|
requirements:
|
189
166
|
- - ! '>='
|
190
167
|
- !ruby/object:Gem::Version
|
@@ -192,7 +169,6 @@ dependencies:
|
|
192
169
|
- !ruby/object:Gem::Dependency
|
193
170
|
name: thin
|
194
171
|
requirement: !ruby/object:Gem::Requirement
|
195
|
-
none: false
|
196
172
|
requirements:
|
197
173
|
- - ! '>='
|
198
174
|
- !ruby/object:Gem::Version
|
@@ -200,7 +176,6 @@ dependencies:
|
|
200
176
|
type: :runtime
|
201
177
|
prerelease: false
|
202
178
|
version_requirements: !ruby/object:Gem::Requirement
|
203
|
-
none: false
|
204
179
|
requirements:
|
205
180
|
- - ! '>='
|
206
181
|
- !ruby/object:Gem::Version
|
@@ -208,7 +183,6 @@ dependencies:
|
|
208
183
|
- !ruby/object:Gem::Dependency
|
209
184
|
name: mail
|
210
185
|
requirement: !ruby/object:Gem::Requirement
|
211
|
-
none: false
|
212
186
|
requirements:
|
213
187
|
- - ! '>='
|
214
188
|
- !ruby/object:Gem::Version
|
@@ -216,7 +190,6 @@ dependencies:
|
|
216
190
|
type: :runtime
|
217
191
|
prerelease: false
|
218
192
|
version_requirements: !ruby/object:Gem::Requirement
|
219
|
-
none: false
|
220
193
|
requirements:
|
221
194
|
- - ! '>='
|
222
195
|
- !ruby/object:Gem::Version
|
@@ -224,7 +197,6 @@ dependencies:
|
|
224
197
|
- !ruby/object:Gem::Dependency
|
225
198
|
name: blather
|
226
199
|
requirement: !ruby/object:Gem::Requirement
|
227
|
-
none: false
|
228
200
|
requirements:
|
229
201
|
- - ~>
|
230
202
|
- !ruby/object:Gem::Version
|
@@ -232,7 +204,6 @@ dependencies:
|
|
232
204
|
type: :runtime
|
233
205
|
prerelease: false
|
234
206
|
version_requirements: !ruby/object:Gem::Requirement
|
235
|
-
none: false
|
236
207
|
requirements:
|
237
208
|
- - ~>
|
238
209
|
- !ruby/object:Gem::Version
|
@@ -240,7 +211,6 @@ dependencies:
|
|
240
211
|
- !ruby/object:Gem::Dependency
|
241
212
|
name: chronic
|
242
213
|
requirement: !ruby/object:Gem::Requirement
|
243
|
-
none: false
|
244
214
|
requirements:
|
245
215
|
- - ! '>='
|
246
216
|
- !ruby/object:Gem::Version
|
@@ -248,7 +218,6 @@ dependencies:
|
|
248
218
|
type: :runtime
|
249
219
|
prerelease: false
|
250
220
|
version_requirements: !ruby/object:Gem::Requirement
|
251
|
-
none: false
|
252
221
|
requirements:
|
253
222
|
- - ! '>='
|
254
223
|
- !ruby/object:Gem::Version
|
@@ -256,7 +225,6 @@ dependencies:
|
|
256
225
|
- !ruby/object:Gem::Dependency
|
257
226
|
name: chronic_duration
|
258
227
|
requirement: !ruby/object:Gem::Requirement
|
259
|
-
none: false
|
260
228
|
requirements:
|
261
229
|
- - ! '>='
|
262
230
|
- !ruby/object:Gem::Version
|
@@ -264,7 +232,6 @@ dependencies:
|
|
264
232
|
type: :runtime
|
265
233
|
prerelease: false
|
266
234
|
version_requirements: !ruby/object:Gem::Requirement
|
267
|
-
none: false
|
268
235
|
requirements:
|
269
236
|
- - ! '>='
|
270
237
|
- !ruby/object:Gem::Version
|
@@ -272,7 +239,6 @@ dependencies:
|
|
272
239
|
- !ruby/object:Gem::Dependency
|
273
240
|
name: activesupport
|
274
241
|
requirement: !ruby/object:Gem::Requirement
|
275
|
-
none: false
|
276
242
|
requirements:
|
277
243
|
- - ~>
|
278
244
|
- !ruby/object:Gem::Version
|
@@ -280,7 +246,6 @@ dependencies:
|
|
280
246
|
type: :runtime
|
281
247
|
prerelease: false
|
282
248
|
version_requirements: !ruby/object:Gem::Requirement
|
283
|
-
none: false
|
284
249
|
requirements:
|
285
250
|
- - ~>
|
286
251
|
- !ruby/object:Gem::Version
|
@@ -288,7 +253,6 @@ dependencies:
|
|
288
253
|
- !ruby/object:Gem::Dependency
|
289
254
|
name: ice_cube
|
290
255
|
requirement: !ruby/object:Gem::Requirement
|
291
|
-
none: false
|
292
256
|
requirements:
|
293
257
|
- - ! '>='
|
294
258
|
- !ruby/object:Gem::Version
|
@@ -296,7 +260,6 @@ dependencies:
|
|
296
260
|
type: :runtime
|
297
261
|
prerelease: false
|
298
262
|
version_requirements: !ruby/object:Gem::Requirement
|
299
|
-
none: false
|
300
263
|
requirements:
|
301
264
|
- - ! '>='
|
302
265
|
- !ruby/object:Gem::Version
|
@@ -304,7 +267,6 @@ dependencies:
|
|
304
267
|
- !ruby/object:Gem::Dependency
|
305
268
|
name: tzinfo
|
306
269
|
requirement: !ruby/object:Gem::Requirement
|
307
|
-
none: false
|
308
270
|
requirements:
|
309
271
|
- - ~>
|
310
272
|
- !ruby/object:Gem::Version
|
@@ -312,7 +274,6 @@ dependencies:
|
|
312
274
|
type: :runtime
|
313
275
|
prerelease: false
|
314
276
|
version_requirements: !ruby/object:Gem::Requirement
|
315
|
-
none: false
|
316
277
|
requirements:
|
317
278
|
- - ~>
|
318
279
|
- !ruby/object:Gem::Version
|
@@ -320,7 +281,6 @@ dependencies:
|
|
320
281
|
- !ruby/object:Gem::Dependency
|
321
282
|
name: tzinfo-data
|
322
283
|
requirement: !ruby/object:Gem::Requirement
|
323
|
-
none: false
|
324
284
|
requirements:
|
325
285
|
- - ! '>='
|
326
286
|
- !ruby/object:Gem::Version
|
@@ -328,7 +288,6 @@ dependencies:
|
|
328
288
|
type: :runtime
|
329
289
|
prerelease: false
|
330
290
|
version_requirements: !ruby/object:Gem::Requirement
|
331
|
-
none: false
|
332
291
|
requirements:
|
333
292
|
- - ! '>='
|
334
293
|
- !ruby/object:Gem::Version
|
@@ -336,7 +295,6 @@ dependencies:
|
|
336
295
|
- !ruby/object:Gem::Dependency
|
337
296
|
name: rake
|
338
297
|
requirement: !ruby/object:Gem::Requirement
|
339
|
-
none: false
|
340
298
|
requirements:
|
341
299
|
- - ! '>='
|
342
300
|
- !ruby/object:Gem::Version
|
@@ -344,7 +302,6 @@ dependencies:
|
|
344
302
|
type: :development
|
345
303
|
prerelease: false
|
346
304
|
version_requirements: !ruby/object:Gem::Requirement
|
347
|
-
none: false
|
348
305
|
requirements:
|
349
306
|
- - ! '>='
|
350
307
|
- !ruby/object:Gem::Version
|
@@ -534,34 +491,28 @@ files:
|
|
534
491
|
- tmp/test_json_post.rb
|
535
492
|
- tmp/test_notification_rules_api.rb
|
536
493
|
homepage: http://flapjack-project.com/
|
537
|
-
licenses:
|
494
|
+
licenses:
|
495
|
+
- MIT
|
496
|
+
metadata: {}
|
538
497
|
post_install_message:
|
539
498
|
rdoc_options: []
|
540
499
|
require_paths:
|
541
500
|
- lib
|
542
501
|
required_ruby_version: !ruby/object:Gem::Requirement
|
543
|
-
none: false
|
544
502
|
requirements:
|
545
503
|
- - ! '>='
|
546
504
|
- !ruby/object:Gem::Version
|
547
505
|
version: '0'
|
548
|
-
segments:
|
549
|
-
- 0
|
550
|
-
hash: -187852671407725987
|
551
506
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
552
|
-
none: false
|
553
507
|
requirements:
|
554
508
|
- - ! '>='
|
555
509
|
- !ruby/object:Gem::Version
|
556
510
|
version: '0'
|
557
|
-
segments:
|
558
|
-
- 0
|
559
|
-
hash: -187852671407725987
|
560
511
|
requirements: []
|
561
512
|
rubyforge_project:
|
562
|
-
rubygems_version: 1.
|
513
|
+
rubygems_version: 2.1.3
|
563
514
|
signing_key:
|
564
|
-
specification_version:
|
515
|
+
specification_version: 4
|
565
516
|
summary: Intelligent, scalable, distributed monitoring notification system.
|
566
517
|
test_files:
|
567
518
|
- features/events.feature
|