fix: prepare D518 runtime secret sources

This commit is contained in:
Codex
2026-06-27 14:07:19 +00:00
parent e56cfe2b73
commit 414bbba866
5 changed files with 236 additions and 44 deletions
+80 -4
View File
@@ -28,12 +28,12 @@ import { nodeObservabilityRecordingRuleExpression, nodeObservabilityRecordingRul
import { runDelegatedHwlabNodeCommand, type DelegatedNodeDomain } from "../hwlab-node-transport";
import type { RenderedCliResult } from "../output";
import type { NodePublicExposureOptions, NodeSecretOptions, RuntimeSecretSpec } from "./entry";
import type { CodeAgentProviderSecretMaterial, NodePublicExposureOptions, NodeSecretOptions, RuntimeSecretSpec } from "./entry";
import { BOOTSTRAP_ADMIN_PASSWORD_HASH_KEY, BOOTSTRAP_ADMIN_SOURCE_NAMESPACE, BOOTSTRAP_ADMIN_SOURCE_SECRET, CLOUD_API_DB_KEY, CODE_AGENT_PROVIDER_OPENAI_KEY, CODE_AGENT_PROVIDER_OPENCODE_KEY, CODE_AGENT_PROVIDER_SOURCE_NAMESPACE, CODE_AGENT_PROVIDER_SOURCE_SECRET, MASTER_ADMIN_API_KEY_KEY, OPENFGA_AUTHN_KEY, OPENFGA_DATASTORE_URI_KEY, OPENFGA_POSTGRES_PASSWORD_KEY } from "./entry";
import { transPath } from "./runtime-common";
import { bootstrapAdminSecretScript, cloudApiDbSecretScript, codeAgentProviderSecretScript, masterAdminApiKeySecretScript, obsoletePlatformDbCleanupScript, obsoletePlatformDbStatusFromText, obsoleteSecretCleanupScript, openFgaSecretScript, ownedPostgresCleanupScript, platformDbSecretStatusScript, secretStatusFromText } from "./secret-scripts";
import { assertLane, assertNodeId, compactCommandResult, keyValueLinesFromText, numericField, optionValue, positiveIntegerOption, readMasterAdminApiKey, requiredOption, shellQuote, statusText } from "./utils";
import { parseEnvFile, readBootstrapAdminSecretMaterial, syncNodeExternalPostgresSecrets } from "./web-probe";
import { displayRepoPath, localSecretSourcePaths, parseEnvFile, readBootstrapAdminSecretMaterial, shortSecretFingerprint, syncNodeExternalPostgresSecrets } from "./web-probe";
import { hwlabRuntimeActiveExternalPostgres } from "../hwlab-node-lanes";
export function isSafeWebProbeScriptRunDir(value: string | null): value is string {
@@ -242,9 +242,12 @@ export function runtimeSecretSpec(input: { node: string; lane: string }): Runtim
obsoleteHwpodDbSecret: `hwpod-${input.lane}-db`,
obsoleteHwpodDbName: `hwpod_${input.lane}`,
obsoleteHwpodDbUser: `hwpod_${input.lane}_app`,
codeAgentProviderSecret: `${namespace}-code-agent-provider`,
codeAgentProviderSecret: runtimeLaneSpec?.codeAgentProvider?.secretName ?? `${namespace}-code-agent-provider`,
codeAgentProviderSourceNamespace: CODE_AGENT_PROVIDER_SOURCE_NAMESPACE,
codeAgentProviderSourceSecret: CODE_AGENT_PROVIDER_SOURCE_SECRET,
...(runtimeLaneSpec?.codeAgentProvider?.sourceRef === undefined ? {} : { codeAgentProviderSourceRef: runtimeLaneSpec.codeAgentProvider.sourceRef }),
...(runtimeLaneSpec?.codeAgentProvider?.openaiSourceKey === undefined ? {} : { codeAgentProviderOpenaiSourceKey: runtimeLaneSpec.codeAgentProvider.openaiSourceKey }),
...(runtimeLaneSpec?.codeAgentProvider?.opencodeSourceKey === undefined ? {} : { codeAgentProviderOpencodeSourceKey: runtimeLaneSpec.codeAgentProvider.opencodeSourceKey }),
fieldManager: `unidesk-hwlab-node-${input.lane}-secret`,
};
}
@@ -256,6 +259,9 @@ export function runNodeSecret(options: NodeSecretOptions): Record<string, unknow
return runExternalPostgresSecretEnsure(options, spec);
}
const bootstrapAdminMaterial = options.preset === "bootstrap-admin" ? readBootstrapAdminSecretMaterial(spec) : null;
const codeAgentProviderMaterial = options.preset === "code-agent-provider" && spec.codeAgentProviderSourceRef !== undefined
? readCodeAgentProviderSecretMaterial(spec)
: null;
const input = options.preset === "master-server-admin-api-key" && options.action === "ensure" && !options.dryRun
? readMasterAdminApiKey(spec).key
: options.preset === "bootstrap-admin" && options.action === "ensure" && !options.dryRun && bootstrapAdminMaterial?.ok === true
@@ -271,7 +277,7 @@ export function runNodeSecret(options: NodeSecretOptions): Record<string, unknow
? spec.platformDb ? platformDbSecretStatusScript(options, spec) : cloudApiDbSecretScript(options, spec)
: options.preset === "owned-postgres-cleanup"
? ownedPostgresCleanupScript(options, spec)
: codeAgentProviderSecretScript(options, spec);
: codeAgentProviderSecretScript(options, spec, codeAgentProviderMaterial);
const result = runTransScript(options.node, script, input, options.timeoutSeconds);
const status = secretStatusFromText(statusText(result), result.exitCode === 0, result.exitCode, result.stderr, spec);
const dryRunOk = options.action === "ensure" && options.dryRun && result.exitCode === 0;
@@ -296,6 +302,76 @@ export function runNodeSecret(options: NodeSecretOptions): Record<string, unknow
};
}
export function readCodeAgentProviderSecretMaterial(spec: RuntimeSecretSpec): CodeAgentProviderSecretMaterial {
const sourceRef = spec.codeAgentProviderSourceRef ?? null;
if (sourceRef === null) {
return {
ok: false,
sourceRef,
sourcePath: null,
sourcePresent: false,
openaiSourceKey: spec.codeAgentProviderOpenaiSourceKey ?? null,
opencodeSourceKey: spec.codeAgentProviderOpencodeSourceKey ?? null,
openaiValue: null,
opencodeValue: null,
openaiFingerprint: null,
opencodeFingerprint: null,
error: "code-agent-provider-source-ref-missing",
};
}
const paths = localSecretSourcePaths(sourceRef);
const sourcePath = paths.find((candidate) => existsSync(candidate)) ?? paths[0] ?? null;
const openaiSourceKey = spec.codeAgentProviderOpenaiSourceKey ?? null;
const opencodeSourceKey = spec.codeAgentProviderOpencodeSourceKey ?? null;
if (sourcePath === null) {
return {
ok: false,
sourceRef,
sourcePath,
sourcePresent: false,
openaiSourceKey,
opencodeSourceKey,
openaiValue: null,
opencodeValue: null,
openaiFingerprint: null,
opencodeFingerprint: null,
error: "code-agent-provider-source-path-unresolved",
};
}
if (!existsSync(sourcePath)) {
return {
ok: false,
sourceRef,
sourcePath: displayRepoPath(sourcePath),
sourcePresent: false,
openaiSourceKey,
opencodeSourceKey,
openaiValue: null,
opencodeValue: null,
openaiFingerprint: null,
opencodeFingerprint: null,
error: "code-agent-provider-source-missing",
};
}
const values = parseEnvFile(readFileSync(sourcePath, "utf8"));
const openaiValue = openaiSourceKey === null ? null : values[openaiSourceKey] ?? null;
const opencodeValue = opencodeSourceKey === null ? null : values[opencodeSourceKey] ?? null;
const ok = (openaiValue !== null && openaiValue.length > 0) || (opencodeValue !== null && opencodeValue.length > 0);
return {
ok,
sourceRef,
sourcePath: displayRepoPath(sourcePath),
sourcePresent: true,
openaiSourceKey,
opencodeSourceKey,
openaiValue,
opencodeValue,
openaiFingerprint: openaiValue === null || openaiValue.length === 0 ? null : shortSecretFingerprint(openaiValue),
opencodeFingerprint: opencodeValue === null || opencodeValue.length === 0 ? null : shortSecretFingerprint(opencodeValue),
error: ok ? null : "code-agent-provider-source-key-missing",
};
}
export function nextSecretCommand(options: NodeSecretOptions, spec: RuntimeSecretSpec): Record<string, string> {
if (options.action === "cleanup-owned-postgres") {
return { ensure: `bun scripts/cli.ts hwlab nodes secret cleanup-owned-postgres --node ${options.node} --lane ${options.lane} --confirm` };