feat: add hwlab opencode public proxy config
This commit is contained in:
@@ -282,6 +282,13 @@ export interface HwlabRuntimePublicExposureFrpcProxySpec {
|
||||
readonly remotePort: number;
|
||||
}
|
||||
|
||||
export interface HwlabRuntimePublicExposureFrpcExtraProxySpec extends HwlabRuntimePublicExposureFrpcProxySpec {
|
||||
readonly id: string;
|
||||
readonly hostname?: string;
|
||||
readonly publicBaseUrl?: string;
|
||||
readonly cloudWebEnvName?: string;
|
||||
}
|
||||
|
||||
export interface HwlabRuntimePublicExposureSpec {
|
||||
readonly enabled: boolean;
|
||||
readonly mode: "pk01-caddy-frp";
|
||||
@@ -303,6 +310,7 @@ export interface HwlabRuntimePublicExposureSpec {
|
||||
readonly responseHeaderTimeoutSeconds: number;
|
||||
readonly webProxy: HwlabRuntimePublicExposureFrpcProxySpec;
|
||||
readonly apiProxy: HwlabRuntimePublicExposureFrpcProxySpec;
|
||||
readonly extraProxies: readonly HwlabRuntimePublicExposureFrpcExtraProxySpec[];
|
||||
}
|
||||
|
||||
export interface HwlabRuntimeBootstrapAdminSpec {
|
||||
@@ -1207,6 +1215,32 @@ function publicExposureProxyConfig(value: unknown, path: string): HwlabRuntimePu
|
||||
};
|
||||
}
|
||||
|
||||
function publicExposureExtraProxyConfig(value: unknown, path: string): HwlabRuntimePublicExposureFrpcExtraProxySpec {
|
||||
const raw = asRecord(value, path);
|
||||
const publicBaseUrl = optionalStringField(raw, "publicBaseUrl", path)?.replace(/\/+$/u, "");
|
||||
const hostname = optionalStringField(raw, "hostname", path);
|
||||
if (publicBaseUrl !== undefined) {
|
||||
validatePublicExposureOrigin(publicBaseUrl, `${path}.publicBaseUrl`);
|
||||
if (hostname !== undefined && new URL(publicBaseUrl).hostname !== hostname) throw new Error(`${path}.publicBaseUrl hostname must match ${path}.hostname`);
|
||||
}
|
||||
const cloudWebEnvName = optionalStringField(raw, "cloudWebEnvName", path);
|
||||
if (cloudWebEnvName !== undefined && !/^HWLAB_CLOUD_WEB_[A-Z0-9_]+$/u.test(cloudWebEnvName)) throw new Error(`${path}.cloudWebEnvName must be a HWLAB_CLOUD_WEB_* env name`);
|
||||
if (cloudWebEnvName !== undefined && publicBaseUrl === undefined) throw new Error(`${path}.cloudWebEnvName requires ${path}.publicBaseUrl`);
|
||||
return {
|
||||
id: stringField(raw, "id", path),
|
||||
...publicExposureProxyConfig(value, path),
|
||||
...(hostname === undefined ? {} : { hostname }),
|
||||
...(publicBaseUrl === undefined ? {} : { publicBaseUrl }),
|
||||
...(cloudWebEnvName === undefined ? {} : { cloudWebEnvName }),
|
||||
};
|
||||
}
|
||||
|
||||
function publicExposureExtraProxiesConfig(value: unknown, path: string): HwlabRuntimePublicExposureFrpcExtraProxySpec[] {
|
||||
if (value === undefined) return [];
|
||||
if (!Array.isArray(value)) throw new Error(`${path} must be an array`);
|
||||
return value.map((item, index) => publicExposureExtraProxyConfig(item, `${path}[${index}]`));
|
||||
}
|
||||
|
||||
function publicExposureConfig(value: unknown, path: string): HwlabRuntimePublicExposureSpec | null {
|
||||
if (value === undefined) return null;
|
||||
const raw = asRecord(value, path);
|
||||
@@ -1237,9 +1271,21 @@ function publicExposureConfig(value: unknown, path: string): HwlabRuntimePublicE
|
||||
responseHeaderTimeoutSeconds: numberField(caddy, "responseHeaderTimeoutSeconds", `${path}.caddy`),
|
||||
webProxy: publicExposureProxyConfig(frpc.webProxy, `${path}.frpc.webProxy`),
|
||||
apiProxy: publicExposureProxyConfig(frpc.apiProxy, `${path}.frpc.apiProxy`),
|
||||
extraProxies: publicExposureExtraProxiesConfig(frpc.extraProxies, `${path}.frpc.extraProxies`),
|
||||
};
|
||||
}
|
||||
|
||||
function validatePublicExposureOrigin(publicBaseUrl: string, path: string): void {
|
||||
try {
|
||||
const parsed = new URL(publicBaseUrl);
|
||||
if (parsed.protocol !== "https:") throw new Error("must use https");
|
||||
if (parsed.pathname !== "/" || parsed.search.length > 0 || parsed.hash.length > 0) throw new Error("must point to the public origin root");
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
throw new Error(`${path} must be an https origin root URL: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function observabilityConfig(value: unknown, path: string): HwlabRuntimeObservabilitySpec {
|
||||
const raw = asRecord(value, path);
|
||||
const recordingRules = observabilityRecordingRulesConfig(raw.recordingRules, `${path}.recordingRules`);
|
||||
|
||||
@@ -455,6 +455,7 @@ export function publicExposureSummary(exposure: HwlabRuntimePublicExposureSpec):
|
||||
tokenKey: exposure.tokenKey,
|
||||
webProxy: exposure.webProxy,
|
||||
apiProxy: exposure.apiProxy,
|
||||
extraProxies: exposure.extraProxies,
|
||||
},
|
||||
caddy: {
|
||||
route: exposure.caddyRoute,
|
||||
@@ -982,7 +983,7 @@ export function publicExposureCaddyScript(options: NodePublicExposureOptions, ex
|
||||
|
||||
export function publicExposureCaddyBlock(exposure: HwlabRuntimePublicExposureSpec): string {
|
||||
const tlsLines = exposure.caddyTls === "internal" ? " tls internal\n" : "";
|
||||
return `${exposure.hostname} {
|
||||
const mainBlock = `${exposure.hostname} {
|
||||
${tlsLines} @api path /health* /auth* /v1* /json-rpc* /openapi* /docs* /swagger*
|
||||
reverse_proxy @api 127.0.0.1:${exposure.apiProxy.remotePort} {
|
||||
transport http {
|
||||
@@ -995,6 +996,16 @@ ${tlsLines} @api path /health* /auth* /v1* /json-rpc* /openapi* /docs* /swagg
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const extraBlocks = exposure.extraProxies
|
||||
.filter((proxy) => proxy.hostname !== undefined)
|
||||
.map((proxy) => `${proxy.hostname} {
|
||||
${tlsLines} reverse_proxy 127.0.0.1:${proxy.remotePort} {
|
||||
transport http {
|
||||
response_header_timeout ${exposure.responseHeaderTimeoutSeconds}s
|
||||
}
|
||||
}
|
||||
}`);
|
||||
return [mainBlock, ...extraBlocks].join("\n\n");
|
||||
}
|
||||
|
||||
export function runTransScript(node: string, script: string, input: string, timeoutSeconds: number): CommandResult {
|
||||
|
||||
@@ -1503,6 +1503,11 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
"function isEnvReuseContainer(container) { return envValue(container, 'HWLAB_RUNTIME_MODE') === 'env-reuse-git-mirror-checkout' || envValue(container, 'HWLAB_BOOT_SH') !== undefined || envValue(container, 'HWLAB_BOOT_COMMIT') !== undefined; }",
|
||||
"function workloadName(item) { return item && item.metadata && item.metadata.labels && item.metadata.labels['app.kubernetes.io/name'] ? String(item.metadata.labels['app.kubernetes.io/name']) : String(item && item.metadata && item.metadata.name || ''); }",
|
||||
"function expectedPublicEndpoint(item) { return workloadName(item) === 'hwlab-cloud-web' ? overlay.publicWebUrl : overlay.publicApiUrl; }",
|
||||
"function publicExposureCloudWebEnvEntries() {",
|
||||
" const exposure = overlay.publicExposure;",
|
||||
" if (!exposure || !Array.isArray(exposure.extraProxies)) return [];",
|
||||
" return exposure.extraProxies.filter((proxy) => proxy && proxy.cloudWebEnvName && proxy.publicBaseUrl).map((proxy) => ({ name: String(proxy.cloudWebEnvName), value: String(proxy.publicBaseUrl) }));",
|
||||
"}",
|
||||
"function startupProbeFrom(probe) {",
|
||||
" const next = JSON.parse(JSON.stringify(probe));",
|
||||
" next.periodSeconds = 10;",
|
||||
@@ -1561,17 +1566,22 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" return changed;",
|
||||
"}",
|
||||
"function patchRuntimeEnv(item, podSpec) {",
|
||||
" if (!isObject(podSpec)) return { publicEndpointChanged: false, dbSslModeChanged: false, codeAgentRuntimeChanged: false };",
|
||||
" if (!isObject(podSpec)) return { publicEndpointChanged: false, dbSslModeChanged: false, codeAgentRuntimeChanged: false, cloudWebRuntimeChanged: false };",
|
||||
" let publicEndpointChanged = false;",
|
||||
" let dbSslModeChanged = false;",
|
||||
" let codeAgentRuntimeChanged = false;",
|
||||
" let cloudWebRuntimeChanged = false;",
|
||||
" const pg = overlay.externalPostgres;",
|
||||
" const codeAgentRuntime = overlay.codeAgentRuntime;",
|
||||
" const cloudWebEnvEntries = publicExposureCloudWebEnvEntries();",
|
||||
" for (const group of ['containers', 'initContainers']) {",
|
||||
" for (const container of Array.isArray(podSpec[group]) ? podSpec[group] : []) {",
|
||||
" if (!isObject(container)) continue;",
|
||||
" if (envValue(container, 'HWLAB_PUBLIC_ENDPOINT') !== undefined) publicEndpointChanged = setEnvValue(container, 'HWLAB_PUBLIC_ENDPOINT', expectedPublicEndpoint(item)) || publicEndpointChanged;",
|
||||
" if (pg && pg.sslmode && envValue(container, 'HWLAB_CLOUD_DB_SSL_MODE') !== undefined) dbSslModeChanged = setEnvValue(container, 'HWLAB_CLOUD_DB_SSL_MODE', pg.sslmode) || dbSslModeChanged;",
|
||||
" if (workloadName(item) === 'hwlab-cloud-web' && container.name === 'hwlab-cloud-web') {",
|
||||
" for (const env of cloudWebEnvEntries) cloudWebRuntimeChanged = setEnvValue(container, env.name, env.value) || cloudWebRuntimeChanged;",
|
||||
" }",
|
||||
" if (codeAgentRuntime && codeAgentRuntime.enabled && workloadName(item) === 'hwlab-cloud-api' && container.name === 'hwlab-cloud-api') {",
|
||||
" codeAgentRuntimeChanged = setEnvValue(container, 'HWLAB_CODE_AGENT_ADAPTER', String(codeAgentRuntime.adapter)) || codeAgentRuntimeChanged;",
|
||||
" codeAgentRuntimeChanged = setEnvValue(container, 'AGENTRUN_MGR_URL', String(codeAgentRuntime.managerUrl)) || codeAgentRuntimeChanged;",
|
||||
@@ -1593,7 +1603,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" }",
|
||||
" }",
|
||||
" }",
|
||||
" return { publicEndpointChanged, dbSslModeChanged, codeAgentRuntimeChanged };",
|
||||
" return { publicEndpointChanged, dbSslModeChanged, codeAgentRuntimeChanged, cloudWebRuntimeChanged };",
|
||||
"}",
|
||||
"function patchRuntimeWorkloads() {",
|
||||
" let observabilityChanged = false;",
|
||||
@@ -1628,15 +1638,16 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" changed = gitUrlChanged || changed;",
|
||||
" gitReadUrlChanged = gitReadUrlChanged || gitUrlChanged;",
|
||||
" const envChanged = patchRuntimeEnv(item, podSpecFor(item));",
|
||||
" changed = envChanged.publicEndpointChanged || envChanged.dbSslModeChanged || envChanged.codeAgentRuntimeChanged || changed;",
|
||||
" changed = envChanged.publicEndpointChanged || envChanged.dbSslModeChanged || envChanged.codeAgentRuntimeChanged || envChanged.cloudWebRuntimeChanged || changed;",
|
||||
" publicEndpointChanged = publicEndpointChanged || envChanged.publicEndpointChanged;",
|
||||
" dbSslModeChanged = dbSslModeChanged || envChanged.dbSslModeChanged;",
|
||||
" codeAgentRuntimeChanged = codeAgentRuntimeChanged || envChanged.codeAgentRuntimeChanged;",
|
||||
" cloudWebRuntimeChanged = cloudWebRuntimeChanged || envChanged.cloudWebRuntimeChanged;",
|
||||
" }",
|
||||
" }",
|
||||
" if (changed) writeYamlDocuments(file, docs);",
|
||||
" }",
|
||||
" return { observabilityChanged, startupProbeChanged, imageRewriteChanged, gitReadUrlChanged, publicEndpointChanged, dbSslModeChanged, codeAgentRuntimeChanged };",
|
||||
" return { observabilityChanged, startupProbeChanged, imageRewriteChanged, gitReadUrlChanged, publicEndpointChanged, dbSslModeChanged, codeAgentRuntimeChanged, cloudWebRuntimeChanged };",
|
||||
"}",
|
||||
"function patchKustomization() {",
|
||||
" const file = path.join(runtimePath, 'kustomization.yaml');",
|
||||
@@ -1722,6 +1733,18 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" if (changed) writeYaml(file, normalizeList(items));",
|
||||
" return changed;",
|
||||
"}",
|
||||
"function publicExposureFrpcProxies(exposure) { return [exposure.webProxy, exposure.apiProxy, ...(Array.isArray(exposure.extraProxies) ? exposure.extraProxies : [])].filter(Boolean); }",
|
||||
"function renderPublicExposureFrpcProxyToml(proxy) {",
|
||||
" return [",
|
||||
" '[[proxies]]',",
|
||||
" 'name = ' + JSON.stringify(String(proxy.name)),",
|
||||
" 'type = \"tcp\"',",
|
||||
" 'localIP = ' + JSON.stringify(String(proxy.localIP)),",
|
||||
" 'localPort = ' + Number(proxy.localPort),",
|
||||
" 'remotePort = ' + Number(proxy.remotePort),",
|
||||
" '',",
|
||||
" ];",
|
||||
"}",
|
||||
"function renderPublicExposureFrpcToml(exposure) {",
|
||||
" return [",
|
||||
" 'serverAddr = ' + JSON.stringify(String(exposure.serverAddr)),",
|
||||
@@ -1729,20 +1752,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" 'loginFailExit = true',",
|
||||
" 'auth.token = \"{{ .Envs.HWLAB_FRP_TOKEN }}\"',",
|
||||
" '',",
|
||||
" '[[proxies]]',",
|
||||
" 'name = ' + JSON.stringify(String(exposure.webProxy.name)),",
|
||||
" 'type = \"tcp\"',",
|
||||
" 'localIP = ' + JSON.stringify(String(exposure.webProxy.localIP)),",
|
||||
" 'localPort = ' + Number(exposure.webProxy.localPort),",
|
||||
" 'remotePort = ' + Number(exposure.webProxy.remotePort),",
|
||||
" '',",
|
||||
" '[[proxies]]',",
|
||||
" 'name = ' + JSON.stringify(String(exposure.apiProxy.name)),",
|
||||
" 'type = \"tcp\"',",
|
||||
" 'localIP = ' + JSON.stringify(String(exposure.apiProxy.localIP)),",
|
||||
" 'localPort = ' + Number(exposure.apiProxy.localPort),",
|
||||
" 'remotePort = ' + Number(exposure.apiProxy.remotePort),",
|
||||
" '',",
|
||||
" ...publicExposureFrpcProxies(exposure).flatMap(renderPublicExposureFrpcProxyToml),",
|
||||
" ].join('\\\\n');",
|
||||
"}",
|
||||
"function setEnvFromSecret(container, name, secretName, secretKey) {",
|
||||
@@ -1800,7 +1810,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" process.exit(50);",
|
||||
" }",
|
||||
" if (changed) writeYamlDocuments(file, docs);",
|
||||
" console.error(JSON.stringify({ event: 'unidesk-public-exposure-postprocess', ok: true, applied: true, changed, filePath: file, hostname: exposure.hostname, serverAddr: exposure.serverAddr, serverPort: exposure.serverPort, webProxy: exposure.webProxy.name, apiProxy: exposure.apiProxy.name, configSha256: crypto.createHash('sha256').update(toml).digest('hex') }));",
|
||||
" console.error(JSON.stringify({ event: 'unidesk-public-exposure-postprocess', ok: true, applied: true, changed, filePath: file, hostname: exposure.hostname, serverAddr: exposure.serverAddr, serverPort: exposure.serverPort, webProxy: exposure.webProxy.name, apiProxy: exposure.apiProxy.name, extraProxyCount: Array.isArray(exposure.extraProxies) ? exposure.extraProxies.length : 0, configSha256: crypto.createHash('sha256').update(toml).digest('hex') }));",
|
||||
" return { configured: true, changed, foundConfigMap, foundDeployment };",
|
||||
"}",
|
||||
"const kustomizationChanged = patchKustomization();",
|
||||
@@ -1808,7 +1818,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
"const externalPostgresChanged = patchExternalPostgres();",
|
||||
"const healthContractChanged = patchHealthContract();",
|
||||
"const publicExposureChanged = patchPublicExposure();",
|
||||
"console.error(JSON.stringify({ event: 'unidesk-runtime-gitops-postprocess', ok: true, runtimePath, sourcePath, pathRelocated: sourcePath !== runtimePath, observabilityPrometheusOperator: overlay.observability ? overlay.observability.prometheusOperator : null, runtimeImageRewriteCount: (overlay.runtimeImageRewrites || []).length, kustomizationChanged, observabilityWorkloadsChanged: runtimeWorkloadsChanged.observabilityChanged, startupProbeChanged: runtimeWorkloadsChanged.startupProbeChanged, runtimeImageRewriteChanged: runtimeWorkloadsChanged.imageRewriteChanged, gitReadUrlChanged: runtimeWorkloadsChanged.gitReadUrlChanged, publicEndpointChanged: runtimeWorkloadsChanged.publicEndpointChanged, dbSslModeChanged: runtimeWorkloadsChanged.dbSslModeChanged, codeAgentRuntimeChanged: runtimeWorkloadsChanged.codeAgentRuntimeChanged, externalPostgresChanged, healthContractChanged, publicExposureChanged }));",
|
||||
"console.error(JSON.stringify({ event: 'unidesk-runtime-gitops-postprocess', ok: true, runtimePath, sourcePath, pathRelocated: sourcePath !== runtimePath, observabilityPrometheusOperator: overlay.observability ? overlay.observability.prometheusOperator : null, runtimeImageRewriteCount: (overlay.runtimeImageRewrites || []).length, kustomizationChanged, observabilityWorkloadsChanged: runtimeWorkloadsChanged.observabilityChanged, startupProbeChanged: runtimeWorkloadsChanged.startupProbeChanged, runtimeImageRewriteChanged: runtimeWorkloadsChanged.imageRewriteChanged, gitReadUrlChanged: runtimeWorkloadsChanged.gitReadUrlChanged, publicEndpointChanged: runtimeWorkloadsChanged.publicEndpointChanged, dbSslModeChanged: runtimeWorkloadsChanged.dbSslModeChanged, codeAgentRuntimeChanged: runtimeWorkloadsChanged.codeAgentRuntimeChanged, cloudWebRuntimeChanged: runtimeWorkloadsChanged.cloudWebRuntimeChanged, externalPostgresChanged, healthContractChanged, publicExposureChanged }));",
|
||||
"NODE_UNIDESK_RUNTIME_GITOPS_POSTPROCESS`;",
|
||||
"}",
|
||||
"function runtimeGitopsVerifyScript() {",
|
||||
@@ -1870,6 +1880,11 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
"function isEnvReuseContainer(container) { return envValue(container, 'HWLAB_RUNTIME_MODE') === 'env-reuse-git-mirror-checkout' || envValue(container, 'HWLAB_BOOT_SH') !== undefined || envValue(container, 'HWLAB_BOOT_COMMIT') !== undefined; }",
|
||||
"function workloadName(item) { return item && item.metadata && item.metadata.labels && item.metadata.labels['app.kubernetes.io/name'] ? String(item.metadata.labels['app.kubernetes.io/name']) : String(item && item.metadata && item.metadata.name || ''); }",
|
||||
"function expectedPublicEndpoint(item) { return workloadName(item) === 'hwlab-cloud-web' ? overlay.publicWebUrl : overlay.publicApiUrl; }",
|
||||
"function publicExposureCloudWebEnvEntries() {",
|
||||
" const exposure = overlay.publicExposure;",
|
||||
" if (!exposure || !Array.isArray(exposure.extraProxies)) return [];",
|
||||
" return exposure.extraProxies.filter((proxy) => proxy && proxy.cloudWebEnvName && proxy.publicBaseUrl).map((proxy) => ({ name: String(proxy.cloudWebEnvName), value: String(proxy.publicBaseUrl) }));",
|
||||
"}",
|
||||
"function workloadRef(item, file, container) { return { file, kind: item && item.kind, name: item && item.metadata && item.metadata.name, container: container && container.name }; }",
|
||||
"function workloadChecks() {",
|
||||
" const metricsRefs = [];",
|
||||
@@ -1879,8 +1894,14 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" const wrongPublicEndpoints = [];",
|
||||
" const wrongDbSslModes = [];",
|
||||
" const wrongCodeAgentRuntimeEnvs = [];",
|
||||
" const wrongCloudWebRuntimeEnvs = [];",
|
||||
" const rewriteSources = new Set((overlay.runtimeImageRewrites || []).map((item) => item && item.source).filter(Boolean));",
|
||||
" const codeAgentRuntime = overlay.codeAgentRuntime;",
|
||||
" const cloudWebEnvEntries = publicExposureCloudWebEnvEntries();",
|
||||
" function checkCloudWebRuntimeValue(item, file, container, envName, expected) {",
|
||||
" const value = envValue(container, envName);",
|
||||
" if (value !== expected) wrongCloudWebRuntimeEnvs.push({ ...workloadRef(item, file, container), envName, expected, value: value ?? null });",
|
||||
" }",
|
||||
" function checkCodeAgentRuntimeValue(item, file, container, envName, expected) {",
|
||||
" const value = envValue(container, envName);",
|
||||
" if (value !== expected) wrongCodeAgentRuntimeEnvs.push({ ...workloadRef(item, file, container), envName, kind: 'value', expected, value: value ?? null });",
|
||||
@@ -1905,6 +1926,9 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" if (publicEndpoint !== undefined && publicEndpoint !== expectedPublicEndpoint(item)) wrongPublicEndpoints.push({ ...workloadRef(item, file, container), value: publicEndpoint, expected: expectedPublicEndpoint(item) });",
|
||||
" const dbSslMode = envValue(container, 'HWLAB_CLOUD_DB_SSL_MODE');",
|
||||
" if (overlay.externalPostgres && overlay.externalPostgres.sslmode && dbSslMode !== undefined && dbSslMode !== overlay.externalPostgres.sslmode) wrongDbSslModes.push({ ...workloadRef(item, file, container), value: dbSslMode, expected: overlay.externalPostgres.sslmode });",
|
||||
" if (workloadName(item) === 'hwlab-cloud-web' && container.name === 'hwlab-cloud-web') {",
|
||||
" for (const env of cloudWebEnvEntries) checkCloudWebRuntimeValue(item, file, container, env.name, env.value);",
|
||||
" }",
|
||||
" if (codeAgentRuntime && codeAgentRuntime.enabled && workloadName(item) === 'hwlab-cloud-api' && container.name === 'hwlab-cloud-api') {",
|
||||
" checkCodeAgentRuntimeValue(item, file, container, 'HWLAB_CODE_AGENT_ADAPTER', String(codeAgentRuntime.adapter));",
|
||||
" checkCodeAgentRuntimeValue(item, file, container, 'AGENTRUN_MGR_URL', String(codeAgentRuntime.managerUrl));",
|
||||
@@ -1929,7 +1953,7 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" }",
|
||||
" }",
|
||||
" }",
|
||||
" return { metricsRefs, missingStartupProbes, publicRuntimeImages, staleGitReadUrls, wrongPublicEndpoints, wrongDbSslModes, wrongCodeAgentRuntimeEnvs };",
|
||||
" return { metricsRefs, missingStartupProbes, publicRuntimeImages, staleGitReadUrls, wrongPublicEndpoints, wrongDbSslModes, wrongCodeAgentRuntimeEnvs, wrongCloudWebRuntimeEnvs };",
|
||||
"}",
|
||||
"const checks = [];",
|
||||
"const workloadCheck = workloadChecks();",
|
||||
@@ -1953,6 +1977,8 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
"if (overlay.externalPostgres && overlay.externalPostgres.sslmode) checks.push('runtime-db-ssl-mode');",
|
||||
"if (workloadCheck.wrongCodeAgentRuntimeEnvs.length > 0) fail('code-agent-runtime-env-mismatch', { refs: workloadCheck.wrongCodeAgentRuntimeEnvs.slice(0, 12), count: workloadCheck.wrongCodeAgentRuntimeEnvs.length });",
|
||||
"if (overlay.codeAgentRuntime && overlay.codeAgentRuntime.enabled) checks.push('code-agent-runtime-env');",
|
||||
"if (workloadCheck.wrongCloudWebRuntimeEnvs.length > 0) fail('cloud-web-runtime-env-mismatch', { refs: workloadCheck.wrongCloudWebRuntimeEnvs.slice(0, 12), count: workloadCheck.wrongCloudWebRuntimeEnvs.length });",
|
||||
"if (publicExposureCloudWebEnvEntries().length > 0) checks.push('cloud-web-runtime-env');",
|
||||
"const pg = overlay.externalPostgres;",
|
||||
"if (pg && pg.serviceName) {",
|
||||
" const access = pg.runtimeAccess || { endpointAddress: pg.endpointAddress, port: pg.port };",
|
||||
@@ -1994,7 +2020,8 @@ export function nodeRuntimePipelinePostprocessScript(): string[] {
|
||||
" if (!deployment) fail('public-exposure-frpc-deployment-missing', { expected: deploymentName });",
|
||||
" const toml = configMap.data && configMap.data[configKey];",
|
||||
" if (typeof toml !== 'string') fail('public-exposure-frpc-config-missing', { expectedKey: configKey });",
|
||||
" for (const expected of [String(exposure.serverAddr), String(exposure.serverPort), String(exposure.webProxy.name), String(exposure.webProxy.remotePort), String(exposure.apiProxy.name), String(exposure.apiProxy.remotePort), 'HWLAB_FRP_TOKEN']) {",
|
||||
" const expectedProxyTokens = [exposure.webProxy, exposure.apiProxy, ...(Array.isArray(exposure.extraProxies) ? exposure.extraProxies : [])].flatMap((proxy) => [String(proxy.name), String(proxy.remotePort)]);",
|
||||
" for (const expected of [String(exposure.serverAddr), String(exposure.serverPort), ...expectedProxyTokens, 'HWLAB_FRP_TOKEN']) {",
|
||||
" if (!toml.includes(expected)) fail('public-exposure-frpc-config-mismatch', { expected });",
|
||||
" }",
|
||||
" const podSpec = podSpecFor(deployment);",
|
||||
|
||||
Reference in New Issue
Block a user