Merge pull request #377 from pikasTech/ymalops-round17

ymal-first Round 17: align Sub2API replicas with YAML
This commit is contained in:
Lyon
2026-06-14 14:31:37 +08:00
committed by GitHub
+8 -8
View File
@@ -577,8 +577,8 @@ function parseTargets(root: Record<string, unknown>, defaultTargetId: string): S
if (!/^[A-Za-z0-9._-]+$/u.test(id)) throw new Error(`${configPath}.${path}.id must be a simple target id`); if (!/^[A-Za-z0-9._-]+$/u.test(id)) throw new Error(`${configPath}.${path}.id must be a simple target id`);
if (!/^[A-Za-z0-9:_./-]+$/u.test(route)) throw new Error(`${configPath}.${path}.route has an unsupported format`); if (!/^[A-Za-z0-9:_./-]+$/u.test(route)) throw new Error(`${configPath}.${path}.route has an unsupported format`);
if (!isKubernetesName(targetNamespace)) throw new Error(`${configPath}.${path}.namespace must be a Kubernetes namespace name`); if (!isKubernetesName(targetNamespace)) throw new Error(`${configPath}.${path}.namespace must be a Kubernetes namespace name`);
if (appReplicas < 0 || appReplicas > 1) throw new Error(`${configPath}.${path}.appReplicas must be 0 or 1`); if (appReplicas < 0) throw new Error(`${configPath}.${path}.appReplicas must be >= 0`);
if (redisReplicas < 0 || redisReplicas > 1) throw new Error(`${configPath}.${path}.redisReplicas must be 0 or 1`); if (redisReplicas < 0) throw new Error(`${configPath}.${path}.redisReplicas must be >= 0`);
return { id, route, namespace: targetNamespace, role, enabled, databaseMode, redisMode, appReplicas, redisReplicas, image, dependencyImages, publicExposure, egressProxy }; return { id, route, namespace: targetNamespace, role, enabled, databaseMode, redisMode, appReplicas, redisReplicas, image, dependencyImages, publicExposure, egressProxy };
}); });
const ids = new Set<string>(); const ids = new Set<string>();
@@ -1906,16 +1906,16 @@ function policyChecks(sub2api: Sub2ApiConfig, yaml: string, target: Sub2ApiTarge
if (target.databaseMode === "external-pending") { if (target.databaseMode === "external-pending") {
checks.push( checks.push(
{ {
name: "pending-db-app-scaled-to-zero", name: "pending-db-replicas-match-yaml",
ok: target.appReplicas === 0 && target.redisReplicas === 0 && hasDeploymentReplicas(yaml, serviceName, 0) && hasDeploymentReplicas(yaml, redisService, 0), ok: hasDeploymentReplicas(yaml, serviceName, target.appReplicas) && hasDeploymentReplicas(yaml, redisService, target.redisReplicas),
detail: "External-pending predeployment keeps the Sub2API app and local Redis cache at replicas=0 until the external DB secret, endpoint, and runtime images are ready.", detail: `External-pending predeployment renders YAML-declared app/Redis replicas ${target.appReplicas}/${target.redisReplicas}.`,
}, },
); );
} else if (target.databaseMode === "external-active") { } else if (target.databaseMode === "external-active") {
checks.push({ checks.push({
name: "external-active-app-and-redis-running", name: "external-active-replicas-match-yaml",
ok: target.appReplicas === 1 && target.redisReplicas === 1 && hasDeploymentReplicas(yaml, serviceName, 1) && hasDeploymentReplicas(yaml, redisService, 1), ok: hasDeploymentReplicas(yaml, serviceName, target.appReplicas) && hasDeploymentReplicas(yaml, redisService, target.redisReplicas),
detail: "External-active targets run one Sub2API app replica and one local ephemeral Redis cache replica against the external PostgreSQL runtime.", detail: `External-active targets render YAML-declared app/Redis replicas ${target.appReplicas}/${target.redisReplicas} against the external PostgreSQL runtime.`,
}); });
} else { } else {
checks.push({ checks.push({