Files
k8s-manifests/tools/README.md
T
chemavxandClaude Opus 4.8 07c872e847 tools: auditor de exports contra el cluster
Deja en el repo lo que hoy destapó que argocd-redis, el daemon.json de gitea y
siete imágenes llevaban meses diciendo una cosa mientras el cluster hacía otra.

Compara cada manifiesto con el objeto vivo, en las dos direcciones (el fichero
afirma algo falso / hay algo desplegado que el fichero no menciona / el objeto no
existe). Sólo mira los directorios fuera de ArgoCD, que es donde no hay nadie
comprobando: en los demás ArgoCD ya marca OutOfSync cada 3 minutos. La lista de
directorios se deduce preguntando a ArgoCD por los paths de sus Applications, así
que si mañana un namespace entra en GitOps el script se ajusta solo.

Las excepciones conocidas van en excepciones-auditoria.yaml CON su motivo, para
que lo normal sea "hallazgos NUEVOS: 0" y cualquier cosa que asome merezca una
mirada. Un informe que siempre saca ruido deja de leerse — que es justo el fallo
que se ha estado corrigiendo estos días. El script también avisa cuando una
excepción ya no se dispara: se arregló y la entrada sobra.

Probado viéndolo fallar, no sólo pasar: inyectadas a propósito una avería de cada
tipo (imagen cambiada, env borrada del fichero, objeto inexistente) y las caza
las tres saliendo con código 1. Al probarlo apareció un fallo propio: con -d
marcaba como sobrantes las excepciones de los directorios no barridos; ahora sólo
lo afirma tras un barrido completo.

No toca nada (sólo lectura), nunca compara valores de Secret —sólo nombres de
clave— y se salta lo que ignora .gitignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 09:37:05 +00:00

2.9 KiB

tools/

audita-exports.py — ¿miente este repo?

Compara cada manifiesto con el objeto que hay desplegado de verdad.

python3 tools/audita-exports.py            # informe (sale 1 si hay algo nuevo)
python3 tools/audita-exports.py -v         # incluye las excepciones y su motivo
python3 tools/audita-exports.py -d gitea   # sólo esos directorios

Por qué existe

Sólo mira los directorios que no gestiona ArgoCD. En los que sí, ArgoCD ya compara git contra el cluster cada 3 minutos y lo marca OutOfSync; ahí la deriva no puede esconderse. En los demás —monitoring, argocd, authentik, gitea, homarr, vaultwarden, cloudflare-ddns, cluster-wide…— nadie comprueba nada: git es documentación, y una documentación desfasada es peor que no tenerla, porque se aplica creyendo que restaura y en realidad rompe.

La primera pasada (2026-07-22) encontró, sobre 175 objetos:

  • argocd/deployment-argocd-redis.yaml no llevaba el anclaje al control-plane ni los límites de recursos. Aplicarlo deshacía el arreglo del Exit Code 255.
  • A gitea/configmap-daemon-json.yaml le faltaban dos insecure-registries que sí estaban vivos: aplicarlo dejaba a la CI sin poder subir imágenes.
  • El ConfigMap buildkitd-config llevaba 90 días desplegado sin manifiesto.
  • Siete imágenes con tag flotante: git decía gitea:1.25.5 y el cluster corría 1.27.0, subido solo en algún reinicio.

Recordatorio que explica cómo se llega a eso: en estos directorios un commit no despliega nada. Hay que editar el fichero y kubectl apply.

Cómo leer la salida

Tipo Significa
DIFIERE el fichero afirma algo que ya no es cierto
SOLO VIVO hay algo desplegado que el fichero no menciona
NO DESPLEGADO el fichero describe un objeto que no existe

Lo normal es terminar en hallazgos NUEVOS: 0. Si sale algo, o el cluster se tocó a mano sin actualizar el fichero (regenéralo), o el fichero se cambió sin aplicarlo (aplícalo), o es una excepción legítima (justifícala abajo).

excepciones-auditoria.yaml

Un informe que siempre saca ruido deja de leerse, así que las excepciones conocidas se declaran ahí con su motivo. El script avisa cuando una excepción ya no se dispara: significa que aquello se arregló y la entrada sobra.

Lo que NO hace

No compara valores de Secret —sólo nombres de clave—, se salta lo que ignora .gitignore (los kube-root-ca.crt y ServiceAccounts default autogenerados) y no toca nada: es de sólo lectura.

Un aviso por experiencia propia: el imageID de un pod no siempre es el digest del registro. Si viene como repo@sha256:… lo es; si es un sha256:… pelado es el id local de containerd y no se puede descargar — fijar una imagen a ese valor da ImagePullBackOff. Para comparar imágenes, repoDigest contra repoDigest, con sudo k3s crictl inspecti <ref>.