feat: routes HTTP Hono (machines, refresh, actions, executions)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 04:13:15 +02:00
parent b4d47901b6
commit c3584f4ec8
3 changed files with 89 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
// server/routes/actions.ts
import { Hono } from "hono";
import { readFileSync } from "node:fs";
import { runAction, listExecutions, getExecution } from "../services/execute.js";
import type { ActionType } from "@shared/types.js";
export const actionsRoutes = new Hono();
actionsRoutes.post("/:id/actions", async (c) => {
const { action } = (await c.req.json()) as { action: ActionType };
if (action !== "apt_full_upgrade" && action !== "reboot") {
return c.json({ error: "Action non autorisée" }, 400);
}
// Exécution lancée en arrière-plan; le suivi se fait via WebSocket.
runAction(c.req.param("id"), action).catch((err) =>
console.error("[action]", (err as Error).message),
);
return c.json({ ok: true, action }, 202);
});
actionsRoutes.get("/:id/executions", (c) => c.json(listExecutions(c.req.param("id"))));
actionsRoutes.get("/:id/executions/:execId", (c) => {
const e = getExecution(c.req.param("execId"));
return e ? c.json(e) : c.json({ error: "Exécution introuvable" }, 404);
});
actionsRoutes.get("/:id/executions/:execId/report", (c) => {
const e = getExecution(c.req.param("execId"));
if (!e?.reportPath) return c.json({ error: "Rapport introuvable" }, 404);
return c.text(readFileSync(e.reportPath, "utf8"));
});
+8
View File
@@ -0,0 +1,8 @@
// server/routes/index.ts
import { Hono } from "hono";
import { machinesRoutes } from "./machines.js";
import { actionsRoutes } from "./actions.js";
export const api = new Hono();
api.route("/machines", machinesRoutes);
api.route("/machines", actionsRoutes);
+49
View File
@@ -0,0 +1,49 @@
// server/routes/machines.ts
import { Hono } from "hono";
import {
listMachines, createMachine, deleteMachine, getMachineRow, getCreds, testConnection,
type CreateMachineInput,
} from "../services/machines.js";
import { refreshMachine, getLatestSnapshot } from "../services/refresh.js";
export const machinesRoutes = new Hono();
machinesRoutes.get("/", (c) => c.json(listMachines()));
machinesRoutes.post("/", async (c) => {
const body = (await c.req.json()) as CreateMachineInput;
try {
const m = await createMachine(body);
return c.json(m, 201);
} catch (err) {
return c.json({ error: `Connexion échouée: ${(err as Error).message}` }, 400);
}
});
machinesRoutes.post("/:id/test-connection", async (c) => {
const m = getMachineRow(c.req.param("id"));
if (!m) return c.json({ error: "Machine introuvable" }, 404);
try {
return c.json(await testConnection(getCreds(m)));
} catch (err) {
return c.json({ error: (err as Error).message }, 400);
}
});
machinesRoutes.get("/:id/snapshot", (c) => {
const snap = getLatestSnapshot(c.req.param("id"));
return snap ? c.json(snap) : c.json({ error: "Aucun snapshot" }, 404);
});
machinesRoutes.post("/:id/refresh", async (c) => {
try {
return c.json(await refreshMachine(c.req.param("id")));
} catch (err) {
return c.json({ error: (err as Error).message }, 400);
}
});
machinesRoutes.delete("/:id", (c) => {
deleteMachine(c.req.param("id"));
return c.json({ ok: true });
});