flapjack 0.7.7 → 0.7.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +7 -1
- data/bin/flapjack-nagios-receiver +7 -5
- data/features/notification_rules.feature +84 -6
- data/lib/flapjack/data/entity_check.rb +12 -2
- data/lib/flapjack/data/event.rb +4 -0
- data/lib/flapjack/data/notification.rb +1 -0
- data/lib/flapjack/data/notification_rule.rb +7 -7
- data/lib/flapjack/executive.rb +27 -9
- data/lib/flapjack/gateways/email.rb +1 -0
- data/lib/flapjack/gateways/email/alert.html.haml +5 -0
- data/lib/flapjack/gateways/jabber.rb +1 -1
- data/lib/flapjack/gateways/web.rb +1 -0
- data/lib/flapjack/gateways/web/views/check.haml +1 -0
- data/lib/flapjack/gateways/web/views/contacts.haml +1 -1
- data/lib/flapjack/gateways/web/views/entities.haml +1 -1
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/data/notification_rule_spec.rb +2 -3
- data/spec/lib/flapjack/data/notification_spec.rb +3 -1
- data/spec/lib/flapjack/gateways/web_spec.rb +1 -0
- metadata +4 -4
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
## Flapjack Changelog
|
2
2
|
|
3
|
-
# 0.7.
|
3
|
+
# 0.7.8 - 2013-05-30
|
4
|
+
- Feature: support multiline check output (thanks @bs-github) gh-100 (@jessereynolds)
|
5
|
+
- Bug: notification rule with no entities or entity tags not being allowed gh-193 (@jessereynolds)
|
6
|
+
- Bug: correct jabber alias in example acknowledgement strings gh-189 (@jessereynolds)
|
7
|
+
- Bug: entity lists in Web UI should be sorted alphabetically gh-195 (@jessereynolds)
|
8
|
+
|
9
|
+
# 0.7.7 - 2013-05-22
|
4
10
|
- Bug: relax notification rule validations somewhat gh-185 (@jessereynolds)
|
5
11
|
- Chore: log notification rule validation errors from api gh-183 (@jessereynolds)
|
6
12
|
|
@@ -25,11 +25,11 @@ def process_input(opts)
|
|
25
25
|
skip unless line
|
26
26
|
split_line = line.split("\t")
|
27
27
|
|
28
|
-
object_type, timestamp, entity, check, state, check_time, check_latency, check_output, check_perfdata = split_line
|
28
|
+
object_type, timestamp, entity, check, state, check_time, check_latency, check_output, check_perfdata, check_long_output = split_line
|
29
29
|
|
30
30
|
case
|
31
|
-
when split_line.length
|
32
|
-
puts "ERROR - rejecting this line as it doesn't split into 9 tab separated strings: [#{line}]"
|
31
|
+
when ! (split_line.length > 8)
|
32
|
+
puts "ERROR - rejecting this line as it doesn't split into at least 9 tab separated strings: [#{line}]"
|
33
33
|
next
|
34
34
|
when (timestamp !~ /^\d+$/)
|
35
35
|
puts "ERROR - rejecting this line as second string doesn't look like a timestamp: [#{line}]"
|
@@ -39,16 +39,18 @@ def process_input(opts)
|
|
39
39
|
next
|
40
40
|
end
|
41
41
|
|
42
|
-
puts "#{object_type}, #{timestamp}, #{entity}, #{check}, #{state}, #{check_output}"
|
42
|
+
puts "#{object_type}, #{timestamp}, #{entity}, #{check}, #{state}, #{check_output}, #{check_long_output}"
|
43
43
|
|
44
44
|
state = 'ok' if state.downcase == 'up'
|
45
45
|
state = 'critical' if state.downcase == 'down'
|
46
|
+
details = check_long_output ? check_long_output.gsub(/\\n/, "\n") : nil
|
46
47
|
event = {
|
47
48
|
'entity' => entity,
|
48
49
|
'check' => check,
|
49
50
|
'type' => 'service',
|
50
51
|
'state' => state,
|
51
52
|
'summary' => check_output,
|
53
|
+
'details' => details,
|
52
54
|
'timestamp' => timestamp,
|
53
55
|
}.to_json
|
54
56
|
redis.lpush 'events', event
|
@@ -63,7 +65,7 @@ def main(opts)
|
|
63
65
|
redis = Redis.new(opts[:redis_options])
|
64
66
|
while true
|
65
67
|
process_input(:redis => redis, :fifo => fifo)
|
66
|
-
puts "Whoops, restarting main loop in 10 seconds"
|
68
|
+
puts "Whoops with the fifo, restarting main loop in 10 seconds"
|
67
69
|
sleep 10
|
68
70
|
end
|
69
71
|
end
|
@@ -6,22 +6,45 @@ Feature: Notification rules on a per contact basis
|
|
6
6
|
| id | first_name | last_name | email | sms | timezone |
|
7
7
|
| 1 | Malak | Al-Musawi | malak@example.com | +61400000001 | Asia/Baghdad |
|
8
8
|
| 2 | Imani | Farooq | imani@example.com | +61400000002 | Europe/Moscow |
|
9
|
+
| 3 | Vera | Дурейко | vera@example.com | +61400000003 | Europe/Paris |
|
9
10
|
|
10
11
|
And the following entities exist:
|
11
12
|
| id | name | contacts |
|
12
13
|
| 1 | foo | 1 |
|
13
|
-
| 2 | bar | 1,2
|
14
|
-
| 3 | baz | 1
|
14
|
+
| 2 | bar | 1,2,3 |
|
15
|
+
| 3 | baz | 1,3 |
|
16
|
+
| 4 | buf | 1,2,3 |
|
15
17
|
|
16
18
|
And user 1 has the following notification intervals:
|
17
19
|
| email | sms |
|
18
20
|
| 15 | 60 |
|
19
21
|
|
22
|
+
And user 2 has the following notification intervals:
|
23
|
+
| email | sms |
|
24
|
+
| 15 | 60 |
|
25
|
+
|
26
|
+
And user 3 has the following notification intervals:
|
27
|
+
| email | sms |
|
28
|
+
| 15 | 60 |
|
29
|
+
|
20
30
|
And user 1 has the following notification rules:
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
| entities | entity_tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
32
|
+
| foo | | email | sms,email | | | 8-18 weekdays |
|
33
|
+
| bar | | | sms,email | true | | |
|
34
|
+
| baz | | email | sms,email | | | |
|
35
|
+
|
36
|
+
And user 2 has the following notification rules:
|
37
|
+
| entities | entity_tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
38
|
+
| | | email | email | | | |
|
39
|
+
| | | sms | sms | | | |
|
40
|
+
| bar | | email | email,sms | | | |
|
41
|
+
|
42
|
+
And user 3 has the following notification rules:
|
43
|
+
| entities | entity_tags | warning_media | critical_media | warning_blackhole | critical_blackhole | time_restrictions |
|
44
|
+
| buf | | email | email | | | |
|
45
|
+
| buf | | sms | sms | | | |
|
46
|
+
| | | email | email | | | |
|
47
|
+
| baz | | sms | sms | | | |
|
25
48
|
|
26
49
|
@time_restrictions @time
|
27
50
|
Scenario: Alerts only during specified time restrictions
|
@@ -152,3 +175,58 @@ Feature: Notification rules on a per contact basis
|
|
152
175
|
And a critical event is received
|
153
176
|
Then 3 email alerts should be queued for malak@example.com
|
154
177
|
And 3 sms alerts should be queued for +61400000001
|
178
|
+
|
179
|
+
@time
|
180
|
+
Scenario: Contact with only entity specific rules should not be notified for other entities they are a contact for
|
181
|
+
Given the check is check 'ping' on entity 'buf'
|
182
|
+
And the check is in an ok state
|
183
|
+
When a critical event is received
|
184
|
+
And 1 minute passes
|
185
|
+
And a critical event is received
|
186
|
+
Then no email alerts should be queued for malak@example.com
|
187
|
+
|
188
|
+
@time
|
189
|
+
Scenario: Contact with entity specific rules and general rules should be notified for other entities they are a contact for
|
190
|
+
Given the check is check 'ping' on entity 'buf'
|
191
|
+
And the check is in an ok state
|
192
|
+
When a critical event is received
|
193
|
+
And 1 minute passes
|
194
|
+
And a critical event is received
|
195
|
+
Then 1 email alert should be queued for imani@example.com
|
196
|
+
|
197
|
+
@time
|
198
|
+
Scenario: Mutiple rules for an entity should be additive
|
199
|
+
Given the check is check 'ping' on entity 'buf'
|
200
|
+
And the check is in an ok state
|
201
|
+
When a critical event is received
|
202
|
+
And 1 minute passes
|
203
|
+
And a critical event is received
|
204
|
+
Then 1 email alert should be queued for vera@example.com
|
205
|
+
Then 1 sms alert should be queued for +61400000003
|
206
|
+
|
207
|
+
@time
|
208
|
+
Scenario: Multiple general rules should be additive
|
209
|
+
Given the check is check 'ping' on entity 'buf'
|
210
|
+
And the check is in an ok state
|
211
|
+
When a critical event is received
|
212
|
+
And 1 minute passes
|
213
|
+
And a critical event is received
|
214
|
+
Then 1 email alert should be queued for imani@example.com
|
215
|
+
Then 1 sms alert should be queued for +61400000002
|
216
|
+
|
217
|
+
@time
|
218
|
+
Scenario: An entity specific rule should override general rules
|
219
|
+
Given the check is check 'ping' on entity 'baz'
|
220
|
+
And the check is in an ok state
|
221
|
+
When a critical event is received
|
222
|
+
And 1 minute passes
|
223
|
+
And a critical event is received
|
224
|
+
Then 0 email alerts should be queued for vera@example.com
|
225
|
+
Then 1 sms alert should be queued for +61400000003
|
226
|
+
|
227
|
+
@time
|
228
|
+
Scenario: A blackhole rule on an entity should override another matching entity specific rule
|
229
|
+
|
230
|
+
@time
|
231
|
+
Scenario: A blackhole rule on an entity should override another matching general rule
|
232
|
+
|
@@ -94,6 +94,7 @@ module Flapjack
|
|
94
94
|
event = { 'type' => 'action',
|
95
95
|
'state' => 'test_notifications',
|
96
96
|
'summary' => options['summary'],
|
97
|
+
'details' => options['details'],
|
97
98
|
'entity' => entity.name,
|
98
99
|
'check' => check
|
99
100
|
}
|
@@ -221,6 +222,7 @@ module Flapjack
|
|
221
222
|
timestamp = options[:timestamp] || Time.now.to_i
|
222
223
|
client = options[:client]
|
223
224
|
summary = options[:summary]
|
225
|
+
details = options[:details]
|
224
226
|
count = options[:count]
|
225
227
|
|
226
228
|
# Note the current state (for speedy lookups)
|
@@ -233,6 +235,7 @@ module Flapjack
|
|
233
235
|
@redis.rpush("#{@key}:states", timestamp)
|
234
236
|
@redis.set("#{@key}:#{timestamp}:state", state)
|
235
237
|
@redis.set("#{@key}:#{timestamp}:summary", summary) if summary
|
238
|
+
@redis.set("#{@key}:#{timestamp}:details", details) if details
|
236
239
|
@redis.set("#{@key}:#{timestamp}:count", count) if count
|
237
240
|
|
238
241
|
@redis.zadd("#{@key}:sorted_state_timestamps", timestamp, timestamp)
|
@@ -349,6 +352,11 @@ module Flapjack
|
|
349
352
|
@redis.get("#{@key}:#{timestamp}:summary")
|
350
353
|
end
|
351
354
|
|
355
|
+
def details
|
356
|
+
timestamp = @redis.lindex("#{@key}:states", -1)
|
357
|
+
@redis.get("#{@key}:#{timestamp}:details")
|
358
|
+
end
|
359
|
+
|
352
360
|
# Returns a list of states for this entity check, sorted by timestamp.
|
353
361
|
#
|
354
362
|
# start_time and end_time should be passed as integer timestamps; these timestamps
|
@@ -368,7 +376,8 @@ module Flapjack
|
|
368
376
|
state_data = state_ts.collect {|ts|
|
369
377
|
{:timestamp => ts.to_i,
|
370
378
|
:state => r.get("#{@key}:#{ts}:state"),
|
371
|
-
:summary => r.get("#{@key}:#{ts}:summary")
|
379
|
+
:summary => r.get("#{@key}:#{ts}:summary"),
|
380
|
+
:details => r.get("#{@key}:#{ts}:details")}
|
372
381
|
}
|
373
382
|
end
|
374
383
|
|
@@ -392,7 +401,8 @@ module Flapjack
|
|
392
401
|
return if ts.nil? || ts.empty?
|
393
402
|
{:timestamp => ts.first.to_i,
|
394
403
|
:state => @redis.get("#{@key}:#{ts.first}:state"),
|
395
|
-
:summary => @redis.get("#{@key}:#{ts.first}:summary")
|
404
|
+
:summary => @redis.get("#{@key}:#{ts.first}:summary"),
|
405
|
+
:details => @redis.get("#{@key}:#{ts.first}:details")}
|
396
406
|
end
|
397
407
|
|
398
408
|
# Returns a list of maintenance periods (either unscheduled or scheduled) for this
|
data/lib/flapjack/data/event.rb
CHANGED
@@ -218,13 +218,13 @@ module Flapjack
|
|
218
218
|
d[:entity_tags].all? {|et| et.is_a?(String)} ) } =>
|
219
219
|
"entity_tags must be a list of strings",
|
220
220
|
|
221
|
-
proc { (d.has_key?(:entities) &&
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
"entities or entity tags must have at least one value",
|
221
|
+
#proc { (d.has_key?(:entities) &&
|
222
|
+
# d[:entities].is_a?(Array) &&
|
223
|
+
# (d[:entities].size > 0)) ||
|
224
|
+
# (d.has_key?(:entity_tags) &&
|
225
|
+
# d[:entity_tags].is_a?(Array) &&
|
226
|
+
# (d[:entity_tags].size > 0)) } =>
|
227
|
+
#"entities or entity tags must have at least one value",
|
228
228
|
|
229
229
|
proc { !d.has_key?(:time_restrictions) ||
|
230
230
|
( d[:time_restrictions].nil? ||
|
data/lib/flapjack/executive.rb
CHANGED
@@ -208,7 +208,7 @@ module Flapjack
|
|
208
208
|
if event.state != event.previous_state
|
209
209
|
entity_check.update_state(event.state, :timestamp => timestamp,
|
210
210
|
:summary => event.summary, :client => event.client,
|
211
|
-
:count => @event_count)
|
211
|
+
:count => @event_count, :details => event.details)
|
212
212
|
end
|
213
213
|
|
214
214
|
# No state change, and event is ok, so no need to run through filters
|
@@ -314,16 +314,23 @@ module Flapjack
|
|
314
314
|
# don't consider notification rules if the contact has none
|
315
315
|
|
316
316
|
tuple = messages.map do |message|
|
317
|
-
@logger.debug "considering message for contact: #{message.contact.id} #{message.medium} #{message.notification.event.id} #{message.notification.event.state}"
|
318
317
|
rules = message.contact.notification_rules
|
319
|
-
@logger.debug "found #{rules.length} rules for this message's contact"
|
320
318
|
event_id = message.notification.event.id
|
319
|
+
|
320
|
+
@logger.debug "considering message for contact: #{message.contact.id} #{message.medium} #{event_id} #{message.notification.event.state}"
|
321
|
+
@logger.debug "found #{rules.length} rules for this message's contact"
|
322
|
+
|
321
323
|
options = {}
|
322
324
|
options[:no_rules_for_contact] = true if rules.empty?
|
325
|
+
|
323
326
|
# filter based on entity, tags, severity, time of day
|
324
327
|
matchers = rules.find_all do |rule|
|
325
328
|
rule.match_entity?(event_id) && rule_occurring_now?(rule, :contact => message.contact)
|
326
329
|
end
|
330
|
+
@logger.debug "#{matchers.length} matchers remain for this message:"
|
331
|
+
matchers.each {|matcher|
|
332
|
+
@logger.debug "matcher: #{matcher.to_json}"
|
333
|
+
}
|
327
334
|
[message, matchers, options]
|
328
335
|
end
|
329
336
|
|
@@ -332,19 +339,26 @@ module Flapjack
|
|
332
339
|
|
333
340
|
@logger.debug "apply_notification_rules: num messages after entity and time matching: #{tuple.size}"
|
334
341
|
|
335
|
-
# delete
|
342
|
+
# delete any matchers for all entities if there are more specific matchers
|
336
343
|
tuple = tuple.map do |message, matchers, options|
|
344
|
+
num_matchers = matchers.length
|
337
345
|
if matchers.length > 1
|
346
|
+
@logger.debug("general removal when entity specific: #{matchers.length} matchers")
|
338
347
|
have_specific = matchers.detect do |matcher|
|
339
|
-
matcher.entities
|
348
|
+
( matcher.entities && !matcher.entities.empty? ) or
|
349
|
+
( matcher.entity_tags && !matcher.entity_tags.empty? )
|
340
350
|
end
|
341
351
|
if have_specific
|
342
|
-
# delete
|
352
|
+
# delete any rules for all entities
|
343
353
|
matchers.reject! do |matcher|
|
344
|
-
matcher.entities.nil?
|
354
|
+
( matcher.entities.nil? || matcher.entities.empty? ) &&
|
355
|
+
( matcher.entity_tags.nil? || matcher.entity_tags.empty? )
|
345
356
|
end
|
346
357
|
end
|
347
358
|
end
|
359
|
+
if num_matchers != matchers.length
|
360
|
+
@logger.debug("apply_notification_rules: removal of general matchers when entity specific matchers are present: number of matchers changed from #{num_matchers} to #{matchers.length} for message id: #{message.contact.id}, medium: #{message.medium}")
|
361
|
+
end
|
348
362
|
[message, matchers, options]
|
349
363
|
end
|
350
364
|
|
@@ -361,6 +375,7 @@ module Flapjack
|
|
361
375
|
state = message.notification.event.state
|
362
376
|
max_notified_severity = message.notification.max_notified_severity
|
363
377
|
|
378
|
+
@logger.debug "apply_notification_rules severity-media constraints: considering message: #{message.contact.id} #{message.medium} #{state}"
|
364
379
|
# use EntityCheck#max_notified_severity_of_current_failure
|
365
380
|
# as calculated prior to updating the last_notification* keys
|
366
381
|
# if it's a higher severity than the current state
|
@@ -371,10 +386,13 @@ module Flapjack
|
|
371
386
|
when [state, max_notified_severity].include?('warning')
|
372
387
|
severity = 'warning'
|
373
388
|
end
|
374
|
-
|
375
|
-
|
389
|
+
|
390
|
+
no_rules_for_contact = !!options[:no_rules_for_contact]
|
391
|
+
sev_media_matchers = matchers.any? {|matcher|
|
376
392
|
(matcher.media_for_severity(severity) || []).include?(message.medium)
|
377
393
|
}
|
394
|
+
@logger.debug "apply_notification_rules severity-media constraints: no_rules_for_contact: #{no_rules_for_contact}, sev_media_matchers: #{sev_media_matchers}"
|
395
|
+
no_rules_for_contact || sev_media_matchers
|
378
396
|
end
|
379
397
|
|
380
398
|
@logger.debug "apply_notification_rules: num messages after pruning for severity-media constraints: #{tuple.size}"
|
@@ -32,6 +32,7 @@ module Flapjack
|
|
32
32
|
@contact_last_name = notification['contact_last_name']
|
33
33
|
@state = notification['state']
|
34
34
|
@summary = notification['summary']
|
35
|
+
@details = notification['details']
|
35
36
|
@time = notification['time']
|
36
37
|
@entity_name, @check = notification['event_id'].split(':')
|
37
38
|
|
@@ -128,7 +128,7 @@ module Flapjack
|
|
128
128
|
dur = nil
|
129
129
|
|
130
130
|
if comment.nil? || (comment.length == 0)
|
131
|
-
error = "please provide a comment, eg \"
|
131
|
+
error = "please provide a comment, eg \"#{@config['alias']}: ACKID #{$1} AL looking\""
|
132
132
|
elsif duration_str
|
133
133
|
# a fairly liberal match above, we'll let chronic_duration do the heavy lifting
|
134
134
|
dur = ChronicDuration.parse(duration_str)
|
@@ -180,6 +180,7 @@ module Flapjack
|
|
180
180
|
@check_last_update = entity_check.last_update
|
181
181
|
@check_last_change = last_change
|
182
182
|
@check_summary = entity_check.summary
|
183
|
+
@check_details = entity_check.details
|
183
184
|
@last_notifications = entity_check.last_notifications_of_each_type
|
184
185
|
@scheduled_maintenances = entity_check.maintenances(nil, nil, :scheduled => true)
|
185
186
|
@acknowledgement_id = entity_check.failed? ?
|
@@ -34,6 +34,7 @@
|
|
34
34
|
- if @current_scheduled_maintenance
|
35
35
|
%h4 (Scheduled Maintenance - #{@current_scheduled_maintenance[:summary]})
|
36
36
|
%h3 Output: #{@check_summary}
|
37
|
+
%p #{@check_details}
|
37
38
|
%table{:class => "table table-hover table-condensed"}
|
38
39
|
%tr
|
39
40
|
%td Last state change:
|
@@ -15,7 +15,7 @@
|
|
15
15
|
%p #{@count_failing_entities} failing out of #{@count_all_entities}
|
16
16
|
%table{:class => "table table-bordered table-hover table-condensed"}
|
17
17
|
- if @entities.length > 0
|
18
|
-
- @entities.each do |entity|
|
18
|
+
- @entities.sort.each do |entity|
|
19
19
|
%tr
|
20
20
|
%td
|
21
21
|
- link = "/entity/#{CGI.escape(entity)}"
|
data/lib/flapjack/version.rb
CHANGED
@@ -95,8 +95,7 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
95
95
|
context 'validation' do
|
96
96
|
|
97
97
|
it "fails to add a notification rule with invalid data" do
|
98
|
-
rule_data[:entities] = []
|
99
|
-
rule_data[:entity_tags] = []
|
98
|
+
rule_data[:entities] = [1, {}]
|
100
99
|
rule = Flapjack::Data::NotificationRule.add(rule_data, :redis => @redis)
|
101
100
|
rule.should be_nil
|
102
101
|
end
|
@@ -112,4 +111,4 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
112
111
|
|
113
112
|
end
|
114
113
|
|
115
|
-
end
|
114
|
+
end
|
@@ -45,12 +45,14 @@ describe Flapjack::Data::Notification, :redis => true do
|
|
45
45
|
event.should_receive(:id).and_return('example.com:ping')
|
46
46
|
event.should_receive(:state).and_return('ok')
|
47
47
|
event.should_receive(:summary).and_return('Shiny & happy')
|
48
|
+
event.should_receive(:details).and_return('Really Shiny & happy')
|
48
49
|
event.should_receive(:time).and_return(t)
|
49
50
|
event.should_receive(:duration).and_return(nil)
|
50
51
|
|
51
52
|
notification.contents.should == {'event_id' => 'example.com:ping',
|
52
53
|
'state' => 'ok',
|
53
54
|
'summary' => 'Shiny & happy',
|
55
|
+
'details' => 'Really Shiny & happy',
|
54
56
|
'time' => t,
|
55
57
|
'duration' => nil,
|
56
58
|
'notification_type' => 'problem',
|
@@ -58,4 +60,4 @@ describe Flapjack::Data::Notification, :redis => true do
|
|
58
60
|
|
59
61
|
end
|
60
62
|
|
61
|
-
end
|
63
|
+
end
|
@@ -122,6 +122,7 @@ describe Flapjack::Gateways::Web, :sinatra => true, :logger => true do
|
|
122
122
|
entity_check.should_receive(:last_update).and_return(time - (3 * 60 * 60))
|
123
123
|
entity_check.should_receive(:last_change).and_return(time - (3 * 60 * 60))
|
124
124
|
entity_check.should_receive(:summary).and_return('all good')
|
125
|
+
entity_check.should_receive(:details).and_return('seriously, all very wonderful')
|
125
126
|
entity_check.should_receive(:last_notifications_of_each_type).and_return(last_notifications)
|
126
127
|
entity_check.should_receive(:maintenances).with(nil, nil, :scheduled => true).and_return([])
|
127
128
|
entity_check.should_receive(:failed?).and_return(false)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flapjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-05-
|
14
|
+
date: 2013-05-30 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: dante
|
@@ -553,7 +553,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
553
553
|
version: '0'
|
554
554
|
segments:
|
555
555
|
- 0
|
556
|
-
hash:
|
556
|
+
hash: 3433474727648053171
|
557
557
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
558
558
|
none: false
|
559
559
|
requirements:
|
@@ -562,7 +562,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
562
562
|
version: '0'
|
563
563
|
segments:
|
564
564
|
- 0
|
565
|
-
hash:
|
565
|
+
hash: 3433474727648053171
|
566
566
|
requirements: []
|
567
567
|
rubyforge_project:
|
568
568
|
rubygems_version: 1.8.23
|