feat: add v03 secret-plane smoke sync

This commit is contained in:
lyon
2026-06-27 18:00:05 +08:00
parent 6120f7fdfe
commit 4964cdde5f
4 changed files with 124 additions and 2 deletions
+29
View File
@@ -0,0 +1,29 @@
version: 1
kind: hwlab-v03-secret-plane
metadata:
id: hwlab-v03-secret-plane
owner: HWLAB
spec: pikasTech/HWLAB#2234
boundary: D601/v0.3 only
secretPlane:
enabled: true
issue: pikasTech/HWLAB#2234
valuesPrinted: false
store:
kind: ClusterSecretStore
name: hwlab-secret-plane-vault-cluster
refreshInterval: 1m
secrets:
- id: hwlab-secret-plane-smoke
externalSecretName: hwlab-secret-plane-smoke
targetSecretName: hwlab-secret-plane-smoke
purpose: Low-risk D601/v0.3 smoke secret for platform-infra secret-plane integration.
data:
- targetKey: password
remoteRef: hwlab-secret-plane/poc
property: password
consumers:
- serviceId: hwlab-cloud-api
kind: Deployment
injectAs: env
envName: HWLAB_SECRET_PLANE_SMOKE
+2
View File
@@ -328,6 +328,7 @@ lanes:
accessControl:
usersRef: config/hwlab-access-control/users.d601-v03.yaml#spec.users
navProfilesRef: config/hwlab-access-control/nav-profiles.yaml#spec.profiles
secretPlaneRef: config/hwlab-v03/secrets.yaml#secretPlane
workbench:
traceTimeline:
autoExpandRunning: false
@@ -766,6 +767,7 @@ lanes:
HWLAB_WORKBENCH_EMPTY_SESSION_GC_BATCH_SIZE: "100"
HWLAB_WORKBENCH_EMPTY_SESSION_GC_JITTER_MS: "15000"
HWLAB_WORKBENCH_EMPTY_SESSION_GC_FAILURE_BACKOFF_MS: "120000"
HWLAB_SECRET_PLANE_SMOKE: secretRef:hwlab-secret-plane-smoke/password
configMapMounts:
- name: hwpod-preinstalled-specs
configMapName: hwlab-v03-hwpod-preinstalled-specs
+82 -2
View File
@@ -5521,10 +5521,88 @@ function runtimeConfigMapsManifest({ configMaps, namespace, labels, annotations
};
}
function runtimeKustomization({ profile = "dev", includeDeviceAgent = profile === "dev", externalPostgres = false, workbenchRedis = false, runtimeConfigMaps = false } = {}) {
async function runtimeSecretPlaneConfigForProfile(deploy, profile) {
if (!isRuntimeLane(profile)) return null;
const laneConfig = deploy?.lanes?.[profile];
const secretPlane = laneConfig?.secretPlaneRef
? await readConfigRef(laneConfig.secretPlaneRef, `${profile}.secretPlaneRef`)
: laneConfig?.secretPlane;
if (!secretPlane || typeof secretPlane !== "object" || Array.isArray(secretPlane)) return null;
if (secretPlane.enabled !== true) return null;
return cloneJson(secretPlane);
}
function runtimeSecretPlaneManifest({ config, namespace, labels, annotations }) {
const store = config?.store;
assert.ok(store && typeof store === "object" && !Array.isArray(store), "secretPlane.store must be an object");
assert.equal(store.kind, "ClusterSecretStore", "secretPlane.store.kind must be ClusterSecretStore for D601/v0.3");
assert.ok(typeof store.name === "string" && store.name.trim(), "secretPlane.store.name must be set");
const secrets = Array.isArray(config.secrets) ? config.secrets : [];
assert.ok(secrets.length > 0, "secretPlane.secrets must not be empty");
return {
apiVersion: "v1",
kind: "List",
items: secrets.map((secret, index) => runtimeSecretPlaneExternalSecret({ config, secret, index, namespace, labels, annotations, store }))
};
}
function runtimeSecretPlaneExternalSecret({ config, secret, index, namespace, labels, annotations, store }) {
const externalSecretName = requiredSecretPlaneString(secret?.externalSecretName, `secretPlane.secrets[${index}].externalSecretName`);
const targetSecretName = requiredSecretPlaneString(secret?.targetSecretName, `secretPlane.secrets[${index}].targetSecretName`);
const data = Array.isArray(secret?.data) ? secret.data : [];
assert.ok(data.length > 0, `secretPlane.secrets[${index}].data must not be empty`);
const sourceRefs = data.map((item) => requiredSecretPlaneString(item?.remoteRef, `secretPlane.secrets[${index}].data.remoteRef`));
return {
apiVersion: "external-secrets.io/v1",
kind: "ExternalSecret",
metadata: {
name: externalSecretName,
namespace,
labels: {
...labels,
"app.kubernetes.io/name": externalSecretName,
"app.kubernetes.io/component": "external-secret",
"hwlab.pikastech.local/secret-plane": String(config.issue ?? "pikasTech/HWLAB#2234")
},
annotations: {
...annotations,
"hwlab.pikastech.local/source-ref": sourceRefs.join(","),
"hwlab.pikastech.local/values-printed": "false"
}
},
spec: {
refreshInterval: requiredSecretPlaneString(config.refreshInterval, "secretPlane.refreshInterval"),
secretStoreRef: {
name: requiredSecretPlaneString(store.name, "secretPlane.store.name"),
kind: store.kind
},
target: {
name: targetSecretName,
creationPolicy: "Owner"
},
data: data.map((item, itemIndex) => ({
secretKey: requiredSecretPlaneString(item?.targetKey, `secretPlane.secrets[${index}].data[${itemIndex}].targetKey`),
remoteRef: {
key: requiredSecretPlaneString(item?.remoteRef, `secretPlane.secrets[${index}].data[${itemIndex}].remoteRef`),
property: requiredSecretPlaneString(item?.property, `secretPlane.secrets[${index}].data[${itemIndex}].property`)
}
}))
}
};
}
function requiredSecretPlaneString(value, label) {
assert.equal(typeof value, "string", `${label} must be a string`);
const trimmed = value.trim();
assert.ok(trimmed, `${label} must not be empty`);
return trimmed;
}
function runtimeKustomization({ profile = "dev", includeDeviceAgent = profile === "dev", externalPostgres = false, workbenchRedis = false, runtimeConfigMaps = false, externalSecrets = false } = {}) {
const resources = ["namespace.yaml", "services.yaml", "health-contract.yaml", "workloads.yaml", "deepseek-proxy.yaml"];
if (!isRuntimeLane(profile)) resources.splice(1, 0, "code-agent-codex-config.yaml");
if (runtimeConfigMaps) resources.splice(3, 0, "configmaps.yaml");
if (externalSecrets) resources.splice(resources.indexOf("workloads.yaml"), 0, "external-secrets.yaml");
if (isRuntimeLane(profile)) {
if (externalPostgres) resources.push("external-postgres.yaml");
else resources.push("postgres.yaml");
@@ -5666,6 +5744,7 @@ async function plannedFiles(args) {
const externalPostgres = externalPostgresConfigForLane(deploy, profile);
const workbenchRedis = workbenchRuntimeRedisConfigForProfile(deploy, profile);
const runtimeConfigMaps = runtimeConfigMapsForProfile(deploy, profile);
const runtimeSecretPlane = await runtimeSecretPlaneConfigForProfile(deploy, profile);
const profileLabels = { ...baseLabels, "hwlab.pikastech.local/environment": runtimeLabelForProfile(profile), "hwlab.pikastech.local/profile": runtimeLabelForProfile(profile) };
const runtimeNamespace = cloneJson(namespaceTemplate);
runtimeNamespace.metadata.name = namespace;
@@ -5673,12 +5752,13 @@ async function plannedFiles(args) {
annotate(runtimeNamespace.metadata, annotations);
const runtimePath = runtimePathForProfile(profile);
const endpoints = profileEndpoint(args, profile);
putJson(`${runtimePath}/kustomization.yaml`, runtimeKustomization({ profile, includeDeviceAgent, externalPostgres: Boolean(externalPostgres), workbenchRedis: Boolean(workbenchRedis), runtimeConfigMaps: runtimeConfigMaps.length > 0 }));
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}/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 }));
putJson(`${runtimePath}/workloads.yaml`, transformWorkloads({ workloads, deploy, catalog: artifactCatalog, source, sourceBranch: args.sourceBranch, gitReadUrl: args.gitReadUrl, registryPrefix: args.registryPrefix, runtimeEndpoint: endpoints.runtimeEndpoint, webEndpoint: endpoints.webEndpoint, profile, useDeployImages: args.useDeployImages, metricsSidecarSha256 }));
putJson(`${runtimePath}/deepseek-proxy.yaml`, deepSeekProxyManifest({ profile, source, sourceBranch: args.sourceBranch, sourceRepo: args.sourceRepo, gitReadUrl: args.gitReadUrl, deploy, registryPrefix: args.registryPrefix, catalog: artifactCatalog, useDeployImages: args.useDeployImages, metricsSidecarSha256 }));
if (isRuntimeLane(profile) && externalPostgres) putJson(`${runtimePath}/external-postgres.yaml`, externalPostgresManifest({ profile, config: externalPostgres, source }));
+11
View File
@@ -566,6 +566,7 @@ test("v03 render keeps node identity as data instead of generated structure", as
assert.ok(generatedPaths.includes("tekton-v03/pipeline.yaml"));
assert.ok(generatedPaths.includes("runtime-v03/external-postgres.yaml"));
assert.ok(generatedPaths.includes("runtime-v03/configmaps.yaml"));
assert.ok(generatedPaths.includes("runtime-v03/external-secrets.yaml"));
const pipeline = await readFile(path.join(outDir, "tekton-v03", "pipeline.yaml"), "utf8");
assert.match(pipeline, /--external-service-report-dir \/workspace\/source\/service-results/u);
assert.match(pipeline, /--ci-plan-path \/workspace\/source\/affected-services\.json/u);
@@ -577,11 +578,20 @@ test("v03 render keeps node identity as data instead of generated structure", as
const workloads = await readFile(path.join(outDir, "runtime-v03", "workloads.yaml"), "utf8");
const workloadsJson = JSON.parse(workloads);
const configMapsJson = JSON.parse(await readFile(path.join(outDir, "runtime-v03", "configmaps.yaml"), "utf8"));
const externalSecretsJson = JSON.parse(await readFile(path.join(outDir, "runtime-v03", "external-secrets.yaml"), "utf8"));
const configMapNames = (configMapsJson.items ?? []).map((item) => item.metadata?.name).sort();
assert.deepEqual(configMapNames, ["hwlab-v03-hwpod-preinstalled-specs", "hwlab-v03-project-management-bootstrap"]);
const smokeExternalSecret = (externalSecretsJson.items ?? []).find((item) => item.kind === "ExternalSecret" && item.metadata?.name === "hwlab-secret-plane-smoke");
assert.ok(smokeExternalSecret, "expected v03 secret-plane smoke ExternalSecret");
assert.equal(smokeExternalSecret.metadata?.namespace, "hwlab-v03");
assert.equal(smokeExternalSecret.spec?.secretStoreRef?.kind, "ClusterSecretStore");
assert.equal(smokeExternalSecret.spec?.secretStoreRef?.name, "hwlab-secret-plane-vault-cluster");
assert.equal(smokeExternalSecret.spec?.target?.name, "hwlab-secret-plane-smoke");
assert.deepEqual(smokeExternalSecret.spec?.data, [{ secretKey: "password", remoteRef: { key: "hwlab-secret-plane/poc", property: "password" } }]);
const cloudApi = (workloadsJson.items ?? []).find((item) => item.kind === "Deployment" && item.metadata?.name === "hwlab-cloud-api");
const cloudApiContainer = collectContainersFromItem(cloudApi).find((container) => container.name === "hwlab-cloud-api");
const cloudApiEnv = new Map((cloudApiContainer?.env ?? []).map((entry) => [entry.name, entry.value]));
const cloudApiEnvEntries = new Map((cloudApiContainer?.env ?? []).map((entry) => [entry.name, entry]));
assert.equal(cloudApi?.spec?.template?.metadata?.labels?.["hwlab.pikastech.local/source-commit"], sourceRevision);
assert.equal(cloudApi?.spec?.template?.metadata?.labels?.["hwlab.pikastech.local/artifact-source-commit"], sourceRevision);
assert.equal(cloudApi?.spec?.template?.metadata?.annotations?.["hwlab.pikastech.local/source-commit"], sourceRevision);
@@ -591,6 +601,7 @@ test("v03 render keeps node identity as data instead of generated structure", as
assert.equal(cloudApiEnv.get("HWLAB_GITOPS_SOURCE_COMMIT"), sourceRevision);
assert.equal(cloudApiEnv.get("HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT"), sourceRevision);
assert.match(cloudApiEnv.get("HWLAB_ENVIRONMENT_IMAGE") ?? "", /hwlab-cloud-api-env:env-stale/u);
assert.deepEqual(cloudApiEnvEntries.get("HWLAB_SECRET_PLANE_SMOKE")?.valueFrom?.secretKeyRef, { name: "hwlab-secret-plane-smoke", key: "password", optional: true });
assert.ok((cloudApi?.spec?.template?.spec?.volumes ?? []).some((volume) => volume.name === "hwpod-preinstalled-specs" && volume.configMap?.name === "hwlab-v03-hwpod-preinstalled-specs"));
assert.ok((cloudApiContainer?.volumeMounts ?? []).some((mount) => mount.name === "hwpod-preinstalled-specs" && mount.mountPath === "/etc/hwlab/hwpod-specs"));
assert.ok((cloudApiContainer?.env ?? []).some((entry) => entry.name === "HWLAB_HWPOD_SPEC_REGISTRY_DIRS" && entry.value === "/etc/hwlab/hwpod-specs"));