Skip to content
This repository has been archived by the owner on Dec 8, 2023. It is now read-only.

Add pagerduty events v2 API support #169

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions services/pagerduty_v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# encoding: utf-8
require 'time'

module Librato::Services
class Service::PagerdutyV2 < Librato::Services::Service

EVENTS_API_URL = "https://events.pagerduty.com/v2/enqueue"
CONTENT_TYPE = { 'Content-Type': 'application/json' }

ERROR_MSG = {
routing_key: "The 32 character Integration Key (required).",
description: "A description for this integration (require),",
severity: "Perceived status of event [critical, error, warning or info] (required.)"
}

def receive_validate(errors)
success = true
[:routing_key, :description, :severity].each do |k|
if settings[k].to_s.empty?
errors[k] = ERROR_MSG[k]
success = false
end
end
success
end

def receive_alert_clear
receive_alert
end

def receive_alert
raise_config_error unless receive_validate({})

if payload[:alert][:version] == 2
http_post EVENTS_API_URL, body, CONTENT_TYPE
else
log("Only v2 Alerts are support")
return true
end
end

def body
payload = {
summary: summary,
source: source,
severity: severity,
timestamp: timestamp,
class: event_class,
custom_details: details,
}

payload[:group] = group unless group.blank?

{
routing_key: routing_key,
event_action: event_action,
dedup_key: dedup_key,
payload: payload,
links: links,
}
end

def routing_key
settings[:routing_key]
end

def event_action
payload[:clear] ? "resolve" : "trigger"
end

def dedup_key
keys = [settings[:incident_key], payload[:incident_key]].compact
keys.join("-")
end

def alert_name
payload[:alert][:name]
end

def summary
summary = alert_name.blank? ? settings[:description] : alert_name
if payload[:triggered_by_user_test]
description = "[Test] " + description
end
summary
end

def source
sources = []
payload[:violations].each do |source, _|
sources << source
end
sources.join(":")
end

def event_class
classes = []
payload[:violations].each do |_, measurements|
measurements.each do |m|
classes << m[:metric]
end
end
classes.join(":")
end

def severity
settings[:severity]
end

def timestamp
Time.at(payload['trigger_time']).iso8601
end

def group
settings[:group]
end

def details
details = {
}

[:alert, :conditions, :violations].each do |whitelisted|
details[whitelisted] = payload[whitelisted]
end

if payload[:triggered_by_user_test]
details[:note] = test_alert_message()
end

unless payload['alert']['description'].blank?
details[:description] = payload['alert']['description']
end

details
end

def links
links = [
{
href: alert_link(payload['alert']['id']),
text: "Alert URL",
},
]

unless payload['alert']['runbook_url'].blank?
links << {
href: payload['alert']['runbook_url'],
text: "Runbook URL",
}
end

if payload[:alert][:version] == 1
links << {
href: payload_link(payload),
text: "Metric URL",
}
end

links
end

def log(msg)
if defined?(Rails)
Rails.logger.info(msg)
else
puts(msg)
end
end
end
end
126 changes: 126 additions & 0 deletions test/pagerduty_v2_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
require File.expand_path('../helper', __FILE__)

module Librato::Services
class PagerdutyV2Test < Librato::Services::TestCase
def setup
@stubs = Faraday::Adapter::Test::Stubs.new
end

def test_validations
params = {
routing_key: 'k',
description: 'd',
severity: 's',
}

0.upto(params.keys.length - 1) do |i|
opts = {}
0.upto(i) do |j|
opts[params.keys[j]] = params[params.keys[j]]
end
svc = service(:alert, opts, alert_payload)
errors = {}
ret = svc.receive_validate(errors)
success = i == params.keys.length - 1
assert_equal(success, ret, "opts not complete: #{opts}")
assert_equal(0, errors.length) if success
end
end

def test_new_alerts
svc = service(:alert, {
routing_key: 'k',
description: 'Some alert name',
severity: 'test',
group: 'testing',
incident_key: 'globalkey'
}, new_alert_payload)

@stubs.post svc.class::EVENTS_API_URL do |env|
body = env[:body]
assert_not_nil body

assert_equal 'k', body[:routing_key]
assert_equal 'trigger', body[:event_action]
assert_equal 'globalkey-foo', body[:dedup_key]

payload = body[:payload]
assert_not_nil payload

assert_equal 'Some alert name', payload[:summary]
assert_equal 'foo.bar', payload[:source]
assert_equal 'test', payload[:severity]
assert_equal 12321123, payload[:timestamp]
assert_equal 'testing', payload[:group]
assert_equal 'metric.name', payload[:class]

custom_details = payload[:custom_details]
assert_not_nil custom_details

assert_not_nil custom_details[:alert]
assert_not_nil custom_details[:conditions]
assert_not_nil custom_details[:violations]

links = body[:links]
assert_not_nil links
assert_equal 'https://metrics.librato.com/alerts/123', links[0][:href]
assert_equal 'Alert URL', links[0][:text]
assert_equal 'http://runbooks.com/howtodoit', links[1][:href]
assert_equal 'Runbook URL', links[1][:text]

[200, {}, '']
end

svc.receive_alert
end

def test_new_alerts_clearing
payload = new_alert_payload.dup
payload[:clear] = "manual"
svc = service(:alert, {
routing_key: 'k',
description: 'Some alert name',
severity: 'test'
}, payload)

@stubs.post svc.class::EVENTS_API_URL do |env|
body = env[:body]
assert_not_nil body

assert_equal 'k', body[:routing_key]
assert_equal 'resolve', body[:event_action]
assert_equal 'foo', body[:dedup_key]

payload = body[:payload]
assert_not_nil payload

assert_equal 'Some alert name', payload[:summary]
assert_equal 'foo.bar', payload[:source]
assert_equal 'test', payload[:severity]
assert_equal 12321123, payload[:timestamp]
assert_equal 'metric.name', payload[:class]

custom_details = payload[:custom_details]
assert_not_nil custom_details

assert_not_nil custom_details[:alert]
assert_not_nil custom_details[:conditions]
assert_not_nil custom_details[:violations]

links = body[:links]
assert_not_nil links
assert_equal 'https://metrics.librato.com/alerts/123', links[0][:href]
assert_equal 'Alert URL', links[0][:text]
assert_equal 'http://runbooks.com/howtodoit', links[1][:href]
assert_equal 'Runbook URL', links[1][:text]
[200, {}, '']
end

svc.receive_alert
end

def service(*args)
super Librato::Services::Service::PagerdutyV2, *args
end
end
end