79 lines
2.1 KiB
Elixir
79 lines
2.1 KiB
Elixir
defmodule Towerops.Workers.PagerdutyWebhookWorker do
|
|
@moduledoc """
|
|
Processes a PagerDuty webhook event asynchronously so the controller can ACK
|
|
the webhook sender immediately.
|
|
"""
|
|
|
|
use Oban.Pro.Worker, queue: :default, max_attempts: 3
|
|
|
|
alias Towerops.Alerts
|
|
|
|
require Logger
|
|
|
|
@impl Oban.Worker
|
|
def perform(%Oban.Job{args: %{"event_type" => event_type, "data" => data, "organization_id" => org_id}}) do
|
|
case event_type do
|
|
"incident.resolved" ->
|
|
resolve_from_pagerduty(data, org_id)
|
|
|
|
"incident.acknowledged" ->
|
|
acknowledge_from_pagerduty(data, org_id)
|
|
|
|
other ->
|
|
Logger.debug("Ignoring PagerDuty webhook event: #{other}")
|
|
:ok
|
|
end
|
|
end
|
|
|
|
defp resolve_from_pagerduty(data, _org_id) do
|
|
case extract_alert_id(data) do
|
|
nil ->
|
|
Logger.debug("PagerDuty resolve: no TowerOps alert ID found in incident")
|
|
:ok
|
|
|
|
alert_id ->
|
|
case Alerts.get_alert(alert_id) do
|
|
nil ->
|
|
Logger.warning("PagerDuty resolve: alert #{alert_id} not found")
|
|
|
|
%{resolved_at: resolved_at} when not is_nil(resolved_at) ->
|
|
Logger.debug("PagerDuty resolve: alert #{alert_id} already resolved")
|
|
|
|
alert ->
|
|
Logger.info("Resolving alert #{alert_id} from PagerDuty")
|
|
Alerts.resolve_alert_silent(alert)
|
|
end
|
|
end
|
|
end
|
|
|
|
defp acknowledge_from_pagerduty(data, _org_id) do
|
|
case extract_alert_id(data) do
|
|
nil ->
|
|
:ok
|
|
|
|
alert_id ->
|
|
case Alerts.get_alert(alert_id) do
|
|
nil ->
|
|
Logger.warning("PagerDuty acknowledge: alert #{alert_id} not found")
|
|
|
|
%{acknowledged_at: ack} when not is_nil(ack) ->
|
|
Logger.debug("PagerDuty acknowledge: alert #{alert_id} already acknowledged")
|
|
|
|
alert ->
|
|
Logger.info("Acknowledging alert #{alert_id} from PagerDuty")
|
|
Alerts.acknowledge_alert_silent(alert)
|
|
end
|
|
end
|
|
end
|
|
|
|
defp extract_alert_id(data) do
|
|
alerts = data["alerts"] || []
|
|
|
|
Enum.find_value(alerts, fn alert ->
|
|
case alert["alert_key"] do
|
|
"towerops-alert-" <> id -> id
|
|
_ -> nil
|
|
end
|
|
end)
|
|
end
|
|
end
|