flapjack 1.6.0rc3 → 1.6.0rc4

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: 5a219d75b1878de449c0a2735258b2962516b75b
4
- data.tar.gz: 66d8c984b4204482680ffeaa711f540ab60c4297
3
+ metadata.gz: ebb781f375968f6795459525d4eb476949f19905
4
+ data.tar.gz: 8b942f1c504d9bdd0ea8e3460c217c0fa1fc7167
5
5
  SHA512:
6
- metadata.gz: bb07615b716a155706165d2bec88ec020df60602ef75e45ae8c5911aca3032dc1e1b3198d7a9e972614ea166cc04adfc43d6fe3e94739594e74ad159d43c9912
7
- data.tar.gz: 877f7c37d41c7068799a26012463f254b15c3bd1698ee66eca186f09a4ad317de6f9bf0cbfb446620f586bff2d088a8a9b68cf5c6e817207affd20ed10543d0d
6
+ metadata.gz: f73ba9354de97136e8b49e9980e83e49687c4007b7881583e34a48ad9d252277c27b2c3c205c6f1c115647509b5b4161d0720ce9c6a403cb8db23d98f1b963b1
7
+ data.tar.gz: f6d5980dbd819dac313aaa7b1faaabaae3eb682ce88cc0aab05f17a0c09d030b00121703b20d3584d100a893c776112feee6bc281b73be872db51611d1eb26ba
@@ -1,5 +1,12 @@
1
1
  ## Flapjack Changelog
2
2
 
3
+ # 1.6.0rc4 - 2015-07-09
4
+ - Feature: slack webhook gateway #881 (@mcqueenorama, @ali-graham)
5
+ - Bug: sns gateway debugging and improvements (but still broken) #879 (@ali-graham, @jessereynolds)
6
+
7
+ ## Notes:
8
+ - the SNS gateway signature calculation has been broken since v1.5.0 or earlier. See [#829](https://github.com/flapjack/flapjack/issues/829)
9
+
3
10
  # 1.6.0rc3 - 2015-06-15
4
11
  - Chore/Bug?: SNS gateway improvements (@ali-graham)
5
12
  - Feature: add summary to rollup alerts #869 (@necula-01)
@@ -40,6 +40,7 @@ production:
40
40
  email_queue: email_notifications
41
41
  sms_queue: sms_notifications
42
42
  sms_nexmo_queue: sms_nexmo_notifications
43
+ slack_queue: slack_notifications
43
44
  sms_twilio_queue: sms_twilio_notifications
44
45
  sns_queue: sns_notifications
45
46
  jabber_queue: jabber_notifications
@@ -102,6 +103,21 @@ production:
102
103
  #templates:
103
104
  # rollup.text: '/etc/flapjack/templates/sms/rollup.text.erb'
104
105
  # alert.text: '/etc/flapjack/templates/sms/alert.text.erb'
106
+ # Sends notifications via Slack
107
+ slack:
108
+ enabled: no
109
+ queue: slack_notifications
110
+ account_sid: "webhookbot"
111
+ endpoint: "https://hooks.slack.com/services/xxx/yyy/"
112
+ auth_token: "zzzzz"
113
+ from: ""
114
+ logger:
115
+ level: INFO
116
+ syslog_errors: yes
117
+ # location of custom alert templates
118
+ #templates:
119
+ # rollup.text: '/etc/flapjack/templates/slack/rollup.text.erb'
120
+ # alert.text: '/etc/flapjack/templates/slack/alert.text.erb'
105
121
  # Sends SMS notifications via Twilio
106
122
  sms_twilio:
107
123
  enabled: no
@@ -113,7 +129,6 @@ production:
113
129
  level: INFO
114
130
  syslog_errors: yes
115
131
  # location of custom alert templates
116
- # location of custom alert templates
117
132
  #templates:
118
133
  # rollup.text: '/etc/flapjack/templates/sms_twilio/rollup.text.erb'
119
134
  # alert.text: '/etc/flapjack/templates/sms_twilio/alert.text.erb'
@@ -24,6 +24,7 @@ module Flapjack
24
24
  ALL_MEDIA = [
25
25
  'email',
26
26
  'sms',
27
+ 'slack',
27
28
  'sms_twilio',
28
29
  'sms_nexmo',
29
30
  'jabber',
@@ -391,8 +392,8 @@ module Flapjack
391
392
  @redis.zadd("contact_alerting_checks:#{self.id}:media:#{media}", Time.now.to_i, event_id)
392
393
  end
393
394
 
394
- def remove_alerting_check_for_media(media, check)
395
- @redis.zrem("contact_alerting_checks:#{self.id}:media:#{media}", check)
395
+ def remove_alerting_check_for_media(media, event_id)
396
+ @redis.zrem("contact_alerting_checks:#{self.id}:media:#{media}", event_id)
396
397
  end
397
398
 
398
399
  # removes any checks that are in ok, scheduled or unscheduled maintenance,
@@ -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 = Time.at(alert.time).strftime('%Y-%m-%dT%H:%M:%SZ')
63
+ timestamp = Time.at(alert.time).utc.strftime('%Y-%m-%dT%H:%M:%SZ')
64
64
 
65
65
  address = alert.address
66
66
  notification_id = alert.notification_id
@@ -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(OpenSSL::Digest.new('sha256'), secret_key, string_to_sign)
148
+ signature = OpenSSL::HMAC.digest('sha256', secret_key, string_to_sign)
149
149
 
150
150
  Base64.encode64(signature).strip
151
151
  end
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'em-synchrony'
4
+ require 'em-synchrony/em-http'
5
+ require 'active_support/inflector'
6
+
7
+ require 'flapjack/redis_pool'
8
+
9
+ require 'flapjack/data/alert'
10
+ require 'flapjack/utility'
11
+
12
+ module Flapjack
13
+ module Gateways
14
+ class Slack
15
+
16
+ include Flapjack::Utility
17
+
18
+ def initialize(opts = {})
19
+ @config = opts[:config]
20
+ @logger = opts[:logger]
21
+ @redis_config = opts[:redis_config] || {}
22
+ @redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 1, :logger => @logger)
23
+
24
+ @logger.info("starting")
25
+ @logger.debug("new slack gateway pikelet with the following options: #{@config.inspect}")
26
+
27
+ @sent = 0
28
+ end
29
+
30
+ def stop
31
+ @logger.info("stopping")
32
+ @should_quit = true
33
+
34
+ redis_uri = @redis_config[:path] ||
35
+ "redis://#{@redis_config[:host] || '127.0.0.1'}:#{@redis_config[:port] || '6379'}/#{@redis_config[:db] || '0'}"
36
+ shutdown_redis = EM::Hiredis.connect(redis_uri)
37
+ shutdown_redis.rpush(@config['queue'], Flapjack.dump_json('notification_type' => 'shutdown'))
38
+ end
39
+
40
+ def start
41
+ queue = @config['queue']
42
+
43
+ until @should_quit
44
+ begin
45
+ @logger.debug("slack gateway is going into blpop mode on #{queue}")
46
+ alert = Flapjack::Data::Alert.next(queue, :redis => @redis, :logger => @logger)
47
+ deliver(alert) unless alert.nil?
48
+ rescue => e
49
+ @logger.error "Error generating or dispatching Slack message: #{e.class}: #{e.message}\n" +
50
+ e.backtrace.join("\n")
51
+ end
52
+ end
53
+ end
54
+
55
+ def deliver(alert)
56
+ account_sid = @config["account_sid"]
57
+ endpoint = @config["endpoint"]
58
+ icon_emoji = @config["icon_emoji"] || ':ghost:'
59
+
60
+ channel = "##{alert.address}"
61
+ channel = '#general' if (channel.size == 1)
62
+ notification_id = alert.notification_id
63
+ message_type = alert.rollup ? 'rollup' : 'alert'
64
+
65
+ slack_template_erb, slack_template =
66
+ load_template(@config['templates'], message_type, 'text',
67
+ File.join(File.dirname(__FILE__), 'slack'))
68
+
69
+ @alert = alert
70
+ bnd = binding
71
+
72
+ begin
73
+ message = slack_template_erb.result(bnd).chomp
74
+ rescue => e
75
+ @logger.error "Error while executing the ERB for an sms: " +
76
+ "ERB being executed: #{slack_template}"
77
+ raise
78
+ end
79
+
80
+ errors = []
81
+
82
+ [
83
+ [endpoint, "Slack endpoint is missing"],
84
+ [account_sid, "Slack account_sid is missing"]
85
+ ].each do |val_err|
86
+
87
+ next unless val_err.first.nil? || (val_err.first.respond_to?(:empty?) && val_err.first.empty?)
88
+ errors << val_err.last
89
+ end
90
+
91
+ unless errors.empty?
92
+ errors.each {|err| @logger.error err }
93
+ return
94
+ end
95
+
96
+ payload = Flapjack.dump_json(
97
+ 'channel' => channel,
98
+ 'username' => account_sid,
99
+ 'text' => message,
100
+ 'icon_emoji' => icon_emoji
101
+ )
102
+ @logger.debug "payload: #{payload.inspect}"
103
+
104
+ http = EM::HttpRequest.new("#{endpoint}").post(:body => {'payload' => payload})
105
+
106
+ @logger.debug "server response: #{http.response}"
107
+
108
+ status = (http.nil? || http.response_header.nil?) ? nil : http.response_header.status
109
+ if (status >= 200) && (status <= 206)
110
+ @sent += 1
111
+ alert.record_send_success!
112
+ @logger.debug "Sent message via Slack, response status is #{status}, " +
113
+ "notification_id: #{notification_id}"
114
+ else
115
+ @logger.error "Failed to send message via Slack, response status is #{status}, " +
116
+ "notification_id: #{notification_id}"
117
+ end
118
+ rescue => e
119
+ @logger.error "Error generating or delivering sms to #{alert.address}: #{e.class}: #{e.message}"
120
+ @logger.error e.backtrace.join("\n")
121
+ raise
122
+ end
123
+
124
+ end
125
+ end
126
+ end
127
+
@@ -0,0 +1,6 @@
1
+ <% summary = @alert.summary -%>
2
+ <%= @alert.type_sentence_case %>: '<%= @alert.check %>' on <%= @alert.entity -%>
3
+ <% unless ['acknowledgement', 'test'].include?(@alert.notification_type) -%>
4
+ is <%= @alert.state_title_case -%>
5
+ <% end -%>
6
+ at <%= Time.at(@alert.time).strftime('%-d %b %H:%M') %><%= (summary.nil? || summary.empty?) ? '' : ", #{summary}" -%>
@@ -0,0 +1,2 @@
1
+ <%= @alert.type_sentence_case %>: <%= @alert.rollup_states_summary -%>
2
+ (<%= @alert.rollup_states_detail_text(:max_checks_per_state => 3) -%>)
@@ -279,7 +279,7 @@
279
279
  initialize: function(options) {
280
280
  var context = this;
281
281
 
282
- _.each(['email', 'sms', 'sms_twilio', 'sms_nexmo', 'sns', 'jabber'], function(type) {
282
+ _.each(['email', 'sms', 'slack', 'sms_twilio', 'sms_nexmo', 'sns', 'jabber'], function(type) {
283
283
  var medium = context.collection.find(function(cm) {
284
284
  return cm.get('type') == type;
285
285
  });
@@ -334,6 +334,7 @@
334
334
  template_values['labels'] = {
335
335
  'email' : 'Email',
336
336
  'sms' : 'SMS (MessageNet)',
337
+ 'slack' : 'Slack',
337
338
  'sms_twilio' : 'SMS (Twilio)',
338
339
  'sms_nexmo' : 'SMS (Nexmo)',
339
340
  'sns' : 'SMS (Amazon SNS)',
@@ -15,6 +15,7 @@ require 'flapjack/utility'
15
15
 
16
16
  require 'flapjack/gateways/email'
17
17
  require 'flapjack/gateways/sms_messagenet'
18
+ require 'flapjack/gateways/slack'
18
19
  require 'flapjack/gateways/sms_twilio'
19
20
  require 'flapjack/gateways/sms_nexmo'
20
21
  require 'flapjack/gateways/aws_sns'
@@ -23,6 +23,7 @@ require 'flapjack/gateways/oobetet'
23
23
  require 'flapjack/gateways/pagerduty'
24
24
  require 'flapjack/gateways/email'
25
25
  require 'flapjack/gateways/sms_messagenet'
26
+ require 'flapjack/gateways/slack'
26
27
  require 'flapjack/gateways/sms_twilio'
27
28
  require 'flapjack/gateways/sms_nexmo'
28
29
  require 'flapjack/gateways/aws_sns'
@@ -104,6 +105,7 @@ module Flapjack
104
105
  'oobetet' => Flapjack::Gateways::Oobetet,
105
106
  'email' => Flapjack::Gateways::Email,
106
107
  'sms' => Flapjack::Gateways::SmsMessagenet,
108
+ 'slack' => Flapjack::Gateways::Slack,
107
109
  'sms_twilio' => Flapjack::Gateways::SmsTwilio,
108
110
  'sms_nexmo' => Flapjack::Gateways::SmsNexmo,
109
111
  'sns' => Flapjack::Gateways::AwsSns}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "1.6.0rc3"
4
+ VERSION = "1.6.0rc4"
5
5
  end
@@ -22,8 +22,8 @@ describe Flapjack::Data::Contact, :redis => true do
22
22
  :tags => Set.new([]),
23
23
  :time_restrictions => [],
24
24
  :unknown_media => [],
25
- :warning_media => ['email', 'sms', 'sms_twilio', 'sms_nexmo', 'jabber', 'pagerduty', 'sns'],
26
- :critical_media => ['email', 'sms', 'sms_twilio', 'sms_nexmo', 'jabber', 'pagerduty', 'sns'],
25
+ :warning_media => ['email', 'sms', 'slack', 'sms_twilio', 'sms_nexmo', 'jabber', 'pagerduty', 'sns'],
26
+ :critical_media => ['email', 'sms', 'slack', 'sms_twilio', 'sms_nexmo', 'jabber', 'pagerduty', 'sns'],
27
27
  :unknown_blackhole => false,
28
28
  :warning_blackhole => false,
29
29
  :critical_blackhole => false}
@@ -7,9 +7,9 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
7
7
 
8
8
  let(:redis) { double('redis') }
9
9
 
10
- let(:time) { Time.new(2013, 10, 31, 13, 45) }
10
+ let(:time_int) { 1383252300 }
11
11
 
12
- let(:time_str) { Time.at(time.to_i).strftime('%Y-%m-%dT%H:%M:%SZ') }
12
+ let(:time_str) { '2013-10-31T20:45:00Z' }
13
13
 
14
14
  let(:config) { {'region' => 'us-east-1',
15
15
  'access_key' => 'AKIAIOSFODNN7EXAMPLE',
@@ -24,7 +24,7 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
24
24
  'summary' => 'smile',
25
25
  'last_state' => 'problem',
26
26
  'last_summary' => 'frown',
27
- 'time' => time.to_i,
27
+ 'time' => time_int,
28
28
  'address' => 'arn:aws:sns:us-east-1:698519295917:My-Topic',
29
29
  'event_id' => 'example.com:ping',
30
30
  'id' => '123456789',
@@ -34,13 +34,21 @@ describe Flapjack::Gateways::AwsSns, :logger => true do
34
34
  }
35
35
 
36
36
  it "sends an SMS message" do
37
+ # bad, bad, bad...
38
+ t = double('time')
39
+ ut = double('utc_time')
40
+ expect(ut).to receive(:strftime).with('%Y-%m-%dT%H:%M:%SZ').and_return(time_str)
41
+ expect(t).to receive(:utc).and_return(ut)
42
+ expect(t).to receive(:strftime).with('%-d %b %H:%M').and_return('31 Oct 20:45')
43
+ expect(Time).to receive(:at).with(time_int).twice.and_return(t)
44
+
37
45
  req = stub_request(:post, "http://sns.us-east-1.amazonaws.com/").
38
46
  with(:query => hash_including({'Action' => 'Publish',
39
47
  'AWSAccessKeyId' => config['access_key'],
40
48
  'TopicArn' => message['address'],
41
49
  'SignatureVersion' => '2',
42
50
  'SignatureMethod' => 'HmacSHA256',
43
- 'Signature' => 'gxoUQ8qUYBQbqgf3XmbiSPZ8qTJZ9WyC81EKc67FY0g=',
51
+ 'Signature' => '5fWqhmDrZQkQfP7wsxWDdQjzV0BLwm6cZNrNqZ+W/ok=',
44
52
  'Timestamp' => time_str})).
45
53
  to_return(:status => 200)
46
54
 
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'flapjack/gateways/slack'
3
+
4
+ describe Flapjack::Gateways::Slack, :logger => true do
5
+
6
+ let(:lock) { double(Monitor) }
7
+
8
+ let(:redis) { double('redis') }
9
+
10
+ let(:config) { {'account_sid' => 'flapslack',
11
+ 'endpoint' => 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
12
+ }
13
+ }
14
+
15
+ let(:time) { Time.new(2013, 10, 31, 13, 45) }
16
+
17
+ let(:time_str) { Time.at(time).strftime('%-d %b %H:%M') }
18
+
19
+ let(:message) { {'notification_type' => 'recovery',
20
+ 'contact_first_name' => 'John',
21
+ 'contact_last_name' => 'Smith',
22
+ 'state' => 'ok',
23
+ 'summary' => 'smile',
24
+ 'last_state' => 'problem',
25
+ 'last_summary' => 'frown',
26
+ 'time' => time.to_i,
27
+ 'address' => 'general',
28
+ 'event_id' => 'example.com:ping',
29
+ 'id' => '123456789',
30
+ 'duration' => 55,
31
+ 'state_duration' => 23
32
+ }
33
+ }
34
+
35
+ it "sends a Slack message" do
36
+ payload_json = Flapjack.dump_json(
37
+ 'channel' => '#general',
38
+ 'username' => 'flapslack',
39
+ 'text' => "Recovery: 'ping' on example.com is OK at #{time_str}, smile",
40
+ 'icon_emoji' => ':ghost:'
41
+ )
42
+
43
+ req = stub_request(:post, config['endpoint']).
44
+ with(:body => {'payload' => payload_json}).
45
+ to_return(:status => 200)
46
+
47
+ EM.synchrony do
48
+ expect(Flapjack::RedisPool).to receive(:new).and_return(redis)
49
+
50
+ alert = Flapjack::Data::Alert.new(message, :logger => @logger)
51
+ slack = Flapjack::Gateways::Slack.new(:config => config, :logger => @logger)
52
+ slack.deliver(alert)
53
+ EM.stop
54
+ end
55
+ expect(req).to have_been_requested
56
+ end
57
+
58
+ it "does not send a Slack message with an invalid config" do
59
+ EM.synchrony do
60
+ expect(Flapjack::RedisPool).to receive(:new).and_return(redis)
61
+
62
+ alert = Flapjack::Data::Alert.new(message, :logger => @logger)
63
+ slack = Flapjack::Gateways::Slack.new(:config => config.reject {|k, v| k == 'endpoint'}, :logger => @logger)
64
+ slack.deliver(alert)
65
+ EM.stop
66
+ end
67
+
68
+ expect(WebMock).not_to have_requested(:post, config['endpoint'])
69
+ end
70
+
71
+ 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.0rc3
4
+ version: 1.6.0rc4
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-06-15 00:00:00.000000000 Z
14
+ date: 2015-07-09 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: dante
@@ -469,6 +469,9 @@ files:
469
469
  - lib/flapjack/gateways/oobetet.rb
470
470
  - lib/flapjack/gateways/pagerduty.rb
471
471
  - lib/flapjack/gateways/pagerduty/alert.text.erb
472
+ - lib/flapjack/gateways/slack.rb
473
+ - lib/flapjack/gateways/slack/alert.text.erb
474
+ - lib/flapjack/gateways/slack/rollup.text.erb
472
475
  - lib/flapjack/gateways/sms_messagenet.rb
473
476
  - lib/flapjack/gateways/sms_messagenet/alert.text.erb
474
477
  - lib/flapjack/gateways/sms_messagenet/rollup.text.erb
@@ -576,6 +579,7 @@ files:
576
579
  - spec/lib/flapjack/gateways/jsonapi_spec.rb
577
580
  - spec/lib/flapjack/gateways/oobetet_spec.rb
578
581
  - spec/lib/flapjack/gateways/pagerduty_spec.rb
582
+ - spec/lib/flapjack/gateways/slack_spec.rb
579
583
  - spec/lib/flapjack/gateways/sms_messagenet_spec.rb
580
584
  - spec/lib/flapjack/gateways/sms_nexmo_spec.rb
581
585
  - spec/lib/flapjack/gateways/sms_twilio_spec.rb
@@ -700,6 +704,7 @@ test_files:
700
704
  - spec/lib/flapjack/gateways/jsonapi_spec.rb
701
705
  - spec/lib/flapjack/gateways/oobetet_spec.rb
702
706
  - spec/lib/flapjack/gateways/pagerduty_spec.rb
707
+ - spec/lib/flapjack/gateways/slack_spec.rb
703
708
  - spec/lib/flapjack/gateways/sms_messagenet_spec.rb
704
709
  - spec/lib/flapjack/gateways/sms_nexmo_spec.rb
705
710
  - spec/lib/flapjack/gateways/sms_twilio_spec.rb