flapjack 1.6.0rc2 → 1.6.0rc3
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 +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/flapjack/data/entity_check.rb +4 -1
- data/lib/flapjack/data/notification_rule.rb +17 -15
- data/lib/flapjack/gateways/aws_sns.rb +4 -6
- data/lib/flapjack/gateways/aws_sns/alert.text.erb +1 -1
- data/lib/flapjack/gateways/email/rollup.html.erb +3 -0
- data/lib/flapjack/notifier.rb +2 -1
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/data/notification_rule_spec.rb +46 -4
- data/spec/lib/flapjack/gateways/aws_sns_spec.rb +6 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a219d75b1878de449c0a2735258b2962516b75b
|
4
|
+
data.tar.gz: 66d8c984b4204482680ffeaa711f540ab60c4297
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb07615b716a155706165d2bec88ec020df60602ef75e45ae8c5911aca3032dc1e1b3198d7a9e972614ea166cc04adfc43d6fe3e94739594e74ad159d43c9912
|
7
|
+
data.tar.gz: 877f7c37d41c7068799a26012463f254b15c3bd1698ee66eca186f09a4ad317de6f9bf0cbfb446620f586bff2d088a8a9b68cf5c6e817207affd20ed10543d0d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## Flapjack Changelog
|
2
2
|
|
3
|
+
# 1.6.0rc3 - 2015-06-15
|
4
|
+
- Chore/Bug?: SNS gateway improvements (@ali-graham)
|
5
|
+
- Feature: add summary to rollup alerts #869 (@necula-01)
|
6
|
+
- Bug: Fix notification rule regex matches #871 (@necula-01)
|
7
|
+
|
3
8
|
# 1.6.0rc2 - 2015-05-14
|
4
9
|
- Bug: Fix SNS query encoding and subject length #867 (@ali-graham, @xcxsxvx)
|
5
10
|
- Chore: improve debug logging in pagerduty when looking for acks e44abd5 (@jessereynolds)
|
@@ -933,7 +933,10 @@ module Flapjack
|
|
933
933
|
if @ack_hash.nil?
|
934
934
|
sha1 = Digest::SHA1.new
|
935
935
|
@ack_hash = Digest.hexencode(sha1.digest(@key))[0..7].downcase
|
936
|
-
@redis.
|
936
|
+
@redis.multi do |r|
|
937
|
+
r.hset("checks_by_hash", @ack_hash, @key)
|
938
|
+
r.hset("check_hashes_by_id", @key, @ack_hash)
|
939
|
+
end
|
937
940
|
end
|
938
941
|
@ack_hash
|
939
942
|
end
|
@@ -121,37 +121,39 @@ module Flapjack
|
|
121
121
|
Flapjack.dump_json(json_data)
|
122
122
|
end
|
123
123
|
|
124
|
-
#
|
124
|
+
# If the rule has any entities, then one of them must match the event's entity
|
125
125
|
def match_entity?(event_id)
|
126
|
-
return
|
127
|
-
|
126
|
+
return true unless @entities && @entities.length > 0
|
127
|
+
event_entity = event_id.split(':').first
|
128
|
+
@entities.include?(event_entity)
|
128
129
|
end
|
129
130
|
|
130
|
-
#
|
131
|
+
# If the rule has any regex_entities, then all of them must match the
|
132
|
+
# event's entity
|
131
133
|
def match_regex_entities?(event_id)
|
132
|
-
return
|
133
|
-
|
134
|
+
return true unless @regex_entities && @regex_entities.length > 0
|
135
|
+
event_entity = event_id.split(':').first
|
134
136
|
matches = 0
|
135
137
|
@regex_entities.each do |regex_entity|
|
136
|
-
matches += 1 if /#{regex_entity}/ ===
|
138
|
+
matches += 1 if /#{regex_entity}/ === event_entity
|
137
139
|
end
|
138
140
|
matches >= @regex_entities.length
|
139
141
|
end
|
140
142
|
|
141
|
-
# tags
|
143
|
+
# If the rule has any tags, then they must all be present in the
|
144
|
+
# event's tags
|
142
145
|
def match_tags?(event_tags)
|
143
|
-
return
|
146
|
+
return true unless @tags && @tags.length > 0
|
144
147
|
@tags.subset?(event_tags)
|
145
148
|
end
|
146
149
|
|
147
|
-
# regex_tags match
|
150
|
+
# If the rule has any regex_tags, then they must all match at least
|
151
|
+
# one of the event's tags
|
148
152
|
def match_regex_tags?(event_tags)
|
149
|
-
return
|
153
|
+
return true unless @regex_tags && @regex_tags.length > 0
|
150
154
|
matches = 0
|
151
|
-
|
152
|
-
|
153
|
-
matches += 1 if /#{regex_tag}/ === event_tag
|
154
|
-
end
|
155
|
+
@regex_tags.each do |regex_tag|
|
156
|
+
matches += 1 if event_tags.any? { |event_tag| /#{regex_tag}/ === event_tag }
|
155
157
|
end
|
156
158
|
matches >= @regex_tags.length
|
157
159
|
end
|
@@ -60,7 +60,7 @@ module Flapjack
|
|
60
60
|
endpoint = "http://#{hostname}/"
|
61
61
|
access_key = @config["access_key"]
|
62
62
|
secret_key = @config["secret_key"]
|
63
|
-
timestamp =
|
63
|
+
timestamp = Time.at(alert.time).strftime('%Y-%m-%dT%H:%M:%SZ')
|
64
64
|
|
65
65
|
address = alert.address
|
66
66
|
notification_id = alert.notification_id
|
@@ -118,7 +118,7 @@ module Flapjack
|
|
118
118
|
'SignatureVersion' => 2,
|
119
119
|
'SignatureMethod' => 'HmacSHA256',
|
120
120
|
'Timestamp' => timestamp,
|
121
|
-
'AWSAccessKeyId' => access_key}
|
121
|
+
'AWSAccessKeyId' => access_key.upcase}
|
122
122
|
|
123
123
|
string_to_sign = self.class.string_to_sign('POST', hostname, "/", query)
|
124
124
|
|
@@ -145,7 +145,7 @@ module Flapjack
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def self.get_signature(secret_key, string_to_sign)
|
148
|
-
signature = OpenSSL::HMAC.digest('sha256', secret_key, string_to_sign)
|
148
|
+
signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret_key, string_to_sign)
|
149
149
|
|
150
150
|
Base64.encode64(signature).strip
|
151
151
|
end
|
@@ -153,10 +153,8 @@ module Flapjack
|
|
153
153
|
def self.string_to_sign(method, host, uri, query)
|
154
154
|
@safe_re ||= Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
155
155
|
|
156
|
-
# we should possibly escape the keys as well, but they are less
|
157
|
-
# likely to have problematic characters
|
158
156
|
encoded_query = query.keys.sort.collect {|key|
|
159
|
-
"#{key}=#{URI.escape(query[key].to_s, @safe_re)}"
|
157
|
+
"#{URI.escape(key, @safe_re)}=#{URI.escape(query[key].to_s, @safe_re)}"
|
160
158
|
}.join("&")
|
161
159
|
|
162
160
|
[method.upcase,
|
@@ -22,16 +22,19 @@
|
|
22
22
|
<th>Entity</th>
|
23
23
|
<th>State</th>
|
24
24
|
<th>Duration</th>
|
25
|
+
<th>Summary</th>
|
25
26
|
</tr>
|
26
27
|
<% @alert.rollup_alerts.sort_by {|entity_check, details| details['duration'] }.each do |rollup_alert| -%>
|
27
28
|
<% r_entity, r_check = rollup_alert[0].split(':', 2) -%>
|
28
29
|
<% state = rollup_alert[1]['state'] -%>
|
29
30
|
<% duration = (ChronicDuration.output(rollup_alert[1]['duration'], :keep_zero => true) || '0 secs') -%>
|
31
|
+
<% summary = rollup_alert[1]['summary'] -%>
|
30
32
|
<tr>
|
31
33
|
<td><%= r_check %></td>
|
32
34
|
<td><%= r_entity %></td>
|
33
35
|
<td><%= ['ok'].include?(state) ? state.upcase : state.titleize %></td>
|
34
36
|
<td><%= duration %></td>
|
37
|
+
<td><%= summary %></td>
|
35
38
|
</tr>
|
36
39
|
<% end %>
|
37
40
|
</tbody>
|
data/lib/flapjack/notifier.rb
CHANGED
data/lib/flapjack/version.rb
CHANGED
@@ -16,7 +16,23 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
16
16
|
{:contact_id => '23',
|
17
17
|
:tags => ["database","physical"],
|
18
18
|
:regex_tags => [],
|
19
|
-
:entities => ["foo-app-01.example.com"],
|
19
|
+
:entities => ["foo-app-01.example.com", "foo-app-10.example.com"],
|
20
|
+
:regex_entities => [],
|
21
|
+
:time_restrictions => [ weekdays_8_18 ],
|
22
|
+
:unknown_media => [],
|
23
|
+
:warning_media => ["email"],
|
24
|
+
:critical_media => ["sms", "email"],
|
25
|
+
:unknown_blackhole => false,
|
26
|
+
:warning_blackhole => false,
|
27
|
+
:critical_blackhole => false
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
let(:empty_rule_data) {
|
32
|
+
{:contact_id => '23',
|
33
|
+
:tags => [],
|
34
|
+
:regex_tags => [],
|
35
|
+
:entities => [],
|
20
36
|
:regex_entities => [],
|
21
37
|
:time_restrictions => [ weekdays_8_18 ],
|
22
38
|
:unknown_media => [],
|
@@ -33,7 +49,7 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
33
49
|
:tags => [],
|
34
50
|
:regex_tags => ["^data.*$","^(physical|bare_metal)$"],
|
35
51
|
:entities => [],
|
36
|
-
:regex_entities => [
|
52
|
+
:regex_entities => ['^foo-\S{3}-\d{2}.example.com$','.*abc.*'],
|
37
53
|
:time_restrictions => [ weekdays_8_18 ],
|
38
54
|
:unknown_media => [],
|
39
55
|
:warning_media => ["email"],
|
@@ -52,6 +68,10 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
52
68
|
Flapjack::Data::NotificationRule.add(rule_data, :redis => @redis)
|
53
69
|
}
|
54
70
|
|
71
|
+
let(:existing_empty_rule) {
|
72
|
+
Flapjack::Data::NotificationRule.add(empty_rule_data, :redis => @redis)
|
73
|
+
}
|
74
|
+
|
55
75
|
let(:existing_regex_rule) {
|
56
76
|
Flapjack::Data::NotificationRule.add(regex_rule_data, :redis => @redis)
|
57
77
|
}
|
@@ -100,25 +120,47 @@ describe Flapjack::Data::NotificationRule, :redis => true do
|
|
100
120
|
rule = existing_rule
|
101
121
|
|
102
122
|
expect(rule.match_entity?('foo-app-01.example.com')).to be true
|
123
|
+
expect(rule.match_entity?('foo-app-10.example.com')).to be true
|
103
124
|
expect(rule.match_entity?('foo-app-02.example.com')).to be false
|
125
|
+
|
126
|
+
expect(existing_empty_rule.match_entity?('anything.example.com')).to be true
|
127
|
+
end
|
128
|
+
|
129
|
+
it "checks whether entity names match a regex" do
|
130
|
+
rule = existing_regex_rule
|
131
|
+
|
132
|
+
expect(rule.match_regex_entities?('foo-abc-01.example.com')).to be true
|
133
|
+
expect(rule.match_regex_entities?('foo-abc-99.example.com')).to be true
|
134
|
+
expect(rule.match_regex_entities?('foo-app-01.example.com')).to be false # does not match second regexp_entities
|
135
|
+
expect(rule.match_regex_entities?('foo-abc.example.com')).to be false
|
136
|
+
expect(rule.match_regex_entities?('bar-abc-01.example.com')).to be false
|
137
|
+
|
138
|
+
expect(existing_empty_rule.match_regex_entities?('anything.example.com')).to be true
|
104
139
|
end
|
105
140
|
|
106
|
-
it "checks whether
|
141
|
+
it "checks whether event tags match" do
|
107
142
|
rule = existing_rule
|
108
143
|
|
109
144
|
expect(rule.match_tags?(['database', 'physical'].to_set)).to be true
|
110
145
|
expect(rule.match_tags?(['database', 'physical', 'beetroot'].to_set)).to be true
|
111
146
|
expect(rule.match_tags?(['database'].to_set)).to be false
|
112
147
|
expect(rule.match_tags?(['virtual'].to_set)).to be false
|
148
|
+
expect(rule.match_tags?([].to_set)).to be false
|
149
|
+
|
150
|
+
expect(existing_empty_rule.match_regex_entities?(['virtual'].to_set)).to be true
|
113
151
|
end
|
114
152
|
|
115
|
-
it "checks whether
|
153
|
+
it "checks whether event tags match a regex" do
|
116
154
|
rule = existing_regex_rule
|
117
155
|
|
118
156
|
expect(rule.match_regex_tags?(['database', 'physical'].to_set)).to be true
|
119
157
|
expect(rule.match_regex_tags?(['database', 'physical', 'beetroot'].to_set)).to be true
|
120
158
|
expect(rule.match_regex_tags?(['database'].to_set)).to be false
|
159
|
+
expect(rule.match_regex_tags?(['database.physical'].to_set)).to be false # does not match second regex_tags
|
160
|
+
expect(rule.match_regex_tags?(['data1', 'data2'].to_set)).to be false # does not match second regex_tags
|
121
161
|
expect(rule.match_regex_tags?(['virtual'].to_set)).to be false
|
162
|
+
|
163
|
+
expect(existing_empty_rule.match_regex_entities?(['virtual'].to_set)).to be true
|
122
164
|
end
|
123
165
|
|
124
166
|
it "checks if blackhole settings for a rule match a severity level" do
|
@@ -9,7 +9,7 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
|
|
9
9
|
|
10
10
|
let(:time) { Time.new(2013, 10, 31, 13, 45) }
|
11
11
|
|
12
|
-
let(:time_str) { Time.at(time).strftime('
|
12
|
+
let(:time_str) { Time.at(time.to_i).strftime('%Y-%m-%dT%H:%M:%SZ') }
|
13
13
|
|
14
14
|
let(:config) { {'region' => 'us-east-1',
|
15
15
|
'access_key' => 'AKIAIOSFODNN7EXAMPLE',
|
@@ -39,7 +39,9 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
|
|
39
39
|
'AWSAccessKeyId' => config['access_key'],
|
40
40
|
'TopicArn' => message['address'],
|
41
41
|
'SignatureVersion' => '2',
|
42
|
-
'SignatureMethod' => 'HmacSHA256'
|
42
|
+
'SignatureMethod' => 'HmacSHA256',
|
43
|
+
'Signature' => 'gxoUQ8qUYBQbqgf3XmbiSPZ8qTJZ9WyC81EKc67FY0g=',
|
44
|
+
'Timestamp' => time_str})).
|
43
45
|
to_return(:status => 200)
|
44
46
|
|
45
47
|
EM.synchrony do
|
@@ -98,7 +100,7 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
|
|
98
100
|
|
99
101
|
let(:query) { {'TopicArn' => 'HelloWorld',
|
100
102
|
'Action' => 'Publish',
|
101
|
-
'Message' => 'Hello World'} }
|
103
|
+
'Message' => 'Hello ~ World'} }
|
102
104
|
|
103
105
|
let(:string_to_sign) { Flapjack::Gateways::AwsSns.string_to_sign(method, host, uri, query) }
|
104
106
|
|
@@ -117,7 +119,7 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
|
|
117
119
|
end
|
118
120
|
|
119
121
|
it 'should put the encoded, sorted query-string on the fourth line' do
|
120
|
-
expect(lines[3]).to eq("Action=Publish&Message=Hello%20World&TopicArn=HelloWorld")
|
122
|
+
expect(lines[3]).to eq("Action=Publish&Message=Hello%20~%20World&TopicArn=HelloWorld")
|
121
123
|
end
|
122
124
|
|
123
125
|
end
|
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: 1.6.
|
4
|
+
version: 1.6.0rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lindsay Holmwood
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-
|
14
|
+
date: 2015-06-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: dante
|