feat: add provider profile management api
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { chmod, readFile, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { startManagerServer } from "../../mgr/server.js";
|
||||
import { MemoryAgentRunStore } from "../../mgr/store.js";
|
||||
import { ManagerClient } from "../../mgr/client.js";
|
||||
import type { JsonRecord } from "../../common/types.js";
|
||||
import { assertNoSecretLeak, type SelfTestCase } from "../harness.js";
|
||||
|
||||
const secretText = "sk-selftest-provider-profile-secret";
|
||||
|
||||
const selfTest: SelfTestCase = async (context) => {
|
||||
const fakeKubectl = path.join(context.tmp, "fake-provider-kubectl.js");
|
||||
const appliedManifestPath = path.join(context.tmp, "provider-secret-apply.json");
|
||||
const createdJobPath = path.join(context.tmp, "provider-validation-job.json");
|
||||
await writeFile(fakeKubectl, `#!/usr/bin/env bun
|
||||
const args = Bun.argv.slice(2);
|
||||
const readStdin = async () => {
|
||||
const chunks = [];
|
||||
for await (const chunk of Bun.stdin.stream()) chunks.push(Buffer.from(chunk));
|
||||
return Buffer.concat(chunks).toString("utf8");
|
||||
};
|
||||
if (args[0] === "get" && args[1] === "secret") {
|
||||
console.log(JSON.stringify({ apiVersion: "v1", kind: "Secret", metadata: { name: args[2], namespace: "agentrun-v01", resourceVersion: "rv-selftest", creationTimestamp: "2026-06-05T00:00:00.000Z" }, data: { "auth.json": Buffer.from(JSON.stringify({ token: "redacted-fixture" })).toString("base64"), "config.toml": Buffer.from("model = \\\"fixture\\\"\\n").toString("base64") } }));
|
||||
process.exit(0);
|
||||
}
|
||||
if (args[0] === "apply") {
|
||||
const text = await readStdin();
|
||||
await Bun.write(${JSON.stringify(appliedManifestPath)}, text);
|
||||
const manifest = JSON.parse(text);
|
||||
const annotations = manifest.metadata?.annotations ?? {};
|
||||
console.log(JSON.stringify({ apiVersion: "v1", kind: "Secret", metadata: { name: manifest.metadata.name, namespace: manifest.metadata.namespace, resourceVersion: "rv-applied", annotations } }));
|
||||
process.exit(0);
|
||||
}
|
||||
if (args[0] === "create") {
|
||||
const text = await readStdin();
|
||||
await Bun.write(${JSON.stringify(createdJobPath)}, text);
|
||||
const manifest = JSON.parse(text);
|
||||
console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kind, metadata: { uid: "job-provider-validation", resourceVersion: "rv-job", name: manifest.metadata.name, namespace: manifest.metadata.namespace } }));
|
||||
process.exit(0);
|
||||
}
|
||||
console.error("unsupported fake kubectl args: " + JSON.stringify(args));
|
||||
process.exit(1);
|
||||
`);
|
||||
await chmod(fakeKubectl, 0o755);
|
||||
const store = new MemoryAgentRunStore();
|
||||
const server = await startManagerServer({
|
||||
port: 0,
|
||||
host: "127.0.0.1",
|
||||
sourceCommit: "self-test",
|
||||
store,
|
||||
providerProfileOptions: { namespace: "agentrun-v01", kubectlCommand: fakeKubectl },
|
||||
runnerJobDefaults: {
|
||||
namespace: "agentrun-v01",
|
||||
managerUrl: "http://agentrun-mgr.agentrun-v01.svc.cluster.local:8080",
|
||||
image: "127.0.0.1:5000/agentrun/agentrun-mgr@sha256:2222222222222222222222222222222222222222222222222222222222222222",
|
||||
kubectlCommand: fakeKubectl,
|
||||
},
|
||||
});
|
||||
try {
|
||||
const client = new ManagerClient(server.baseUrl);
|
||||
const list = await client.get("/api/v1/provider-profiles") as JsonRecord;
|
||||
assert.equal(list.count, 3);
|
||||
assert.equal(JSON.stringify(list).includes("auth.json"), true);
|
||||
assert.equal(JSON.stringify(list).includes("redacted-fixture"), false);
|
||||
|
||||
const updated = await client.put("/api/v1/provider-profiles/deepseek/credential", {
|
||||
apiKey: secretText,
|
||||
delegatedBy: { system: "hwlab-v02", userId: "u1", username: "tester", requestId: "req-selftest" },
|
||||
reason: "self-test",
|
||||
}) as JsonRecord;
|
||||
assert.equal(updated.profile, "deepseek");
|
||||
assert.equal(updated.resourceVersion, "rv-applied");
|
||||
assert.equal(updated.requiresExternalBridgeUpdate, true);
|
||||
assert.equal(JSON.stringify(updated).includes(secretText), false);
|
||||
assertNoSecretLeak(updated);
|
||||
const manifest = JSON.parse(await readFile(appliedManifestPath, "utf8")) as JsonRecord;
|
||||
const stringData = manifest.stringData as JsonRecord;
|
||||
assert.equal(String(stringData["auth.json"]).includes(secretText), true);
|
||||
assert.equal(String(stringData["auth.json"]).includes("OPENAI_API_KEY"), true);
|
||||
assert.equal(String(stringData["config.toml"]).includes("hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local"), true);
|
||||
assert.equal(String(stringData["config.toml"]).includes("hyueapi.com"), false);
|
||||
|
||||
await assert.rejects(
|
||||
() => client.put("/api/v1/provider-profiles/deepseek/credential", { apiKey: secretText, config: { baseUrl: "https://hyueapi.com/v1" } }),
|
||||
(error) => error instanceof Error && error.message.includes("not hyueapi.com"),
|
||||
);
|
||||
|
||||
const validation = await client.post("/api/v1/provider-profiles/deepseek/validate", {}) as JsonRecord;
|
||||
assert.equal(validation.profile, "deepseek");
|
||||
assert.equal(validation.status, "running");
|
||||
assert.equal(typeof validation.validationId, "string");
|
||||
const validationId = String(validation.validationId);
|
||||
const jobManifest = JSON.parse(await readFile(createdJobPath, "utf8")) as JsonRecord;
|
||||
assert.equal(JSON.stringify(jobManifest).includes("agentrun-v01-provider-deepseek"), true);
|
||||
assert.equal(JSON.stringify(jobManifest).includes(secretText), false);
|
||||
assertNoSecretLeak(validation);
|
||||
|
||||
await client.post(`/api/v1/runs/${encodeURIComponent(String(validation.runId))}/events`, { type: "assistant_message", payload: { commandId: validation.commandId, text: "AGENTRUN_PROVIDER_PROFILE_OK_DEEPSEEK", final: true, replyAuthority: true } });
|
||||
await client.patch(`/api/v1/commands/${encodeURIComponent(String(validation.commandId))}/status`, { terminalStatus: "completed", failureKind: null, failureMessage: null });
|
||||
const finalValidation = await client.get(`/api/v1/provider-profiles/deepseek/validations/${encodeURIComponent(validationId)}`) as JsonRecord;
|
||||
assert.equal(finalValidation.status, "completed");
|
||||
assert.equal(JSON.stringify(finalValidation).includes(secretText), false);
|
||||
assertNoSecretLeak(finalValidation);
|
||||
return { name: "provider-profile-management", tests: ["provider-profiles-list-redacted", "provider-profile-set-key-redacted", "provider-profile-deepseek-moon-bridge", "provider-profile-validation-runner-job"] };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.server.close(() => resolve()));
|
||||
}
|
||||
};
|
||||
|
||||
export default selfTest;
|
||||
Reference in New Issue
Block a user