fix: authenticate CaseRun HWPOD prepare

This commit is contained in:
root
2026-07-16 21:19:40 +02:00
parent 66afd74c06
commit 5b60491e59
4 changed files with 113 additions and 3 deletions
@@ -5,6 +5,25 @@ import path from "node:path";
import { test } from "bun:test";
import { createCloudApiServer } from "./server.ts";
import { caseRunInternalFetch } from "./server-caserun-http.ts";
test("CaseRun internal requests reuse the existing bootstrap admin API key only for the internal origin", async () => {
const calls: Array<{ url: string; authorization: string | null }> = [];
const fetchImpl = async (input: URL | RequestInfo, init: RequestInit = {}) => {
const headers = new Headers(init.headers);
calls.push({ url: String(input), authorization: headers.get("authorization") });
return new Response("{}", { status: 200, headers: { "content-type": "application/json" } });
};
const internalFetch = caseRunInternalFetch(fetchImpl as typeof fetch, "http://hwlab-cloud-api.hwlab-v03.svc.cluster.local:6667", { HWLAB_BOOTSTRAP_ADMIN_API_KEY: "hwl_live_test" });
await internalFetch("http://hwlab-cloud-api.hwlab-v03.svc.cluster.local:6667/v1/hwpod-node-ops", { method: "POST" });
await internalFetch("https://lab-dev.hwpod.com/v1/hwpod-node-ops", { method: "POST" });
assert.deepEqual(calls, [
{ url: "http://hwlab-cloud-api.hwlab-v03.svc.cluster.local:6667/v1/hwpod-node-ops", authorization: "Bearer hwl_live_test" },
{ url: "https://lab-dev.hwpod.com/v1/hwpod-node-ops", authorization: null }
]);
});
test("cloud-api exposes web CaseRun cases, run status, events and aggregate", async () => {
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-caserun-api-"));
+15 -1
View File
@@ -184,6 +184,7 @@ async function runSoftwareSmokeCase(context: any, emit: (stage: string, payload?
function caseContextForRecord(record: any, input: any) {
const internalApiUrl = internalRuntimeApiUrlForCaseRun(record, input.env ?? {});
const fetchImpl = caseRunInternalFetch(input.fetchImpl ?? globalThis.fetch, internalApiUrl, input.env ?? {});
const parsed = {
_: [],
caseId: record.caseId,
@@ -204,7 +205,7 @@ function caseContextForRecord(record: any, input: any) {
HWLAB_CASERUN_PUBLIC_RUNTIME_API_URL: record.runtimeApiUrl,
HWLAB_RUNTIME_ENDPOINT_LOCKED: "1"
},
fetchImpl: input.fetchImpl ?? globalThis.fetch,
fetchImpl,
cwd: input.cwd,
now: () => new Date().toISOString(),
sleep: (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)),
@@ -215,6 +216,19 @@ function caseContextForRecord(record: any, input: any) {
};
}
export function caseRunInternalFetch(fetchImpl: typeof fetch, internalApiUrl: string, env: Record<string, string | undefined>) {
const apiKey = String(env.HWLAB_BOOTSTRAP_ADMIN_API_KEY ?? "").trim();
if (!apiKey) return fetchImpl;
const internalOrigin = new URL(internalApiUrl).origin;
return async (input: URL | RequestInfo, init: RequestInit = {}) => {
const target = new URL(typeof input === "string" || input instanceof URL ? input : input.url);
if (target.origin !== internalOrigin) return fetchImpl(input, init);
const headers = new Headers(init.headers);
if (!headers.has("authorization")) headers.set("authorization", `Bearer ${apiKey}`);
return fetchImpl(input, { ...init, headers });
};
}
function resolveCwd(env: Record<string, string | undefined>) {
return path.resolve(String(env.HWLAB_CASERUN_REPO_ROOT ?? process.cwd()));
}