Require a token to scrape /metrics

The metrics endpoint fans out a gather to every connected host, so
anyone who could reach the controller could read cluster statistics and
put load on all hosts at will. Scraping now needs a user token holding
the new core.controller.metrics permission. The token is accepted via
Authorization: Bearer as well as X-Access-Token because Prometheus can
only send the former. Concurrent scrapes share one gather so hosts see
at most one metrics request at a time.

The three connection gauges in controller.ts now no-op before the
controller exists, like the other gauges there, so the endpoint can be
tested against the mock controller.

Closes #1009

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Fable 5.1 committed 2026-09-12 22:28:43 +00:00
1 parent 2b981a5734
commit 87aa7b3b4c
6 files changed
+151 -10

No files matched your search

+9
View File
@@ -101,6 +101,9 @@ void new lib.Gauge(
"clusterio_controller_websocket_active_connections",
"How many WebSocket connections are currently open to the controller",
{ callback: function(gauge:lib.Gauge) {
if (!controller) {
return;
}
gauge.set(controller.wsServer.activeConnectors.size);
}}
);
@@ -109,6 +112,9 @@ void new lib.Gauge(
"clusterio_controller_active_hosts",
"How many hosts are currently connected to the controller",
{ callback: function(gauge:lib.Gauge) {
if (!controller) {
return;
}
gauge.set(controller.wsServer.hostConnections.size);
}}
);
@@ -118,6 +124,9 @@ void new lib.Gauge(
"How many clients are currently connected to this controller",
{
labels: ["type"], callback: async function(gauge:lib.Gauge) {
if (!controller) {
return;
}
gauge.labels("host").set(controller.wsServer.hostConnections.size);
gauge.labels("control").set(controller.wsServer.controlConnections.size);
},