diff --git a/server/lib/server_web/controllers/host_controller.ex b/server/lib/server_web/controllers/host_controller.ex new file mode 100644 index 0000000..0b1f894 --- /dev/null +++ b/server/lib/server_web/controllers/host_controller.ex @@ -0,0 +1,30 @@ +defmodule ServerWeb.HostController do + use ServerWeb, :controller + + alias Server.{Metrics, Repo, Schema.Host} + + def show(conn, %{"name" => name}) do + case Repo.get_by(Host, name: name) do + nil -> + conn + |> put_status(:not_found) + |> json(%{error: "host_not_found"}) + + %Host{} = host -> + samples = + for interval <- ~w(fast medium slow), + sample = Metrics.latest_sample(host.id, interval), + into: %{} do + {interval, %{collected_at: sample.collected_at, payload: sample.payload}} + end + + json(conn, %{ + name: host.name, + status: host.status, + agent_version: host.agent_version, + last_seen_at: host.last_seen_at, + samples: samples + }) + end + end +end diff --git a/server/lib/server_web/router.ex b/server/lib/server_web/router.ex index 2d4c74b..af8415e 100644 --- a/server/lib/server_web/router.ex +++ b/server/lib/server_web/router.ex @@ -20,10 +20,11 @@ defmodule ServerWeb.Router do get "/", PageController, :home end - # Other scopes may use custom stacks. - # scope "/api", ServerWeb do - # pipe_through :api - # end + scope "/api", ServerWeb do + pipe_through :api + + get "/hosts/:name", HostController, :show + end # Enable LiveDashboard in development if Application.compile_env(:server, :dev_routes) do diff --git a/server/test/server_web/controllers/host_controller_test.exs b/server/test/server_web/controllers/host_controller_test.exs new file mode 100644 index 0000000..80735fd --- /dev/null +++ b/server/test/server_web/controllers/host_controller_test.exs @@ -0,0 +1,36 @@ +defmodule ServerWeb.HostControllerTest do + use ServerWeb.ConnCase, async: true + + alias Server.{Hosts, Metrics} + + describe "GET /api/hosts/:name" do + setup do + {:ok, {host, _token}} = Hosts.create_host("pve-01") + + {:ok, _} = + Metrics.record_sample( + host.id, + "fast", + DateTime.utc_now(), + %{"host" => %{"load1" => 0.5}} + ) + + %{host: host} + end + + test "returns host info and latest samples", %{conn: conn, host: host} do + conn = get(conn, ~p"/api/hosts/#{host.name}") + + assert %{ + "name" => "pve-01", + "status" => _, + "samples" => %{"fast" => %{"payload" => %{"host" => %{"load1" => 0.5}}}} + } = json_response(conn, 200) + end + + test "returns 404 for unknown host", %{conn: conn} do + conn = get(conn, ~p"/api/hosts/nope") + assert json_response(conn, 404) == %{"error" => "host_not_found"} + end + end +end