fix: 支持动态 provider profile slug
This commit is contained in:
@@ -12,12 +12,9 @@ const secretText = "sk-selftest-provider-profile-secret";
|
||||
const selfTest: SelfTestCase = async (context) => {
|
||||
const gitopsRenderer = await readFile(path.join(context.root, "scripts/src/gitops-render.ts"), "utf8");
|
||||
assert.equal(gitopsRenderer.includes("agentrun-v01-mgr-provider-secret-manager"), true);
|
||||
assert.equal(gitopsRenderer.includes('verbs: ["create"]'), true);
|
||||
assert.equal(gitopsRenderer.includes('verbs: ["get", "patch", "update"]'), true);
|
||||
assert.equal(gitopsRenderer.includes('resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-dsflash-go"]'), true);
|
||||
for (const profile of ["codex", "deepseek", "minimax-m3", "dsflash-go"]) {
|
||||
assert.equal(gitopsRenderer.includes(`agentrun-v01-provider-${profile}`), true);
|
||||
}
|
||||
assert.equal(gitopsRenderer.includes('verbs: ["create", "get", "list", "patch", "update"]'), true);
|
||||
assert.equal(gitopsRenderer.includes('resourceNames: ["agentrun-v01-provider-codex", "agentrun-v01-provider-deepseek", "agentrun-v01-provider-minimax-m3", "agentrun-v01-provider-dsflash-go"]'), false);
|
||||
assert.equal(gitopsRenderer.includes('resources: ["secrets"]'), true);
|
||||
|
||||
const fakeKubectl = path.join(context.tmp, "fake-provider-kubectl.js");
|
||||
const replacedSecretPath = path.join(context.tmp, "provider-secret-replace.json");
|
||||
@@ -42,11 +39,22 @@ if (args[0] === "get" && args[1] === "secret") {
|
||||
console.log(await stateFile.text());
|
||||
process.exit(0);
|
||||
}
|
||||
if (name === "agentrun-v01-provider-dsflash-go") {
|
||||
if (name === "agentrun-v01-provider-dsflash-go" || name === "agentrun-v01-provider-dsflash-go-cli-selftest") {
|
||||
console.error('Error from server (NotFound): secrets "' + name + '" not found');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(JSON.stringify(fixtureSecret(name)));
|
||||
const fixture = fixtureSecret(name);
|
||||
await Bun.write(secretStatePath(name), JSON.stringify(fixture));
|
||||
console.log(JSON.stringify(fixture));
|
||||
process.exit(0);
|
||||
}
|
||||
if (args[0] === "get" && args[1] === "secrets") {
|
||||
const items = [fixtureSecret("agentrun-v01-provider-codex"), fixtureSecret("agentrun-v01-provider-deepseek"), fixtureSecret("agentrun-v01-provider-minimax-m3")];
|
||||
const dsflashState = Bun.file(secretStatePath("agentrun-v01-provider-dsflash-go"));
|
||||
if (await dsflashState.exists()) items.push(JSON.parse(await dsflashState.text()));
|
||||
const dynamicState = Bun.file(secretStatePath("agentrun-v01-provider-dsflash-go-cli-selftest"));
|
||||
if (await dynamicState.exists()) items.push(JSON.parse(await dynamicState.text()));
|
||||
console.log(JSON.stringify({ apiVersion: "v1", kind: "SecretList", items }));
|
||||
process.exit(0);
|
||||
}
|
||||
if (args[0] === "apply") {
|
||||
@@ -71,12 +79,10 @@ if (args[0] === "patch" && args[1] === "secret") {
|
||||
if (args[0] === "replace") {
|
||||
const text = await readStdin();
|
||||
const manifest = JSON.parse(text);
|
||||
if (manifest.metadata?.name === "agentrun-v01-provider-dsflash-go") {
|
||||
const stateFile = Bun.file(secretStatePath(manifest.metadata.name));
|
||||
if (!(await stateFile.exists())) {
|
||||
console.error('Error from server (NotFound): secrets "' + manifest.metadata.name + '" not found');
|
||||
process.exit(1);
|
||||
}
|
||||
const stateFile = Bun.file(secretStatePath(manifest.metadata.name));
|
||||
if (!(await stateFile.exists())) {
|
||||
console.error('Error from server (NotFound): secrets "' + manifest.metadata.name + '" not found');
|
||||
process.exit(1);
|
||||
}
|
||||
await Bun.write(${JSON.stringify(replacedSecretPath)}, JSON.stringify({ args, manifest }, null, 2));
|
||||
const annotations = manifest.metadata?.annotations ?? {};
|
||||
@@ -148,6 +154,27 @@ process.exit(1);
|
||||
assert.equal(Buffer.from(String(configData["auth.json"]), "base64").toString("utf8").includes("redacted-fixture"), true);
|
||||
assert.equal(Buffer.from(String(configData["config.toml"]), "base64").toString("utf8"), updatedConfigToml);
|
||||
|
||||
const dynamicProfile = "dsflash-go-cli-selftest";
|
||||
const dynamicConfigToml = "model_provider = \"opencode\"\nmodel = \"deepseek-v4-flash\"\nreview_model = \"deepseek-v4-flash\"\nbase_url = \"http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1\"\n";
|
||||
const dynamicConfig = await client.put(`/api/v1/provider-profiles/${encodeURIComponent(dynamicProfile)}/config`, {
|
||||
configToml: dynamicConfigToml,
|
||||
delegatedBy: { system: "hwlab-v02", userId: "u-dynamic", username: "dynamic", requestId: "req-config-dynamic-selftest" },
|
||||
reason: "self-test-dynamic-config",
|
||||
}) as JsonRecord;
|
||||
assert.equal(dynamicConfig.profile, dynamicProfile);
|
||||
assert.equal(dynamicConfig.configured, false);
|
||||
assert.equal(dynamicConfig.credentialHashSuffix, null);
|
||||
const dynamicCreateRecord = JSON.parse(await readFile(createdSecretPath, "utf8")) as JsonRecord;
|
||||
const dynamicCreateManifest = dynamicCreateRecord.manifest as JsonRecord;
|
||||
assert.equal(((dynamicCreateManifest.metadata as JsonRecord).name), `agentrun-v01-provider-${dynamicProfile}`);
|
||||
const dynamicCreateData = dynamicCreateManifest.data as JsonRecord;
|
||||
assert.equal(Object.hasOwn(dynamicCreateData, "auth.json"), false);
|
||||
assert.equal(Buffer.from(String(dynamicCreateData["config.toml"]), "base64").toString("utf8"), dynamicConfigToml);
|
||||
|
||||
const dynamicShownAfterConfig = await client.get(`/api/v1/provider-profiles/${encodeURIComponent(dynamicProfile)}`) as JsonRecord;
|
||||
assert.equal(dynamicShownAfterConfig.configured, false);
|
||||
assert.equal(dynamicShownAfterConfig.failureKind, "secret-unavailable");
|
||||
|
||||
const updated = await client.put("/api/v1/provider-profiles/deepseek/credential", {
|
||||
apiKey: secretText,
|
||||
delegatedBy: { system: "hwlab-v02", userId: "u1", username: "tester", requestId: "req-selftest" },
|
||||
@@ -205,6 +232,30 @@ process.exit(1);
|
||||
assert.equal(dsflashShown.failureKind, null);
|
||||
assertNoSecretLeak(dsflashCreated);
|
||||
|
||||
const dynamicCredential = await client.put(`/api/v1/provider-profiles/${encodeURIComponent(dynamicProfile)}/credential`, {
|
||||
apiKey: secretText,
|
||||
delegatedBy: { system: "hwlab-v02", userId: "u3", username: "tester3", requestId: "req-dynamic-create-selftest" },
|
||||
reason: "self-test-dynamic-create",
|
||||
}) as JsonRecord;
|
||||
assert.equal(dynamicCredential.profile, dynamicProfile);
|
||||
assert.equal(dynamicCredential.resourceVersion, "rv-cleaned");
|
||||
assert.equal(dynamicCredential.requiresExternalBridgeUpdate, true);
|
||||
const dynamicReplaceRecord = JSON.parse(await readFile(replacedSecretPath, "utf8")) as JsonRecord;
|
||||
const dynamicReplaceManifest = dynamicReplaceRecord.manifest as JsonRecord;
|
||||
assert.equal(((dynamicReplaceManifest.metadata as JsonRecord).name), `agentrun-v01-provider-${dynamicProfile}`);
|
||||
const dynamicReplaceData = dynamicReplaceManifest.data as JsonRecord;
|
||||
assert.equal(Buffer.from(String(dynamicReplaceData["auth.json"]), "base64").toString("utf8").includes(secretText), true);
|
||||
assert.equal(Buffer.from(String(dynamicReplaceData["config.toml"]), "base64").toString("utf8"), dynamicConfigToml);
|
||||
const dynamicShown = await client.get(`/api/v1/provider-profiles/${encodeURIComponent(dynamicProfile)}`) as JsonRecord;
|
||||
assert.equal(dynamicShown.configured, true);
|
||||
assert.equal(dynamicShown.failureKind, null);
|
||||
|
||||
const listAfterDynamic = await client.get("/api/v1/provider-profiles") as JsonRecord;
|
||||
assert.equal(listAfterDynamic.count, 5);
|
||||
const dynamicListItems = (listAfterDynamic.items as JsonRecord[]) ?? [];
|
||||
assert.equal(dynamicListItems.some((item) => item.profile === dynamicProfile), true);
|
||||
assertNoSecretLeak(dynamicCredential);
|
||||
|
||||
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"),
|
||||
@@ -228,7 +279,7 @@ process.exit(1);
|
||||
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-config", "provider-profile-set-key-redacted", "provider-profile-secret-replace-annotation-cleanup", "provider-profile-secret-create-upsert", "provider-profile-deepseek-moon-bridge", "provider-profile-manager-secret-rbac", "provider-profile-validation-runner-job"] };
|
||||
return { name: "provider-profile-management", tests: ["provider-profiles-list-redacted", "provider-profile-config", "provider-profile-set-key-redacted", "provider-profile-secret-replace-annotation-cleanup", "provider-profile-secret-create-upsert", "provider-profile-config-only-create", "provider-profile-dynamic-slug-roundtrip", "provider-profile-deepseek-moon-bridge", "provider-profile-manager-secret-rbac", "provider-profile-validation-runner-job"] };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.server.close(() => resolve()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user