defmodule ToweropsWeb.GraphQL.Resolvers.Check do @moduledoc "GraphQL resolvers for service check queries and mutations." alias Towerops.Monitoring alias Towerops.Monitoring.Check alias ToweropsWeb.GraphQL.Resolvers.Helpers alias ToweropsWeb.ScopedResource @service_check_types ~w(http tcp dns ping) def list(_parent, args, %{context: %{organization_id: org_id}}) do opts = [] |> maybe_add_opt(:device_id, args[:device_id]) |> maybe_add_opt(:check_type, args[:check_type]) checks = org_id |> Monitoring.list_checks(opts) |> Enum.filter(&(&1.check_type in @service_check_types)) {:ok, checks} end def list(_parent, _args, _resolution), do: Helpers.authentication_error() def get(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do fetch_org_check(id, org_id) end def get(_parent, _args, _resolution), do: Helpers.authentication_error() def create(_parent, %{input: input}, %{context: %{organization_id: org_id}}) do attrs = input |> Map.new(fn {k, v} -> {to_string(k), v} end) |> Map.put("organization_id", org_id) check_type = Map.get(attrs, "check_type", "") if check_type in @service_check_types do create_and_schedule_check(attrs) else {:error, "Invalid check type '#{check_type}'. Must be one of: #{Enum.join(@service_check_types, ", ")}"} end end def create(_parent, _args, _resolution), do: Helpers.authentication_error() def update(_parent, %{id: id, input: input}, %{context: %{organization_id: org_id}}) do with {:ok, check} <- fetch_org_check(id, org_id) do attrs = Map.new(input, fn {k, v} -> {to_string(k), v} end) case Monitoring.update_check(check, attrs) do {:ok, updated} -> {:ok, updated} {:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)} end end end def update(_parent, _args, _resolution), do: Helpers.authentication_error() def delete(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do with {:ok, check} <- fetch_org_check(id, org_id) do case Monitoring.delete_check(check) do {:ok, _} -> {:ok, %{success: true, message: "Check deleted"}} {:error, _} -> {:ok, %{success: false, message: "Could not delete check"}} end end end def delete(_parent, _args, _resolution), do: Helpers.authentication_error() defp create_and_schedule_check(attrs) do case Monitoring.create_check(attrs) do {:ok, check} -> if check.enabled, do: Monitoring.schedule_check(check) {:ok, check} {:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)} end end defp fetch_org_check(id, org_id) do case ScopedResource.fetch(Check, id, org_id) do {:ok, check} -> {:ok, check} {:error, _reason} -> {:error, "Check not found"} end end defp maybe_add_opt(opts, _key, nil), do: opts defp maybe_add_opt(opts, key, value), do: Keyword.put(opts, key, value) end