110 lines
3.6 KiB
JavaScript
110 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
|
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const namespace = "hwlab-dev";
|
|
const expected = Object.freeze({
|
|
"hwlab-box-simu": {
|
|
replicas: 2,
|
|
env: {
|
|
HWLAB_BOX_ID: ["boxsimu_1", "boxsimu_2"]
|
|
}
|
|
},
|
|
"hwlab-gateway-simu": {
|
|
replicas: 2,
|
|
env: {
|
|
HWLAB_BOX_RESOURCES: ["res_boxsimu_1", "res_boxsimu_2"]
|
|
}
|
|
},
|
|
"hwlab-patch-panel": {
|
|
replicas: 1,
|
|
env: {}
|
|
}
|
|
});
|
|
|
|
async function readJson(relativePath) {
|
|
const raw = await readFile(path.join(repoRoot, relativePath), "utf8");
|
|
return JSON.parse(raw);
|
|
}
|
|
|
|
function listItems(document) {
|
|
return document?.kind === "List" ? document.items ?? [] : [document];
|
|
}
|
|
|
|
function envMap(env = []) {
|
|
return Object.fromEntries(env.map((item) => [item.name, item.value ?? ""]));
|
|
}
|
|
|
|
function splitList(value) {
|
|
return String(value ?? "")
|
|
.split(",")
|
|
.map((item) => item.trim())
|
|
.filter(Boolean);
|
|
}
|
|
|
|
function assertSameMembers(actual, required, label) {
|
|
assert.deepEqual([...actual].sort(), [...required].sort(), label);
|
|
}
|
|
|
|
function workloadByName(workloads) {
|
|
return new Map(
|
|
listItems(workloads)
|
|
.filter((item) => item?.kind === "Deployment")
|
|
.map((item) => [item.metadata?.name, item])
|
|
);
|
|
}
|
|
|
|
function assertDevK8sCardinality(workloads) {
|
|
const byName = workloadByName(workloads);
|
|
|
|
for (const [serviceId, requirement] of Object.entries(expected)) {
|
|
const deployment = byName.get(serviceId);
|
|
assert.ok(deployment, `deploy/k8s/base/workloads.yaml missing ${serviceId} Deployment`);
|
|
assert.equal(deployment.metadata?.namespace, namespace, `${serviceId} namespace`);
|
|
assert.equal(deployment.spec?.replicas, requirement.replicas, `${serviceId} replicas`);
|
|
|
|
const labels = deployment.metadata?.labels ?? {};
|
|
assert.equal(labels["hwlab.pikastech.local/service-id"], serviceId, `${serviceId} service label`);
|
|
|
|
const container = deployment.spec?.template?.spec?.containers?.find((item) => item.name === serviceId);
|
|
assert.ok(container, `${serviceId} container`);
|
|
const env = envMap(container.env);
|
|
|
|
for (const [name, values] of Object.entries(requirement.env)) {
|
|
assertSameMembers(splitList(env[name]), values, `${serviceId} ${name}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
function assertDeployManifestCardinality(deploy) {
|
|
assert.equal(deploy.environment, "dev", "deploy/deploy.json environment");
|
|
assert.equal(deploy.namespace, namespace, "deploy/deploy.json namespace");
|
|
assert.equal(deploy.profiles?.prod?.enabled, false, "deploy/deploy.json prod disabled");
|
|
|
|
const byId = new Map((deploy.services ?? []).map((service) => [service.serviceId, service]));
|
|
for (const [serviceId, requirement] of Object.entries(expected)) {
|
|
const service = byId.get(serviceId);
|
|
assert.ok(service, `deploy/deploy.json missing ${serviceId}`);
|
|
assert.equal(service.namespace, namespace, `${serviceId} deploy namespace`);
|
|
assert.equal(service.profile, "dev", `${serviceId} deploy profile`);
|
|
assert.equal(service.replicas, requirement.replicas, `${serviceId} deploy replicas`);
|
|
|
|
for (const [name, values] of Object.entries(requirement.env)) {
|
|
assertSameMembers(splitList(service.env?.[name]), values, `${serviceId} deploy ${name}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
const [deploy, workloads] = await Promise.all([
|
|
readJson("deploy/deploy.json"),
|
|
readJson("deploy/k8s/base/workloads.yaml")
|
|
]);
|
|
|
|
assertDeployManifestCardinality(deploy);
|
|
assertDevK8sCardinality(workloads);
|
|
|
|
console.log("validated DEV M3 manifest cardinality: 2 box-simu, 2 gateway-simu, 1 patch-panel");
|