fix: assemble UniDesk SSH endpoint env
This commit is contained in:
@@ -3,7 +3,7 @@ import { AgentRunError } from "../common/errors.js";
|
||||
import { redactJson, redactText } from "../common/redaction.js";
|
||||
import { isTerminalCommandState, isTerminalRunStatus, summarizeResourceBundleRef, summarizeSessionRef } from "./store.js";
|
||||
import type { AgentRunStore } from "./store.js";
|
||||
import type { JsonRecord } from "../common/types.js";
|
||||
import type { ExecutionPolicy, JsonRecord } from "../common/types.js";
|
||||
import { stableHash, validateEnvName } from "../common/validation.js";
|
||||
import { renderRunnerJobManifest } from "../runner/k8s-job.js";
|
||||
import type { RunnerSessionPvcOptions, RunnerTransientEnv } from "../runner/k8s-job.js";
|
||||
@@ -20,6 +20,17 @@ const reusableCredentialEnvNames = new Set([
|
||||
"UNIDESK_SSH_CLIENT_TOKEN",
|
||||
]);
|
||||
|
||||
const unideskSshEndpointEnvNames = ["UNIDESK_MAIN_SERVER_IP", "UNIDESK_MAIN_SERVER_HOST", "UNIDESK_FRONTEND_URL"] as const;
|
||||
const unideskSshEndpointEnvNameSet = new Set<string>(unideskSshEndpointEnvNames);
|
||||
const unideskSshEndpointConfigEnvNames: Array<{ configName: string; targetName: (typeof unideskSshEndpointEnvNames)[number] }> = [
|
||||
{ configName: "AGENTRUN_UNIDESK_MAIN_SERVER_IP", targetName: "UNIDESK_MAIN_SERVER_IP" },
|
||||
{ configName: "AGENTRUN_UNIDESK_MAIN_SERVER_HOST", targetName: "UNIDESK_MAIN_SERVER_HOST" },
|
||||
{ configName: "AGENTRUN_UNIDESK_FRONTEND_URL", targetName: "UNIDESK_FRONTEND_URL" },
|
||||
{ configName: "UNIDESK_MAIN_SERVER_IP", targetName: "UNIDESK_MAIN_SERVER_IP" },
|
||||
{ configName: "UNIDESK_MAIN_SERVER_HOST", targetName: "UNIDESK_MAIN_SERVER_HOST" },
|
||||
{ configName: "UNIDESK_FRONTEND_URL", targetName: "UNIDESK_FRONTEND_URL" },
|
||||
];
|
||||
|
||||
export interface RunnerJobDefaults {
|
||||
namespace: string;
|
||||
managerUrl: string;
|
||||
@@ -27,6 +38,7 @@ export interface RunnerJobDefaults {
|
||||
sourceCommit: string;
|
||||
serviceAccountName?: string;
|
||||
kubectlCommand?: string;
|
||||
unideskSshEndpointEnv?: JsonRecord;
|
||||
}
|
||||
|
||||
export interface CreateRunnerJobInput extends JsonRecord {
|
||||
@@ -56,7 +68,7 @@ export async function createKubernetesRunnerJob(options: { store: AgentRunStore;
|
||||
const sourceCommit = optionalString(options.input.sourceCommit) ?? options.defaults.sourceCommit;
|
||||
const serviceAccountName = optionalString(options.input.serviceAccountName) ?? options.defaults.serviceAccountName;
|
||||
const idempotencyKey = optionalString(options.input.idempotencyKey);
|
||||
const transientEnv = transientEnvField(options.input.transientEnv);
|
||||
const transientEnv = assembleToolContextTransientEnv(run.executionPolicy, transientEnvField(options.input.transientEnv), options.defaults);
|
||||
const normalizedPayload = {
|
||||
commandId,
|
||||
image,
|
||||
@@ -198,6 +210,45 @@ function transientEnvField(value: unknown): RunnerTransientEnv[] {
|
||||
});
|
||||
}
|
||||
|
||||
function assembleToolContextTransientEnv(policy: ExecutionPolicy, provided: RunnerTransientEnv[], defaults: RunnerJobDefaults): RunnerTransientEnv[] {
|
||||
if (!usesUnideskSsh(policy)) return provided;
|
||||
if (provided.some((item) => unideskSshEndpointEnvNameSet.has(item.name))) return provided;
|
||||
const endpoint = defaultUnideskSshEndpointEnv(defaults);
|
||||
if (!endpoint) {
|
||||
throw new AgentRunError("schema-invalid", "unidesk-ssh tool credential requires runner-job transientEnv UNIDESK_MAIN_SERVER_IP, UNIDESK_MAIN_SERVER_HOST, or UNIDESK_FRONTEND_URL", {
|
||||
httpStatus: 400,
|
||||
details: { tool: "unidesk-ssh", requiredEnv: [...unideskSshEndpointEnvNames], valuesPrinted: false },
|
||||
});
|
||||
}
|
||||
return [...provided, endpoint];
|
||||
}
|
||||
|
||||
function usesUnideskSsh(policy: ExecutionPolicy): boolean {
|
||||
return (policy.secretScope.toolCredentials ?? []).some((item) => item.tool === "unidesk-ssh");
|
||||
}
|
||||
|
||||
function defaultUnideskSshEndpointEnv(defaults: RunnerJobDefaults): RunnerTransientEnv | null {
|
||||
const fromDefaults = defaults.unideskSshEndpointEnv;
|
||||
if (fromDefaults !== undefined) return unideskSshEndpointEnvFromRecord(fromDefaults, "runnerJobDefaults.unideskSshEndpointEnv");
|
||||
for (const item of unideskSshEndpointConfigEnvNames) {
|
||||
const value = optionalString(process.env[item.configName]);
|
||||
if (value) return { name: item.targetName, value, sensitive: true };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function unideskSshEndpointEnvFromRecord(record: JsonRecord, fieldName: string): RunnerTransientEnv {
|
||||
const name = stringField(record, "name");
|
||||
validateEnvName(name, `${fieldName}.name`);
|
||||
if (!unideskSshEndpointEnvNameSet.has(name)) {
|
||||
throw new AgentRunError("schema-invalid", `${fieldName}.name must be one of ${unideskSshEndpointEnvNames.join(", ")}`, { httpStatus: 400, details: { requiredEnv: [...unideskSshEndpointEnvNames], valuesPrinted: false } });
|
||||
}
|
||||
const rawValue = record.value;
|
||||
if (typeof rawValue !== "string" || rawValue.length === 0) throw new AgentRunError("schema-invalid", `${fieldName}.value must be a non-empty string`, { httpStatus: 400 });
|
||||
if (Buffer.byteLength(rawValue, "utf8") > 8192) throw new AgentRunError("schema-invalid", `${fieldName}.value is too large`, { httpStatus: 400 });
|
||||
return { name, value: rawValue, sensitive: true };
|
||||
}
|
||||
|
||||
function summarizeToolCredentials(items: Array<{ tool: string; purpose: string | null; secretRef: { namespace?: string; name: string; keys?: string[] }; envName: string; secretKey: string }>, namespace: string): JsonRecord {
|
||||
return {
|
||||
count: items.length,
|
||||
|
||||
Reference in New Issue
Block a user