114 lines
3.3 KiB
Elixir
114 lines
3.3 KiB
Elixir
defmodule ToweropsWeb.Api.V1.AlertsController do
|
|
@moduledoc "API controller for alerts."
|
|
use ToweropsWeb, :controller
|
|
|
|
alias Towerops.Alerts
|
|
|
|
def index(conn, params) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
filters =
|
|
params
|
|
|> Map.take(~w(status limit))
|
|
|> then(fn f ->
|
|
case params["device_id"] do
|
|
nil -> f
|
|
device_id -> Map.put(f, "device_id", device_id)
|
|
end
|
|
end)
|
|
|
|
alerts =
|
|
organization_id
|
|
|> Alerts.list_organization_alerts(filters)
|
|
|> Enum.map(&format_alert/1)
|
|
|
|
json(conn, %{data: alerts})
|
|
end
|
|
|
|
def show(conn, %{"id" => id}) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
alert = Alerts.get_alert!(id)
|
|
device = alert.device
|
|
|
|
if device && device.organization_id == organization_id do
|
|
json(conn, %{data: format_alert(alert)})
|
|
else
|
|
conn |> put_status(:not_found) |> json(%{error: "Alert not found"})
|
|
end
|
|
rescue
|
|
Ecto.NoResultsError ->
|
|
conn |> put_status(:not_found) |> json(%{error: "Alert not found"})
|
|
end
|
|
|
|
def acknowledge(conn, %{"id" => id}) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
user = conn.assigns[:current_user]
|
|
|
|
alert = Alerts.get_alert!(id)
|
|
device = alert.device
|
|
|
|
if device && device.organization_id == organization_id do
|
|
user_id = if user, do: user.id, else: nil
|
|
|
|
case Alerts.acknowledge_alert(alert, user_id) do
|
|
{:ok, updated} ->
|
|
json(conn, %{data: format_alert(Towerops.Repo.preload(updated, [:device, :acknowledged_by], force: true))})
|
|
|
|
{:error, _changeset} ->
|
|
conn |> put_status(:unprocessable_entity) |> json(%{error: "Could not acknowledge alert"})
|
|
end
|
|
else
|
|
conn |> put_status(:not_found) |> json(%{error: "Alert not found"})
|
|
end
|
|
rescue
|
|
Ecto.NoResultsError ->
|
|
conn |> put_status(:not_found) |> json(%{error: "Alert not found"})
|
|
end
|
|
|
|
def resolve(conn, %{"id" => id}) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
alert = Alerts.get_alert!(id)
|
|
device = alert.device
|
|
|
|
if device && device.organization_id == organization_id do
|
|
case Alerts.resolve_alert(alert) do
|
|
{:ok, updated} ->
|
|
json(conn, %{data: format_alert(Towerops.Repo.preload(updated, [:device, :acknowledged_by], force: true))})
|
|
|
|
{:error, _changeset} ->
|
|
conn |> put_status(:unprocessable_entity) |> json(%{error: "Could not resolve alert"})
|
|
end
|
|
else
|
|
conn |> put_status(:not_found) |> json(%{error: "Alert not found"})
|
|
end
|
|
rescue
|
|
Ecto.NoResultsError ->
|
|
conn |> put_status(:not_found) |> json(%{error: "Alert not found"})
|
|
end
|
|
|
|
defp format_alert(alert) do
|
|
%{
|
|
id: alert.id,
|
|
alert_type: alert.alert_type,
|
|
message: alert.message,
|
|
triggered_at: alert.triggered_at,
|
|
acknowledged_at: alert.acknowledged_at,
|
|
resolved_at: alert.resolved_at,
|
|
device_id: alert.device_id,
|
|
device_name: get_in_loaded(alert, :device, :name),
|
|
acknowledged_by_email: get_in_loaded(alert, :acknowledged_by, :email),
|
|
gaiia_impact: alert.gaiia_impact,
|
|
inserted_at: alert.inserted_at
|
|
}
|
|
end
|
|
|
|
defp get_in_loaded(struct, assoc, field) do
|
|
case Map.get(struct, assoc) do
|
|
%Ecto.Association.NotLoaded{} -> nil
|
|
nil -> nil
|
|
loaded -> Map.get(loaded, field)
|
|
end
|
|
end
|
|
end
|