4 Commits
Author SHA1 Message Date
chemavxandClaude Opus 5 bd92f5ae9d Distinguir "no se reinicio" de "no pude comprobarlo"
El GET de comprobacion no miraba su propio codigo HTTP. Un 403 devuelve un
objeto Status, que parsea como JSON perfectamente y luego revienta en
dep.spec.replicas ("Cannot read properties of undefined (reading 'replicas')").
El aviso resultante decia "reinicio fallido, intervencion manual necesaria"
cuando el reinicio habia ido BIEN y lo unico roto era la verificacion.

Falso negativo, mucho menos grave que el falso positivo de ayer -- pero te
levanta de la cama para nada, y estando Jose fuera eso importa.

Ahora el nodo marca verificable:false cuando no ha podido comprobar (HTTP no
2xx, cuerpo ilegible o error de red) y el aviso lo dice con esas palabras,
con el codigo de la comprobacion aparte del codigo del PATCH.

Reproducido en produccion: POST legitimo a las 08:43:22 (PATCH ok, restartedAt
cambia), permiso retirado a los 15 s, GET a los 60 s con 403. Ejecucion de
60,394 s, o sea el camino completo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:46:25 +00:00
chemavxandClaude Opus 5 50f090bbea Cerrar el auto-reinicio: fail-closed, permisos por nombre y fallo visible
Tres agujeros que encontro una review adversarial de Codex sobre el trabajo
de ayer. Los tres verificados contra el fichero antes de tocar nada.

1. El webhook publico fallaba en ABIERTO. Con `optional: true` y un
   `if (secreto && ...)`, la ausencia del secreto equivalia a autorizacion:
   cualquier POST con heartbeat.status=0 y un monitor.name del mapa reiniciaba
   n8n, Gitea, ArgoCD, Vaultwarden o los blogs. El argumento para dejarlo asi
   era "que un despiste no te deje sin avisos", y era falso: el aviso de caida
   lo manda Kuma por su notificacion 1, directa, no por este webhook.
   Ahora el secreto es obligatorio (sin `optional`) y la puerta rechaza si
   falta. Secreto ausente da error ruidoso; cabecera que no casa, vacio.

2. El ClusterRole permitia patch sobre CUALQUIER deployment de 10 namespaces,
   y la SA va montada en el pod entero de n8n: cualquier workflow con un nodo
   Code heredaba eso. Ahora son Roles por namespace con resourceNames sobre
   los 12 workloads exactos del SERVICE_MAP.

3. El flujo daba exito aunque el PATCH fallara. `restartOk` se calculaba y se
   tiraba: `K8s API Check Status` construia un objeto nuevo sin el, y el IF
   final solo miraba `statusOk`. Un 403 sobre un servicio ya sano mandaba
   "reiniciado correctamente". Ahora hay rama de fallo tras el PATCH y el
   exito exige observedGeneration >= la generation que devolvio el PATCH.
   Se compara con >= porque selfHeal de ArgoCD revierte la anotacion y vuelve
   a subir la generation; con == daria un fallo falso.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:02:07 +00:00
chemavxandClaude Opus 5 125cdc9de0 n8n: cerrar el webhook del auto-reinicio con un secreto compartido
/webhook/uptime-kuma-restart es publico y sin autenticar. Mientras no reiniciaba
nada daba igual; desde hoy reinicia doce servicios, los dos blogs incluidos, asi
que cualquiera que diera con la ruta podia zarandear el cluster.

Uptime Kuma manda ahora la cabecera X-Kuma-Token (webhookAdditionalHeaders de la
notificacion "n8n Auto-Restart") y el primer nodo Code la compara con
KUMA_WEBHOOK_TOKEN antes de hacer nada.

La comprobacion falla en ABIERTO si el secreto no esta configurado en n8n: un
despiste de configuracion degrada al comportamiento de antes en vez de dejar de
avisar en silencio, que es el fallo que no se ve venir. Si esta configurado y no
coincide, se devuelve vacio: ni reinicio, ni Telegram, ni fila de error que se
pueda llenar a base de peticiones.

El secret n8n-kuma-webhook se crea con kubectl y NO esta en git; el env va con
optional: true para que la ausencia no impida arrancar el pod.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 20:25:17 +00:00
chemavxandClaude Opus 5 cbfbc8bf16 n8n: copia en git del workflow del auto-reinicio
Los workflows viven solo en la SQLite, que ya se revirtio sola una vez (16-jul,
a un snapshot de abril) y se llevo por delante mes y medio de trabajo. Este en
concreto es el que reacciona a las caidas, asi que conviene tenerlo fuera.

Ya no hay nada secreto que ocultar: los tres nodos de Telegram leen el token de
$env.TELEGRAM_BOT_TOKEN en vez de llevarlo incrustado.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 20:19:20 +00:00