100 lines
2.8 KiB
Elixir
100 lines
2.8 KiB
Elixir
defmodule ToweropsWeb.Api.V1.AgentsController do
|
|
@moduledoc "API controller for agent tokens."
|
|
use ToweropsWeb, :controller
|
|
|
|
alias Towerops.Agents
|
|
|
|
def index(conn, _params) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
agents =
|
|
organization_id
|
|
|> Agents.list_organization_agent_tokens()
|
|
|> Enum.map(&format_agent/1)
|
|
|
|
json(conn, %{data: agents})
|
|
end
|
|
|
|
def create(conn, %{"name" => name}) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
case Agents.create_agent_token(organization_id, name) do
|
|
{:ok, agent_token, raw_token} ->
|
|
conn
|
|
|> put_status(:created)
|
|
|> json(%{data: Map.put(format_agent(agent_token), :token, raw_token)})
|
|
|
|
{:error, changeset} ->
|
|
conn
|
|
|> put_status(:unprocessable_entity)
|
|
|> json(%{errors: translate_errors(changeset)})
|
|
end
|
|
end
|
|
|
|
def create(conn, _params) do
|
|
conn |> put_status(:bad_request) |> json(%{error: "Missing 'name' parameter"})
|
|
end
|
|
|
|
def show(conn, %{"id" => id}) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
agent = Agents.get_agent_token!(id)
|
|
|
|
if agent.organization_id == organization_id do
|
|
device_count = Agents.count_assigned_devices(id)
|
|
|
|
json(conn, %{
|
|
data:
|
|
format_agent(agent)
|
|
|> Map.put(:device_count, device_count)
|
|
})
|
|
else
|
|
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
|
|
end
|
|
rescue
|
|
Ecto.NoResultsError ->
|
|
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
|
|
end
|
|
|
|
def delete(conn, %{"id" => id}) do
|
|
organization_id = conn.assigns.current_organization_id
|
|
|
|
agent = Agents.get_agent_token!(id)
|
|
|
|
if agent.organization_id == organization_id do
|
|
case Agents.delete_agent_token(id) do
|
|
{:ok, _} -> conn |> put_status(:no_content) |> send_resp(204, "")
|
|
{:error, _} -> conn |> put_status(:unprocessable_entity) |> json(%{error: "Could not delete agent"})
|
|
end
|
|
else
|
|
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
|
|
end
|
|
rescue
|
|
Ecto.NoResultsError ->
|
|
conn |> put_status(:not_found) |> json(%{error: "Agent not found"})
|
|
end
|
|
|
|
defp format_agent(agent) do
|
|
%{
|
|
id: agent.id,
|
|
name: agent.name,
|
|
enabled: agent.enabled,
|
|
last_seen_at: agent.last_seen_at,
|
|
last_ip: agent.last_ip,
|
|
metadata: agent.metadata,
|
|
inserted_at: agent.inserted_at
|
|
}
|
|
end
|
|
|
|
defp translate_errors(changeset) do
|
|
Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} ->
|
|
Regex.replace(~r"%{(\w+)}", msg, fn _, key ->
|
|
if String.length(key) <= 50 and String.match?(key, ~r/^[a-z_]+$/) do
|
|
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
|
|
else
|
|
key
|
|
end
|
|
end)
|
|
end)
|
|
end
|
|
end
|