fix: patch frontend auth resources in place
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success
This commit is contained in:
@@ -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)],
|
||||
]),
|
||||
|
||||
Reference in New Issue
Block a user