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.
28 lines
1.6 KiB
TypeScript
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}`);
|
|
}
|
|
});
|