Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/frontend/packages/swarm-ui/src/App.tsx
atlas 7d09776742 swarm UI: an alerts page, read by the controller with a Viewer Grafana token from bao
swarm-bao-grafana-controller-token, on the host that runs Grafana, logs in
to Grafana's API over its socket as the built-in admin (the password
swarm-bao-grafana-admin minted, #5138) and keeps a `swarm-controller`
service account that is an enabled Viewer. It mints a token for that
account and writes it to bao at
swarm/controller/swarm-controller/grafana/token under Grafana's leaf. A
ten-minute timer runs it again. The unit keeps a stored token Grafana
accepts. If Grafana refuses the stored token with 401, or bao holds
none, the unit deletes every token of the account and mints a new one.
Grafana's grant gains create/read/update on that leaf, and the
controller's gains read.

swarm-controller serves GET /api/alerts from Grafana's
/api/prometheus/grafana/api/v1/alerts. It reads the token from bao,
keeps it in memory, and re-reads bao once on a 401. The HTTP client has
5s connect and 15s request timeouts. Any failure is a 503 that names its
cause. swarm-ui gets an /alerts page listing them, built the same way as
the hives page.

This is option (c) on #5129, the operator's choice.
2026-10-15 15:16:21 +02:00

47 lines
1.8 KiB
TypeScript

// Root shell component — routing only. Each route's content is its own
// page component under `./pages/`; this file just maps paths to them.
import { Route, Switch } from "wouter-preact";
import { Shell } from "./shell/Shell.js";
import { AgentsPage } from "./pages/agents/AgentsPage.js";
import { AgentTerminalPage } from "./pages/agents/AgentTerminalPage.js";
import { AlertsPage } from "./pages/AlertsPage.js";
import { ComponentsPage } from "./pages/ComponentsPage.js";
import { JobsPage } from "./pages/JobsPage.js";
import { HivesPage } from "./pages/HivesPage.js";
import { IssueReportPage } from "./pages/IssueReportPage.js";
import { ReviewPage } from "./pages/review/ReviewPage.js";
import { SchedulesPage } from "./pages/schedules/SchedulesPage.js";
import { StartPage } from "./pages/StartPage.js";
import { Panel } from "./ui/panel/Panel.js";
function NotFound() {
return (
<Panel title="404" icon="🧭">
<p>no route here.</p>
</Panel>
);
}
export function App() {
return (
<Shell>
<Switch>
<Route path="/" component={StartPage} />
<Route path="/hives" component={HivesPage} />
<Route path="/alerts" component={AlertsPage} />
<Route path="/agents" component={AgentsPage} />
<Route path="/agents/:name/terminal" component={AgentTerminalPage} />
<Route
path="/agents/:name/subagents/:subagent/terminal"
component={AgentTerminalPage}
/>
<Route path="/jobs" component={JobsPage} />
<Route path="/schedules" component={SchedulesPage} />
<Route path="/issues" component={IssueReportPage} />
<Route path="/review" component={ReviewPage} />
<Route path="/components" component={ComponentsPage} />
<Route component={NotFound} />
</Switch>
</Shell>
);
}