Add Pagerduty integration for Sensu
diff --git a/sensu/files/handlers/pagerduty.json b/sensu/files/handlers/pagerduty.json
new file mode 100644
index 0000000..3a0be25
--- /dev/null
+++ b/sensu/files/handlers/pagerduty.json
@@ -0,0 +1,27 @@
+{%- set handler = pillar.sensu.server.handler[handler_name] %}
+{%- if handler_setting == "handler" %}
+{
+ "handlers": {
+ "pagerduty": {
+ "type": "pipe",
+ {%- if handler.mutator is defined %}
+ "mutator": "{{ handler.mutator }}",
+ {%- endif %}
+ "command": "/etc/sensu/handlers/handler-pagerduty.rb",
+ "severities": [
+ "ok",
+ "critical",
+ "warning",
+ "unknown"
+ ]
+ }
+ }
+}
+{%- endif %}
+{%- if handler_setting == "config" %}
+{
+ "pagerduty": {
+ "api_key": "{{ handler.api_key }}"
+ }
+}
+{%- endif %}
\ No newline at end of file
diff --git a/sensu/files/plugins/handlers/notification/pagerduty.rb b/sensu/files/plugins/handlers/notification/pagerduty.rb
new file mode 100644
index 0000000..0c3d46e
--- /dev/null
+++ b/sensu/files/plugins/handlers/notification/pagerduty.rb
@@ -0,0 +1,112 @@
+#!/usr/bin/env ruby
+#
+# This handler creates and resolves PagerDuty incidents, refreshing
+# stale incident details every 30 minutes
+#
+# Copyright 2011 Sonian, Inc <chefs@sonian.net>
+#
+# Released under the same terms as Sensu (the MIT license); see LICENSE
+# for details.
+#
+# Note: The sensu api token could also be configured on a per client or per check basis.
+# By defining the "pager_team" attribute in the client config file or the check config.
+# The override order will be client > check > json_config
+#
+# Dependencies:
+#
+# sensu-plugin >= 1.0.0
+#
+
+require 'sensu-handler'
+require 'pagerduty'
+
+#
+# Pagerduty
+#
+class PagerdutyHandler < Sensu::Handler
+ option :json_config,
+ description: 'Config Name',
+ short: '-j JsonConfig',
+ long: '--json_config JsonConfig',
+ required: false,
+ default: 'pagerduty'
+
+ def incident_key
+ source = @event['check']['source'] || @event['client']['name']
+ incident_id = [source, @event['check']['name']].join('/')
+ dedup_rules = settings[json_config]['dedup_rules'] || {}
+ dedup_rules.each do |key, val|
+ incident_id = incident_id.gsub(Regexp.new(key), val)
+ end
+ incident_id
+ end
+
+ def json_config
+ @json_config ||= config[:json_config]
+ end
+
+ def api_key
+ @api_key ||=
+ if @event['client']['pager_team']
+ settings[json_config][@event['client']['pager_team']]['api_key']
+ elsif @event['check']['pager_team']
+ settings[json_config][@event['check']['pager_team']]['api_key']
+ else
+ settings[json_config]['api_key']
+ end
+ end
+
+ def proxy_settings
+ proxy_settings = {}
+
+ proxy_settings['proxy_host'] = settings[json_config]['proxy_host'] || nil
+ proxy_settings['proxy_port'] = settings[json_config]['proxy_port'] || 3128
+ proxy_settings['proxy_username'] = settings[json_config]['proxy_username'] || ''
+ proxy_settings['proxy_password'] = settings[json_config]['proxy_password'] || ''
+
+ proxy_settings
+ end
+
+ def contexts
+ @contexts ||= @event['check']['pagerduty_contexts'] || []
+ end
+
+ def handle(pd_client = nil)
+ incident_key_prefix = settings[json_config]['incident_key_prefix']
+ description_prefix = settings[json_config]['description_prefix']
+ proxy_settings = proxy_settings()
+ begin
+ timeout(5) do
+ if proxy_settings['proxy_host']
+ pagerduty = pd_client || Pagerduty.new(api_key,
+ proxy_host: proxy_settings['proxy_host'],
+ proxy_port: proxy_settings['proxy_port'],
+ proxy_username: proxy_settings['proxy_username'],
+ proxy_password: proxy_settings['proxy_password'])
+ else
+ pagerduty = pd_client || Pagerduty.new(api_key)
+ end
+
+ begin
+ case @event['action']
+ when 'create'
+ pagerduty.trigger([description_prefix, event_summary].compact.join(' '),
+ incident_key: [incident_key_prefix, incident_key].compact.join(''),
+ details: @event,
+ contexts: contexts)
+ when 'resolve'
+ pagerduty.get_incident([incident_key_prefix, incident_key].compact.join('')).resolve(
+ [description_prefix, event_summary].compact.join(' '), @event
+ )
+ end
+ puts 'pagerduty -- ' + @event['action'].capitalize + 'd incident -- ' + incident_key
+ rescue Net::HTTPServerException => error
+ puts 'pagerduty -- failed to ' + @event['action'] + ' incident -- ' + incident_key + ' -- ' +
+ error.response.code + ' ' + error.response.message + ': ' + error.response.body
+ end
+ end
+ rescue Timeout::Error
+ puts 'pagerduty -- timed out while attempting to ' + @event['action'] + ' a incident -- ' + incident_key
+ end
+ end
+end
diff --git a/sensu/server.sls b/sensu/server.sls
index 237a6ca..1cb6b53 100644
--- a/sensu/server.sls
+++ b/sensu/server.sls
@@ -86,7 +86,7 @@
{%- for handler_name, handler in server.get('handler', {}).iteritems() %}
-{%- if handler_name in ['default', 'flapjack', 'mail', 'sccd', 'stdout', 'statsd', 'slack', 'pipe', 'sfdc'] %}
+{%- if handler_name in ['default', 'flapjack', 'mail', 'sccd', 'stdout', 'statsd', 'slack', 'pipe', 'sfdc', 'pagerduty'] %}
{%- include "sensu/server/_handler_"+handler_name+".sls" %}
diff --git a/sensu/server/_handler_pagerduty.sls b/sensu/server/_handler_pagerduty.sls
new file mode 100644
index 0000000..700bfde
--- /dev/null
+++ b/sensu/server/_handler_pagerduty.sls
@@ -0,0 +1,42 @@
+
+gem_sensu_pagerduty:
+ gem.installed:
+ - name: pagerduty
+ - gem_bin: /opt/sensu/embedded/bin/gem
+
+/etc/sensu/conf.d/pagerduty.json:
+ file.managed:
+ - source: salt://sensu/files/handlers/pagerduty.json
+ - template: jinja
+ - defaults:
+ handler_name: "{{ handler_name }}"
+ handler_setting: "config"
+ - watch_in:
+ - service: service_sensu_server
+ - service: service_sensu_api
+ - require_in:
+ - file: sensu_conf_dir_clean
+
+/etc/sensu/conf.d/handler_pagerduty.json:
+ file.managed:
+ - source: salt://sensu/files/handlers/pagerduty.json
+ - template: jinja
+ - defaults:
+ handler_name: "{{ handler_name }}"
+ handler_setting: "handler"
+ - watch_in:
+ - service: service_sensu_server
+ - service: service_sensu_api
+ - require_in:
+ - file: sensu_conf_dir_clean
+
+/etc/sensu/handlers/pagerduty.rb:
+ file.managed:
+ - source: salt://sensu/files/plugins/handlers/notification/pagerduty.rb
+ - mode: 700
+ - user: sensu
+ - watch_in:
+ - service: service_sensu_server
+ - service: service_sensu_api
+ - require:
+ - gem_sensu_pagerduty
\ No newline at end of file
diff --git a/tests/pillar/sensu_server.sls b/tests/pillar/sensu_server.sls
index 80431c9..d050bd9 100644
--- a/tests/pillar/sensu_server.sls
+++ b/tests/pillar/sensu_server.sls
@@ -2,7 +2,7 @@
server:
enabled: true
keepalive_warning: 20
- keepalive_critical: 60
+ keepalive_critical: 60
mine_checks: true
database:
engine: redis
@@ -24,6 +24,7 @@
set:
- mail
- pipe
+ - pagerduty
stdout:
enabled: true
pipe:
@@ -38,6 +39,8 @@
authentication: cram_md5
encryption: ssl
domain: 'domain.cz'
+ pagerduty:
+ api_key: 'insert-your-key-here'
client:
enabled: false