flapjack 0.6.43 → 0.6.44

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.
Files changed (90) hide show
  1. data/bin/flapjack +4 -2
  2. data/bin/flapjack-nagios-receiver +4 -1
  3. data/bin/flapjack-populator +4 -1
  4. data/etc/flapjack_config.yaml.example +111 -106
  5. data/features/steps/notifications_steps.rb +6 -6
  6. data/lib/flapjack/configuration.rb +76 -24
  7. data/lib/flapjack/coordinator.rb +27 -44
  8. data/lib/flapjack/data/entity.rb +28 -7
  9. data/lib/flapjack/data/entity_check.rb +18 -20
  10. data/lib/flapjack/executive.rb +5 -4
  11. data/lib/flapjack/gateways/api.rb +391 -0
  12. data/lib/flapjack/gateways/api/entity_check_presenter.rb +185 -0
  13. data/lib/flapjack/gateways/api/entity_presenter.rb +70 -0
  14. data/lib/flapjack/gateways/base.rb +38 -0
  15. data/lib/flapjack/{notification → gateways}/email.rb +4 -5
  16. data/lib/flapjack/{notification → gateways}/email/alert.html.haml +0 -0
  17. data/lib/flapjack/{notification → gateways}/email/alert.text.erb +0 -0
  18. data/lib/flapjack/gateways/jabber.rb +387 -0
  19. data/lib/flapjack/gateways/oobetet.rb +241 -0
  20. data/lib/flapjack/gateways/pagerduty.rb +247 -0
  21. data/lib/flapjack/{notification → gateways}/sms.rb +5 -6
  22. data/lib/flapjack/{notification → gateways}/sms/messagenet.rb +1 -1
  23. data/lib/flapjack/gateways/web.rb +293 -0
  24. data/lib/flapjack/{web → gateways/web}/views/_css.haml +0 -0
  25. data/lib/flapjack/{web → gateways/web}/views/_nav.haml +0 -0
  26. data/lib/flapjack/{web → gateways/web}/views/check.haml +0 -0
  27. data/lib/flapjack/{web → gateways/web}/views/contact.haml +0 -0
  28. data/lib/flapjack/{web → gateways/web}/views/contacts.haml +0 -0
  29. data/lib/flapjack/{web → gateways/web}/views/index.haml +0 -0
  30. data/lib/flapjack/{web → gateways/web}/views/self_stats.haml +0 -0
  31. data/lib/flapjack/pikelet.rb +0 -23
  32. data/lib/flapjack/version.rb +1 -1
  33. data/spec/lib/flapjack/coordinator_spec.rb +56 -36
  34. data/spec/lib/flapjack/data/entity_spec.rb +53 -4
  35. data/spec/lib/flapjack/{api → gateways/api}/entity_check_presenter_spec.rb +10 -13
  36. data/spec/lib/flapjack/{api → gateways/api}/entity_presenter_spec.rb +10 -10
  37. data/spec/lib/flapjack/{api_spec.rb → gateways/api_spec.rb} +14 -14
  38. data/spec/lib/flapjack/gateways/email_spec.rb +6 -0
  39. data/spec/lib/flapjack/{jabber_spec.rb → gateways/jabber_spec.rb} +9 -9
  40. data/spec/lib/flapjack/{oobetet_spec.rb → gateways/oobetet_spec.rb} +10 -10
  41. data/spec/lib/flapjack/{pagerduty_spec.rb → gateways/pagerduty_spec.rb} +11 -11
  42. data/spec/lib/flapjack/gateways/sms_spec.rb +6 -0
  43. data/spec/lib/flapjack/{web_spec.rb → gateways/web_spec.rb} +4 -4
  44. metadata +46 -79
  45. data/bin/install-flapjack-systemwide +0 -58
  46. data/features/steps/flapjack-importer_steps.rb +0 -109
  47. data/features/steps/flapjack-worker_steps.rb +0 -68
  48. data/lib/flapjack/api.rb +0 -388
  49. data/lib/flapjack/api/entity_check_presenter.rb +0 -181
  50. data/lib/flapjack/api/entity_presenter.rb +0 -66
  51. data/lib/flapjack/cli/worker_manager.rb +0 -46
  52. data/lib/flapjack/inifile.rb +0 -44
  53. data/lib/flapjack/jabber.rb +0 -383
  54. data/lib/flapjack/notifier_engine.rb +0 -40
  55. data/lib/flapjack/notifiers/mailer/init.rb +0 -3
  56. data/lib/flapjack/notifiers/mailer/mailer.rb +0 -51
  57. data/lib/flapjack/notifiers/xmpp/init.rb +0 -3
  58. data/lib/flapjack/notifiers/xmpp/xmpp.rb +0 -46
  59. data/lib/flapjack/oobetet.rb +0 -240
  60. data/lib/flapjack/pagerduty.rb +0 -242
  61. data/lib/flapjack/web.rb +0 -286
  62. data/spec.old/check_sandbox/echo +0 -3
  63. data/spec.old/check_sandbox/sandboxed_check +0 -5
  64. data/spec.old/configs/flapjack-notifier-couchdb.ini +0 -25
  65. data/spec.old/configs/flapjack-notifier.ini +0 -39
  66. data/spec.old/configs/recipients.ini +0 -14
  67. data/spec.old/helpers.rb +0 -15
  68. data/spec.old/inifile_spec.rb +0 -66
  69. data/spec.old/mock-notifiers/mock/init.rb +0 -3
  70. data/spec.old/mock-notifiers/mock/mock.rb +0 -19
  71. data/spec.old/notifier-directories/spoons/testmailer/init.rb +0 -20
  72. data/spec.old/notifier_application_spec.rb +0 -222
  73. data/spec.old/notifier_filters_spec.rb +0 -52
  74. data/spec.old/notifier_options_multiplexer_spec.rb +0 -71
  75. data/spec.old/notifier_options_spec.rb +0 -115
  76. data/spec.old/notifier_spec.rb +0 -57
  77. data/spec.old/notifiers/mailer_spec.rb +0 -36
  78. data/spec.old/notifiers/xmpp_spec.rb +0 -36
  79. data/spec.old/persistence/datamapper_spec.rb +0 -74
  80. data/spec.old/persistence/mock_persistence_backend.rb +0 -26
  81. data/spec.old/simple.ini +0 -6
  82. data/spec.old/spec.opts +0 -4
  83. data/spec.old/test-filters/blocker.rb +0 -13
  84. data/spec.old/test-filters/mock.rb +0 -13
  85. data/spec.old/transports/beanstalkd_spec.rb +0 -44
  86. data/spec.old/transports/mock_transport.rb +0 -58
  87. data/spec.old/worker_application_spec.rb +0 -62
  88. data/spec.old/worker_options_spec.rb +0 -83
  89. data/spec/lib/flapjack/notification/email_spec.rb +0 -6
  90. data/spec/lib/flapjack/notification/sms_spec.rb +0 -6
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'socket'
4
+ require 'eventmachine'
5
+ require 'em-synchrony'
6
+ require 'blather/client/client'
7
+ require 'em-synchrony/fiber_iterator'
8
+ require 'yajl/json_gem'
9
+
10
+ require 'flapjack/utility'
11
+ require 'flapjack/gateways/base'
12
+
13
+ module Flapjack
14
+
15
+ module Gateways
16
+
17
+ class Oobetet < Blather::Client
18
+
19
+ include Flapjack::Gateways::Generic
20
+ include Flapjack::Utility
21
+
22
+ log = Logger.new(STDOUT)
23
+ # log.level = Logger::DEBUG
24
+ log.level = Logger::INFO
25
+ Blather.logger = log
26
+
27
+ def setup
28
+ @hostname = Socket.gethostname
29
+ @flapjacktest_jid = Blather::JID.new((@config['jabberid'] || 'flapjacktest') + "/#{@hostname}:#{Process.pid}")
30
+
31
+ super(@flapjacktest_jid, @config['password'], @config['server'], @config['port'].to_i)
32
+
33
+ logger.debug("Building jabber connection with jabberid: " +
34
+ @flapjacktest_jid.to_s + ", port: " + @config['port'].to_s +
35
+ ", server: " + @config['server'].to_s + ", password: " +
36
+ @config['password'].to_s)
37
+
38
+ @pagerduty_events_api_url = 'https://events.pagerduty.com/generic/2010-04-15/create_event.json'
39
+
40
+ if !@config['watched_check'] or !@config['watched_entity']
41
+ raise RuntimeError, 'Flapjack::Oobetet: watched_check and watched_entity must be defined in the config'
42
+ end
43
+
44
+ @check_matcher = '"' + @config['watched_check'] + '" on ' + @config['watched_entity']
45
+ @max_latency = @config['max_latency'] || 300
46
+ @flapjack_ok = true
47
+
48
+ t = Time.now.to_i
49
+ @times = { :last_problem => t,
50
+ :last_recovery => t,
51
+ :last_ack => t,
52
+ :last_ack_sent => t }
53
+
54
+ @last_alert = nil
55
+ end
56
+
57
+ # split out to ease testing
58
+ def register_handlers
59
+ register_handler :ready do |stanza|
60
+ EventMachine::Synchrony.next_tick do
61
+ on_ready(stanza)
62
+ end
63
+ end
64
+
65
+ register_handler :message, :groupchat? do |stanza|
66
+ EventMachine::Synchrony.next_tick do
67
+ on_groupchat(stanza)
68
+ end
69
+ end
70
+
71
+ register_handler :disconnected do |stanza|
72
+ ret = true
73
+ EventMachine::Synchrony.next_tick do
74
+ ret = on_disconnect(stanza)
75
+ end
76
+ ret
77
+ end
78
+ end
79
+
80
+
81
+ # Join the MUC Chat room after connecting.
82
+ def on_ready(stanza)
83
+ return if should_quit?
84
+ @connected_at = Time.now.to_i
85
+ logger.info("Jabber Connected")
86
+ if @config['rooms'] && @config['rooms'].length > 0
87
+ @config['rooms'].each do |room|
88
+ logger.info("Joining room #{room}")
89
+ presence = Blather::Stanza::Presence.new
90
+ presence.from = @flapjacktest_jid
91
+ presence.to = Blather::JID.new("#{room}/#{@config['alias']}")
92
+ presence << "<x xmlns='http://jabber.org/protocol/muc'/>"
93
+ write presence
94
+ say(room, "flapjack self monitoring (oobetet) started at #{Time.now}, g'day!", :groupchat)
95
+ end
96
+ end
97
+ end
98
+
99
+ # returning true to prevent the reactor loop from stopping
100
+ def on_disconnect(stanza)
101
+ return true if should_quit?
102
+ logger.warn("jabbers disconnected! reconnecting in 1 second ...")
103
+ EventMachine::Timer.new(1) do
104
+ connect # Blather::Client.connect
105
+ end
106
+ true
107
+ end
108
+
109
+ def on_groupchat(stanza)
110
+ return if should_quit?
111
+
112
+ stanza_body = stanza.body
113
+
114
+ logger.debug("groupchat stanza body: " + stanza_body)
115
+ logger.debug("groupchat message received: #{stanza.inspect}")
116
+
117
+ if (stanza_body =~ /^(?:problem|recovery|acknowledgement)/i) &&
118
+ (stanza_body =~ /^(\w+).*#{Regexp.escape(@check_matcher)}/)
119
+
120
+ # got something interesting
121
+ status = $1.downcase
122
+ t = Time.now.to_i
123
+ logger.debug("groupchat found the following state for #{@check_matcher}: #{status}")
124
+
125
+ case status
126
+ when 'problem'
127
+ logger.debug("updating @times last_problem")
128
+ @times[:last_problem] = t
129
+ when 'recovery'
130
+ logger.debug("updating @times last_recovery")
131
+ @times[:last_recovery] = t
132
+ when 'acknowledgement'
133
+ logger.debug("updating @times last_ack")
134
+ @times[:last_ack] = t
135
+ end
136
+ end
137
+ logger.debug("@times: #{@times.inspect}")
138
+ end
139
+
140
+ def check_timers
141
+ t = Time.now.to_i
142
+ breach = nil
143
+ @logger.debug("check_timers: inspecting @times #{@times.inspect}")
144
+ case
145
+ when @times[:last_problem] < (t - @max_latency)
146
+ breach = "haven't seen a test problem notification in the last #{@max_latency} seconds"
147
+ when @times[:last_recovery] < (t - @max_latency)
148
+ breach = "haven't seen a test recovery notification in the last #{@max_latency} seconds"
149
+ end
150
+
151
+ unless @flapjack_ok || breach
152
+ emit_jabber("Flapjack Self Monitoring is OK")
153
+ emit_pagerduty("Flapjack Self Monitoring is OK", 'resolve')
154
+ end
155
+
156
+ @flapjack_ok = !breach
157
+
158
+ return unless breach
159
+ @logger.error("Self monitoring has detected the following breach: #{breach}")
160
+ summary = "Flapjack Self Monitoring is Critical: #{breach} for #{@check_matcher}, "
161
+ summary += "from #{@hostname} at #{Time.now}"
162
+
163
+ if !@last_alert or @last_alert < (t - 55)
164
+
165
+ emit_jabber(summary)
166
+ emit_pagerduty(summary, 'trigger')
167
+
168
+ if !@last_alert or @last_alert < (t - 55)
169
+ msg = "NOTICE: Self monitoring has detected a failure and is unable to tell "
170
+ msg += "anyone about it. DON'T PANIC."
171
+ @logger.error msg
172
+ end
173
+
174
+ end
175
+ end
176
+
177
+ def emit_jabber(summary)
178
+ if @config['rooms'] && @config['rooms'].length > 0
179
+ @config['rooms'].each do |room|
180
+ say(room, summary, :groupchat)
181
+ end
182
+ @last_alert = Time.now.to_i
183
+ end
184
+ end
185
+
186
+ def emit_pagerduty(summary, event_type = 'trigger')
187
+ if @config['pagerduty_contact']
188
+ pagerduty_event = { :service_key => @config['pagerduty_contact'],
189
+ :incident_key => "Flapjack Self Monitoring from #{@hostname}",
190
+ :event_type => event_type,
191
+ :description => summary }
192
+ status, response = send_pagerduty_event(pagerduty_event)
193
+ if status == 200
194
+ @logger.debug("successfully sent pagerduty event")
195
+ @last_alert = Time.now.to_i
196
+ else
197
+ @logger.error("pagerduty returned #{status} #{response.inspect}")
198
+ end
199
+ end
200
+ end
201
+
202
+ def say(to, msg, using = :chat)
203
+ @logger.debug("Sending a jabber message to: #{to.to_s}, using: #{using.to_s}, message: #{msg}")
204
+ write Blather::Stanza::Message.new(to, msg, using)
205
+ end
206
+
207
+ def send_pagerduty_event(event)
208
+ options = { :body => Yajl::Encoder.encode(event) }
209
+ http = EM::HttpRequest.new(@pagerduty_events_api_url).post(options)
210
+ response = Yajl::Parser.parse(http.response)
211
+ status = http.response_header.status
212
+ logger.debug "send_pagerduty_event got a return code of #{status.to_s} - #{response.inspect}"
213
+ [status, response]
214
+ end
215
+
216
+ def main
217
+ logger.debug("New oobetet pikelet with the following options: #{@config.inspect}")
218
+
219
+ keepalive_timer = EM::Synchrony.add_periodic_timer(60) do
220
+ logger.debug("calling keepalive on the jabber connection")
221
+ write(' ') if connected?
222
+ end
223
+
224
+ setup
225
+ register_handlers
226
+ connect # Blather::Client.connect
227
+
228
+ until should_quit?
229
+ EM::Synchrony.sleep(10)
230
+ check_timers
231
+ end
232
+
233
+ keepalive_timer.cancel
234
+ end
235
+
236
+ end
237
+ end
238
+ end
239
+
240
+
241
+
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'em-synchrony'
4
+ require 'em-synchrony/em-http'
5
+
6
+ require 'yajl/json_gem'
7
+
8
+ require 'flapjack/data/entity_check'
9
+ require 'flapjack/data/global'
10
+ require 'flapjack/redis_pool'
11
+
12
+ require 'flapjack/gateways/base'
13
+
14
+ module Flapjack
15
+
16
+ module Gateways
17
+
18
+ class Pagerduty
19
+ include Flapjack::Gateways::Generic
20
+
21
+ PAGERDUTY_EVENTS_API_URL = 'https://events.pagerduty.com/generic/2010-04-15/create_event.json'
22
+ SEM_PAGERDUTY_ACKS_RUNNING = 'sem_pagerduty_acks_running'
23
+
24
+ alias_method :generic_bootstrap, :bootstrap
25
+ alias_method :generic_cleanup, :cleanup
26
+
27
+ def bootstrap(opts = {})
28
+ generic_bootstrap(opts)
29
+
30
+ @redis_config = opts[:redis_config]
31
+ @redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 1)
32
+
33
+ logger.debug("New Pagerduty pikelet with the following options: #{@config.inspect}")
34
+
35
+ @pagerduty_acks_started = nil
36
+ end
37
+
38
+ def cleanup
39
+ @redis.empty! if @redis
40
+ @redis_timer.empty! if @redis_timer
41
+ generic_cleanup
42
+ end
43
+
44
+ def add_shutdown_event(opts = {})
45
+ return unless redis = opts[:redis]
46
+ redis.rpush(@config['queue'], JSON.generate('notification_type' => 'shutdown'))
47
+ end
48
+
49
+ def main
50
+ logger.debug("pagerduty gateway - commencing main method")
51
+ raise "Can't connect to the pagerduty API" unless test_pagerduty_connection
52
+
53
+ # TODO: only clear this if there isn't another pagerduty gateway instance running
54
+ # or better, include an instance ID in the semaphore key name
55
+ @redis.del(SEM_PAGERDUTY_ACKS_RUNNING)
56
+
57
+ acknowledgement_timer = EM::Synchrony.add_periodic_timer(10) do
58
+ @redis_timer ||= Flapjack::RedisPool.new(:config => @redis_config, :size => 1)
59
+ find_pagerduty_acknowledgements_if_safe
60
+ end
61
+
62
+ queue = @config['queue']
63
+ events = {}
64
+
65
+ until should_quit?
66
+ logger.debug("pagerduty gateway is going into blpop mode on #{queue}")
67
+ events[queue] = @redis.blpop(queue, 0)
68
+ event = Yajl::Parser.parse(events[queue][1])
69
+ type = event['notification_type']
70
+ logger.debug("pagerduty notification event popped off the queue: " + event.inspect)
71
+ unless 'shutdown'.eql?(type)
72
+ event_id = event['event_id']
73
+ entity, check = event_id.split(':')
74
+ state = event['state']
75
+ summary = event['summary']
76
+ address = event['address']
77
+
78
+ headline = type.upcase
79
+
80
+ case type.downcase
81
+ when 'acknowledgement'
82
+ maint_str = "has been acknowledged"
83
+ pagerduty_type = 'acknowledge'
84
+ when 'problem'
85
+ maint_str = "is #{state.upcase}"
86
+ pagerduty_type = "trigger"
87
+ when 'recovery'
88
+ maint_str = "is #{state.upcase}"
89
+ pagerduty_type = "resolve"
90
+ when 'test'
91
+ maint_str = ""
92
+ pagerduty_type = "trigger"
93
+ headline = "TEST NOTIFICATION"
94
+ end
95
+
96
+ message = "#{type.upcase} - \"#{check}\" on #{entity} #{maint_str} - #{summary}"
97
+
98
+ pagerduty_event = { :service_key => address,
99
+ :incident_key => event_id,
100
+ :event_type => pagerduty_type,
101
+ :description => message }
102
+
103
+ send_pagerduty_event(pagerduty_event)
104
+ end
105
+ end
106
+
107
+ acknowledgement_timer.cancel
108
+ end
109
+
110
+ # considering this as part of the public API -- exposes it for testing.
111
+ def find_pagerduty_acknowledgements_if_safe
112
+
113
+ # ensure we're the only instance of the pagerduty acknowledgement check running (with a naive
114
+ # timeout of five minutes to guard against stale locks caused by crashing code) either in this
115
+ # process or in other processes
116
+ if (@pagerduty_acks_started and @pagerduty_acks_started > (Time.now.to_i - 300)) or
117
+ @redis_timer.get(SEM_PAGERDUTY_ACKS_RUNNING) == 'true'
118
+ logger.debug("skipping looking for acks in pagerduty as this is already happening")
119
+ return
120
+ end
121
+
122
+ @pagerduty_acks_started = Time.now.to_i
123
+ @redis_timer.set(SEM_PAGERDUTY_ACKS_RUNNING, 'true')
124
+ @redis_timer.expire(SEM_PAGERDUTY_ACKS_RUNNING, 300)
125
+
126
+ find_pagerduty_acknowledgements
127
+
128
+ @redis_timer.del(SEM_PAGERDUTY_ACKS_RUNNING)
129
+ @pagerduty_acks_started = nil
130
+ end
131
+
132
+ private
133
+
134
+ def test_pagerduty_connection
135
+ noop = { "service_key" => "11111111111111111111111111111111",
136
+ "incident_key" => "Flapjack is running a NOOP",
137
+ "event_type" => "nop",
138
+ "description" => "I love APIs with noops." }
139
+ code, results = send_pagerduty_event(noop)
140
+ return true if code == 200 && results['status'] =~ /success/i
141
+ logger.error "Error: test_pagerduty_connection: API returned #{code.to_s} #{results.inspect}"
142
+ false
143
+ end
144
+
145
+ def send_pagerduty_event(event)
146
+ options = { :body => Yajl::Encoder.encode(event) }
147
+ http = EM::HttpRequest.new(PAGERDUTY_EVENTS_API_URL).post(options)
148
+ response = Yajl::Parser.parse(http.response)
149
+ status = http.response_header.status
150
+ logger.debug "send_pagerduty_event got a return code of #{status.to_s} - #{response.inspect}"
151
+ [status, response]
152
+ end
153
+
154
+ def find_pagerduty_acknowledgements
155
+
156
+ logger.debug("looking for acks in pagerduty for unack'd problems")
157
+
158
+ unacknowledged_failing_checks = Flapjack::Data::Global.unacknowledged_failing_checks(:redis => @redis_timer)
159
+
160
+ @logger.debug "found unacknowledged failing checks as follows: " + unacknowledged_failing_checks.join(', ')
161
+
162
+ unacknowledged_failing_checks.each do |entity_check|
163
+ pagerduty_credentials = entity_check.pagerduty_credentials(:redis => @redis_timer)
164
+ check = entity_check.check
165
+
166
+ if pagerduty_credentials.empty?
167
+ @logger.debug("No pagerduty credentials found for #{entity_check.entity_name}:#{check}, skipping")
168
+ next
169
+ end
170
+
171
+ # FIXME: try each set of credentials until one works (may have stale contacts turning up)
172
+ options = pagerduty_credentials.first.merge('check' => check)
173
+
174
+ acknowledged = pagerduty_acknowledged?(options)
175
+ if acknowledged.nil?
176
+ @logger.debug "#{check} is not acknowledged in pagerduty, skipping"
177
+ next
178
+ end
179
+
180
+ pg_acknowledged_by = acknowledged[:pg_acknowledged_by]
181
+ @logger.debug "#{check} is acknowledged in pagerduty, creating flapjack acknowledgement... "
182
+ who_text = ""
183
+ if !pg_acknowledged_by.nil? && !pg_acknowledged_by['name'].nil?
184
+ who_text = " by #{pg_acknowledged_by['name']}"
185
+ end
186
+ entity_check.create_acknowledgement('summary' => "Acknowledged on PagerDuty" + who_text)
187
+ end
188
+
189
+ end
190
+
191
+ def pagerduty_acknowledged?(opts)
192
+ subdomain = opts['subdomain']
193
+ username = opts['username']
194
+ password = opts['password']
195
+ check = opts['check']
196
+
197
+ t = Time.now.utc
198
+
199
+ url = 'https://' + subdomain + '.pagerduty.com/api/v1/incidents'
200
+ query = { 'fields' => 'incident_number,status,last_status_change_by',
201
+ 'since' => (t - (60*60*24*7)).iso8601, # the last week
202
+ 'until' => (t + (60*60*24)).iso8601, # 1 day in the future
203
+ 'incident_key' => check,
204
+ 'status' => 'acknowledged' }
205
+
206
+ options = { :head => { 'authorization' => [username, password] },
207
+ :query => query }
208
+
209
+ http = EM::HttpRequest.new(url).get(options)
210
+ # DEBUG flapjack-pagerduty: pagerduty_acknowledged?: decoded response as:
211
+ # {"incidents"=>[{"incident_number"=>40, "status"=>"acknowledged",
212
+ # "last_status_change_by"=>{"id"=>"PO1NWPS", "name"=>"Jesse Reynolds",
213
+ # "email"=>"jesse@bulletproof.net",
214
+ # "html_url"=>"http://bltprf.pagerduty.com/users/PO1NWPS"}}], "limit"=>100, "offset"=>0,
215
+ # "total"=>1}
216
+ begin
217
+ response = Yajl::Parser.parse(http.response)
218
+ rescue Yajl::ParseError
219
+ @logger.error("failed to parse json from a post to #{url} ... response headers and body follows...")
220
+ @logger.error(http.response_header.inspect)
221
+ @logger.error(http.response)
222
+ return nil
223
+ end
224
+ status = http.response_header.status
225
+
226
+ @logger.debug("pagerduty_acknowledged?: decoded response as: #{response.inspect}")
227
+ if response.nil?
228
+ @logger.error('no valid response received from pagerduty!')
229
+ return nil
230
+ end
231
+
232
+ if response['incidents'].nil?
233
+ @logger.error('no incidents found in response')
234
+ return nil
235
+ end
236
+
237
+ return nil if response['incidents'].empty?
238
+
239
+ {:pg_acknowledged_by => response['incidents'].first['last_status_change_by']}
240
+ end
241
+
242
+ end
243
+
244
+ end
245
+
246
+ end
247
+