Files
mesh-catalog/modules/grafana/test/refused.test.ts
T
jschoubben 0e6ca453be Say grafana's refused admin password once with its cause, and ask again hourly, not every 30 s (issue 774)
Grafana on ace answers 401 to the vault's admin password, every 30 s since at least 2026-10-05. I think the cause is
the adoption: Grafana keeps the admin password it was first given in its database and applies
GF_SECURITY_ADMIN_PASSWORD__FILE only when it creates it; ace's Grafana came with its database before the mesh minted
own/ace/grafana/admin (2026-09-30, generation 1, unchanged since), so the minted value never took (keycloak's
admin, hq issue 179, is the same kind).

Quick fix: none in code; the password in Grafana's database must become the vault's (grafana cli admin
reset-admin-password in the container), an act on ace no tool offers yet. Thorough fix: a step that converges the
admin password at every start, which needs a container entrypoint the node-engine's declaration does not carry.
This commit does what the catalogue can now: the refusal is said once with its cause and what ends it, asked again
hourly, and its end is said.
2026-10-30 18:18:16 +01:00

28 lines
1.6 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "node:test";
// The sweep of 2026-10-30 (issue 774): a refused admin password was said every 30 s, forever. Now it is said once with
// its cause, asked again hourly, and its end is said; any other error is still said each time.
test("a refused credential is said once, asked again hourly, and its end said", async () => {
const { Refusal, AskAgainRefusedMs } = await import("../refused.ts");
const r = new Refusal();
const refused = new Error('Grafana API /api/prometheus/grafana/api/v1/alerts: 401 {"message":"Invalid username or password"}');
const rows: [number, Error | undefined, boolean, RegExp | undefined][] = [
// at, error of the ask, due before it, what is said
[0, refused, true, /refuses the vault's admin password.*reset-admin-password/],
[30_000, undefined, false, undefined],
[AskAgainRefusedMs, refused, true, undefined],
[AskAgainRefusedMs + 1, new Error("Grafana API /api/health: 502 bad gateway"), false, undefined],
[2 * AskAgainRefusedMs, undefined, true, /accepts the vault's admin password again/],
[2 * AskAgainRefusedMs + 30_000, new Error("Grafana API /x: 502 bad gateway"), true, /502 bad gateway/],
[2 * AskAgainRefusedMs + 60_000, new Error("Grafana API /x: 502 bad gateway"), true, /502 bad gateway/],
];
for (const [i, [at, err, due, said]] of rows.entries()) {
assert.equal(r.due(at), due, `row ${i}: due`);
if (!due) continue;
const line = r.after(at, err);
if (said) assert.match(line ?? "", said, `row ${i}`);
else assert.equal(line, undefined, `row ${i}`);
}
});