112 lines
3 KiB
Elixir
112 lines
3 KiB
Elixir
defmodule Towerops.PagerDuty.Client do
|
|
@moduledoc "PagerDuty Events API v2 client."
|
|
|
|
require Logger
|
|
|
|
@events_url "https://events.pagerduty.com/v2/enqueue"
|
|
|
|
def trigger(routing_key, alert, device, site_name, towerops_url) do
|
|
send_event(%{
|
|
routing_key: routing_key,
|
|
event_action: "trigger",
|
|
dedup_key: dedup_key(alert),
|
|
payload: %{
|
|
summary: alert_summary(alert, device),
|
|
source: "towerops",
|
|
severity: severity(alert.alert_type),
|
|
timestamp: DateTime.to_iso8601(alert.triggered_at),
|
|
component: device.hostname || device.ip_address,
|
|
group: site_name,
|
|
class: to_string(alert.alert_type),
|
|
custom_details: %{
|
|
device_id: device.id,
|
|
device_name: device.hostname || device.ip_address,
|
|
ip_address: device.ip_address,
|
|
site_name: site_name,
|
|
alert_type: to_string(alert.alert_type),
|
|
message: alert.message,
|
|
towerops_url: towerops_url
|
|
}
|
|
},
|
|
links: [%{href: towerops_url, text: "View in TowerOps"}]
|
|
})
|
|
end
|
|
|
|
def acknowledge(routing_key, alert) do
|
|
send_event(%{
|
|
routing_key: routing_key,
|
|
event_action: "acknowledge",
|
|
dedup_key: dedup_key(alert)
|
|
})
|
|
end
|
|
|
|
def resolve(routing_key, alert) do
|
|
send_event(%{
|
|
routing_key: routing_key,
|
|
event_action: "resolve",
|
|
dedup_key: dedup_key(alert)
|
|
})
|
|
end
|
|
|
|
def test_connection(routing_key) do
|
|
test_dedup = "towerops-test-#{System.unique_integer([:positive])}"
|
|
|
|
case send_event(%{
|
|
routing_key: routing_key,
|
|
event_action: "trigger",
|
|
dedup_key: test_dedup,
|
|
payload: %{
|
|
summary: "TowerOps integration test",
|
|
source: "towerops",
|
|
severity: "info",
|
|
timestamp: DateTime.to_iso8601(DateTime.utc_now())
|
|
}
|
|
}) do
|
|
{:ok, _} ->
|
|
send_event(%{
|
|
routing_key: routing_key,
|
|
event_action: "resolve",
|
|
dedup_key: test_dedup
|
|
})
|
|
|
|
error ->
|
|
error
|
|
end
|
|
end
|
|
|
|
defp send_event(body) do
|
|
case Req.post(@events_url, json: body) do
|
|
{:ok, %{status: status, body: resp_body}} when status in [200, 202] ->
|
|
{:ok, resp_body}
|
|
|
|
{:ok, %{status: 400, body: resp_body}} ->
|
|
{:error, {:bad_request, resp_body["message"] || "Invalid event"}}
|
|
|
|
{:ok, %{status: 429}} ->
|
|
{:error, :rate_limited}
|
|
|
|
{:ok, %{status: status}} ->
|
|
{:error, {:unexpected_status, status}}
|
|
|
|
{:error, error} ->
|
|
Logger.warning("PagerDuty API error: #{inspect(error)}")
|
|
{:error, error}
|
|
end
|
|
end
|
|
|
|
defp dedup_key(alert), do: "towerops-alert-#{alert.id}"
|
|
|
|
defp alert_summary(alert, device) do
|
|
name = device.hostname || device.ip_address
|
|
|
|
case alert.alert_type do
|
|
:device_down -> "Device down: #{name}"
|
|
:device_up -> "Device recovered: #{name}"
|
|
other -> "Alert: #{other} on #{name}"
|
|
end
|
|
end
|
|
|
|
defp severity(:device_down), do: "critical"
|
|
defp severity(:device_up), do: "info"
|
|
defp severity(_), do: "warning"
|
|
end
|