flapjack 1.6.0rc2 → 1.6.0rc3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77cf774d68b395a3d2c146b884788e5e71020479
4
- data.tar.gz: 14de90365627b2362a59e6e0249861c4a070fc5c
3
+ metadata.gz: 5a219d75b1878de449c0a2735258b2962516b75b
4
+ data.tar.gz: 66d8c984b4204482680ffeaa711f540ab60c4297
5
5
  SHA512:
6
- metadata.gz: ef929d2621508fde4072e9b3d66e1139315d581ed2e8304b503fe6e95b8669c82127ce9561e1ceea989b26686d015086a0a213d703341f3d81bf246b08cf87b0
7
- data.tar.gz: 85d21013929b673fc3ca4e0b991c2c6decaec14b7819bd0e19f61186073a3382f0f3b698d2e91f37decdbed0344d3bfb08eeb9ffed3e2be8853dc9ac3093a176
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.hset("checks_by_hash", @ack_hash, @key)
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
- # entity names match?
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 false unless @entities
127
- @entities.include?(event_id.split(':').first)
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
- # entity names match regex?
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 false unless @regex_entities && @regex_entities.length > 0
133
- entity = event_id.split(':').first
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}/ === 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 match?
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 false unless @tags && @tags.length > 0
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 false unless @regex_tags && @regex_tags.length > 0
153
+ return true unless @regex_tags && @regex_tags.length > 0
150
154
  matches = 0
151
- event_tags.each do |event_tag|
152
- @regex_tags.each do |regex_tag|
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 = @config["timestamp"] || DateTime.now.iso8601
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,
@@ -1,4 +1,4 @@
1
- <% summary = @alert.summary %>
1
+ <% summary = @alert.summary -%>
2
2
  <%= @alert.type_sentence_case %>: '<%= @alert.check %>' on <%= @alert.entity -%>
3
3
  <% unless ['acknowledgement', 'test'].include?(@alert.notification_type) -%>
4
4
  is <%= @alert.state_title_case -%>
@@ -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>
@@ -119,7 +119,8 @@ module Flapjack
119
119
  last_change = ec.last_change
120
120
  memo[alert] = {
121
121
  'duration' => last_change ? (Time.now.to_i - last_change) : nil,
122
- 'state' => ec.state
122
+ 'state' => ec.state,
123
+ 'summary' => ec.summary
123
124
  }
124
125
  memo
125
126
  end
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "1.6.0rc2"
4
+ VERSION = "1.6.0rc3"
5
5
  end
@@ -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 => ["^foo-\S{3}-\d{2}.example.com$"],
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 entity tags match" do
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 entity tags match a regex" do
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('%-d %b %H:%M') }
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.0rc2
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-05-14 00:00:00.000000000 Z
14
+ date: 2015-06-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: dante