feat: 为 NC01 v0.3 声明 Public Edge 上游

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
root
2026-07-15 13:51:21 +02:00
parent 787da1d3c4
commit 530b005505
5 changed files with 48 additions and 14 deletions
+1 -1
View File
@@ -239,7 +239,7 @@ async function plannedFiles(args) {
putJson(`${runtimePath}/kustomization.yaml`, runtimeKustomization({ profile, includeDeviceAgent, externalPostgres: Boolean(externalPostgres), workbenchRedis: Boolean(workbenchRedis), runtimeConfigMaps: runtimeConfigMaps.length > 0, externalSecrets: Boolean(runtimeSecretPlane) }));
putJson(`${runtimePath}/namespace.yaml`, runtimeNamespace);
if (!isRuntimeLane(profile)) putJson(`${runtimePath}/code-agent-codex-config.yaml`, transformListNamespace(config, namespace, profileLabels, annotations));
putJson(`${runtimePath}/services.yaml`, transformServices({ services, namespace, labels: profileLabels, annotations, profile, deploy }));
putJson(`${runtimePath}/services.yaml`, transformServices({ services, namespace, labels: profileLabels, annotations, profile, deploy, nodeId: args.nodeId }));
putJson(`${runtimePath}/health-contract.yaml`, transformHealthContract(health, namespace, profileLabels, annotations, endpoints.runtimeEndpoint, endpoints.webEndpoint, profile));
if (runtimeConfigMaps.length > 0) putJson(`${runtimePath}/configmaps.yaml`, runtimeConfigMapsManifest({ configMaps: runtimeConfigMaps, namespace, labels: profileLabels, annotations }));
if (runtimeSecretPlane) putJson(`${runtimePath}/external-secrets.yaml`, runtimeSecretPlaneManifest({ config: runtimeSecretPlane, namespace, labels: profileLabels, annotations }));
+26 -1
View File
@@ -1688,7 +1688,7 @@ function transformListNamespace(value, namespace, labels, annotations) {
return result;
}
function transformServices({ services, namespace, labels, annotations, profile = "dev", deploy = null }) {
function transformServices({ services, namespace, labels, annotations, profile = "dev", deploy = null, nodeId = "node" }) {
const observableServiceIds = isRuntimeLane(profile) ? runtimeLaneObservableServiceIdsForDeploy(deploy, profile) : new Set();
const result = transformListNamespace(services, namespace, labels, annotations);
if (result.kind === "List") {
@@ -1699,6 +1699,31 @@ function transformServices({ services, namespace, labels, annotations, profile =
label(item.metadata ??= {}, v02MetricsLabels(serviceId));
upsertV02MetricsPort(item);
}
const nodePublicServices = deploy?.lanes?.[profile]?.publicServices?.nodes?.[nodeId];
assert.ok(nodePublicServices === undefined || Array.isArray(nodePublicServices), `deploy.lanes.${profile}.publicServices.nodes.${nodeId} must be an array`);
for (const service of nodePublicServices ?? []) {
assert.ok(service && typeof service === "object" && !Array.isArray(service), `deploy.lanes.${profile}.publicServices.nodes.${nodeId} entries must be objects`);
assert.ok(typeof service.name === "string" && service.name.length > 0, `deploy.lanes.${profile}.publicServices.nodes.${nodeId}[].name is required`);
assert.ok(service.selector && typeof service.selector === "object" && !Array.isArray(service.selector), `deploy.lanes.${profile}.publicServices.nodes.${nodeId}[].selector is required`);
for (const key of ["port", "targetPort", "nodePort"]) {
assert.ok(Number.isInteger(service[key]) && service[key] > 0, `deploy.lanes.${profile}.publicServices.nodes.${nodeId}[].${key} must be a positive integer`);
}
result.items.push({
apiVersion: "v1",
kind: "Service",
metadata: {
name: service.name,
namespace,
labels: { ...labels, "app.kubernetes.io/name": service.name },
annotations: { ...annotations }
},
spec: {
type: "NodePort",
selector: cloneJson(service.selector),
ports: [{ name: "http", port: service.port, targetPort: service.targetPort, nodePort: service.nodePort }]
}
});
}
}
return result;
}