fix: patch frontend auth resources in place
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success

This commit is contained in:
Codex
2026-07-09 15:48:47 +02:00
parent 9915f28da9
commit ed2c6298fd
+35 -41
View File
@@ -207,8 +207,17 @@ function readAuthMaterial(auth: RuntimeAuthConfig): AuthMaterial {
}
function applyScript(auth: RuntimeAuthConfig, material: AuthMaterial): string {
const manifest = renderManifest(auth, material);
const manifestB64 = Buffer.from(manifest, "utf8").toString("base64");
if (material.username === null || material.password === null || material.fingerprint === null) throw new Error("auth material is incomplete");
const configMapPatch = {
metadata: { annotations: authAnnotations(auth, material) },
data: { [auth.target.usernameKey]: material.username },
};
const secretPatch = {
metadata: { annotations: authAnnotations(auth, material) },
data: { [auth.target.passwordKey]: Buffer.from(material.password, "utf8").toString("base64") },
};
const configMapPatchB64 = Buffer.from(JSON.stringify(configMapPatch), "utf8").toString("base64");
const secretPatchB64 = Buffer.from(JSON.stringify(secretPatch), "utf8").toString("base64");
const summaryB64 = Buffer.from(JSON.stringify({
namespace: auth.target.namespace,
configMapName: auth.target.configMapName,
@@ -224,21 +233,25 @@ function applyScript(auth: RuntimeAuthConfig, material: AuthMaterial): string {
set -u
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
manifest="$tmp/frontend-auth.yaml"
printf '%s' '${manifestB64}' | base64 -d >"$manifest"
kubectl apply --server-side --force-conflicts --field-manager=${fieldManager} -f "$manifest" >"$tmp/apply.out" 2>"$tmp/apply.err"
apply_rc=$?
if [ "$apply_rc" -eq 0 ]; then
cm_patch="$tmp/configmap.patch.json"
secret_patch="$tmp/secret.patch.json"
printf '%s' '${configMapPatchB64}' | base64 -d >"$cm_patch"
printf '%s' '${secretPatchB64}' | base64 -d >"$secret_patch"
kubectl -n ${sh(auth.target.namespace)} patch configmap ${sh(auth.target.configMapName)} --type merge --patch-file "$cm_patch" >"$tmp/configmap.out" 2>"$tmp/configmap.err"
cm_rc=$?
kubectl -n ${sh(auth.target.namespace)} patch secret ${sh(auth.target.secretName)} --type merge --patch-file "$secret_patch" >"$tmp/secret.out" 2>"$tmp/secret.err"
secret_rc=$?
if [ "$cm_rc" -eq 0 ] && [ "$secret_rc" -eq 0 ]; then
kubectl -n ${sh(auth.target.namespace)} rollout restart deployment/${sh(auth.target.rolloutDeployment)} >"$tmp/rollout.out" 2>"$tmp/rollout.err"
rollout_rc=$?
else
: >"$tmp/rollout.out"
printf '%s\\n' 'skipped because apply failed' >"$tmp/rollout.err"
printf '%s\\n' 'skipped because configmap or secret patch failed' >"$tmp/rollout.err"
rollout_rc=1
fi
python3 - "$apply_rc" "$rollout_rc" "$tmp/apply.out" "$tmp/apply.err" "$tmp/rollout.out" "$tmp/rollout.err" <<'PY'
python3 - "$cm_rc" "$secret_rc" "$rollout_rc" "$tmp/configmap.out" "$tmp/configmap.err" "$tmp/secret.out" "$tmp/secret.err" "$tmp/rollout.out" "$tmp/rollout.err" <<'PY'
import base64, json, sys
apply_rc, rollout_rc = int(sys.argv[1]), int(sys.argv[2])
cm_rc, secret_rc, rollout_rc = int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3])
def tail(path, limit=4000):
try:
return open(path, encoding="utf-8", errors="replace").read()[-limit:]
@@ -246,11 +259,12 @@ def tail(path, limit=4000):
return ""
summary = json.loads(base64.b64decode("${summaryB64}").decode("utf-8"))
payload = {
"ok": apply_rc == 0 and rollout_rc == 0,
"ok": cm_rc == 0 and secret_rc == 0 and rollout_rc == 0,
**summary,
"steps": {
"apply": {"exitCode": apply_rc, "stdoutTail": tail(sys.argv[3]), "stderrTail": tail(sys.argv[4])},
"rolloutRestart": {"exitCode": rollout_rc, "stdoutTail": tail(sys.argv[5]), "stderrTail": tail(sys.argv[6])},
"configMapPatch": {"exitCode": cm_rc, "stdoutTail": tail(sys.argv[4]), "stderrTail": tail(sys.argv[5])},
"secretPatch": {"exitCode": secret_rc, "stdoutTail": tail(sys.argv[6]), "stderrTail": tail(sys.argv[7])},
"rolloutRestart": {"exitCode": rollout_rc, "stdoutTail": tail(sys.argv[8]), "stderrTail": tail(sys.argv[9])},
},
"valuesPrinted": False,
}
@@ -331,33 +345,12 @@ PY
`;
}
function renderManifest(auth: RuntimeAuthConfig, material: AuthMaterial): string {
if (material.username === null || material.password === null || material.fingerprint === null) throw new Error("auth material is incomplete");
const annotations = [
` unidesk.ai/source-ref: ${yaml(auth.source.path)}`,
` unidesk.ai/frontend-auth-fingerprint: ${yaml(material.fingerprint)}`,
].join("\n");
return `apiVersion: v1
kind: ConfigMap
metadata:
name: ${auth.target.configMapName}
namespace: ${auth.target.namespace}
annotations:
${annotations}
data:
${auth.target.usernameKey}: ${yaml(material.username)}
---
apiVersion: v1
kind: Secret
metadata:
name: ${auth.target.secretName}
namespace: ${auth.target.namespace}
annotations:
${annotations}
type: Opaque
stringData:
${auth.target.passwordKey}: ${yaml(material.password)}
`;
function authAnnotations(auth: RuntimeAuthConfig, material: AuthMaterial): Record<string, string> {
if (material.fingerprint === null) throw new Error("auth material fingerprint is missing");
return {
"unidesk.ai/source-ref": auth.source.path,
"unidesk.ai/frontend-auth-fingerprint": material.fingerprint,
};
}
function parseAction(value: string): Action {
@@ -462,7 +455,8 @@ function renderApply(result: Record<string, unknown>): RenderedCliResult {
`mode: ${str(result.mode)} mutation: ${str(result.mutation)} ok: ${bool(result.ok)}`,
...table(["STEP", "OK", "DETAIL"], [
["local-source", bool(asRecord(result.localSource, "localSource").fingerprint !== undefined && asRecord(result.localSource, "localSource").fingerprint !== null), str(asRecord(result.localSource, "localSource").sourceRef)],
["apply", bool(asRecord(steps.apply, "steps.apply").exitCode === 0), compact(str(asRecord(steps.apply, "steps.apply").stderrTail, str(asRecord(steps.apply, "steps.apply").stdoutTail)))],
["configmap-patch", bool(asRecord(steps.configMapPatch, "steps.configMapPatch").exitCode === 0), compact(str(asRecord(steps.configMapPatch, "steps.configMapPatch").stderrTail, str(asRecord(steps.configMapPatch, "steps.configMapPatch").stdoutTail)))],
["secret-patch", bool(asRecord(steps.secretPatch, "steps.secretPatch").exitCode === 0), compact(str(asRecord(steps.secretPatch, "steps.secretPatch").stderrTail, str(asRecord(steps.secretPatch, "steps.secretPatch").stdoutTail)))],
["rollout-restart", bool(asRecord(steps.rolloutRestart, "steps.rolloutRestart").exitCode === 0), compact(str(asRecord(steps.rolloutRestart, "steps.rolloutRestart").stdoutTail, str(asRecord(steps.rolloutRestart, "steps.rolloutRestart").stderrTail)))],
["runtime-status", bool(asRecord(result.runtime, "runtime").ok), str(asRecord(result.runtime, "runtime").observedFingerprint)],
]),