Sync del fix ADDON-PROVISIONER-DB-SECRET-NOT-PUBLISHED (IDP P0).
Ver IDP commit 673c16d para contexto completo.
El init container wait-for-secret del Job Alembic ahora espera 72×5s=360s
(antes 48×5s=240s), dimensionado a 3× el RECONCILE_INTERVAL del
addon-provisioner. El controller bajó su default 300s → 60s en el mismo
parche.
Defense-in-depth: con el controller corriendo a 60s, el delay típico
del Secret publish es ~60-180s. Los 360s del init container absorben
hasta 3 ticks fallidos del controller (cluster recién Ready, kubeconfig
no propagado, etc.).
helm timeout 7m → 10m para que el wait extendido del init container
+ Alembic + StatefulSet ready quepan dentro del comando helm.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bug en chart 0.2.x: AddonClaim era Helm hook pre-install,pre-upgrade
weight -10 SIN hook-delete-policy. El default Helm 3 es
before-hook-creation → borra el claim en cada upgrade → finalizer
cleanup-logical rotaba credenciales + atoraba release en pending-upgrade.
Cambios:
- helm/APP_NAME/templates/addonclaim.yaml eliminado.
- manifests/addonclaim.yaml creado con placeholders sed.
- scripts/pre-helm-detach.sh idempotente para migracion v1.0.0 → 1.1.0.
- .gitea/workflows/APP_NAME-build.yaml: 2 nuevos steps detach + apply
AddonClaim entre kubeconfig y helm upgrade.
- Chart.yaml bump 0.2.0 → 0.3.0.
- README reescrito (3 pasos workflow + tabla hooks sin AddonClaim +
seccion Por que FUERA del chart + opt-out actualizado).
- Comentarios stale del AddonClaim como hook -10 limpiados en
networkpolicy.yaml, role-db-secret-reader.yaml, job-alembic-upgrade.yaml.
ADR-066 del IDP documenta la decision arquitectural completa.
Validacion en cluster tenant DO destapo el issue: el Service `kubernetes` en
ns default tiene endpoint a la IP PUBLICA del Droplet:6443, no a una ClusterIP
intra-cluster. kube-proxy DNATea 10.43.0.1:443 -> public-ip:6443. Calico
aplica las NetworkPolicy egress rules contra la IP de DESTINO POST-DNAT, asi
que namespaceSelector "default" no matchea (no hay pod selector aplicable).
ipBlock 0.0.0.0/0 cubre ambos: apiserver public-ip:6443 + Harbor:443.
Trade-off de seguridad menor (egress permitido a IPs externas por 443/6443)
aceptable para Golden Path: las apps web necesitan llegar a apiserver y
posiblemente a HTTPS externos (APIs publicas). Endurecimiento P3 con
egress NetworkPolicy mas granular cuando haya use cases especificos.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Chicken-and-egg encontrado en smoke E2E DO (cluster 91c93c9c):
- ns 'apps' tiene default-deny NetworkPolicy entregada por stack-deployer.
- Job Alembic (pre-install hook) ejecuta InitContainer wait-for-secret que
hace REST API call al kube-apiserver para chequear Secret.
- La NetworkPolicy del chart (que permite DNS + apiserver egress) estaba como
RESOURCE NORMAL, asi que solo se aplicaba en la FASE PRINCIPAL del helm
install, DESPUES de los hooks.
- Resultado: el InitContainer del hook quedaba bloqueado DNS por
default-deny → curl timeout 240s → helm install fail → NetworkPolicy
nunca se aplica.
Fix:
- Annotations 'helm.sh/hook: pre-install,pre-upgrade' + 'hook-weight: -8'
+ 'hook-delete-policy: before-hook-creation'.
- Weight ordering: -10 AddonClaim → -8 NetworkPolicy → -7 Role/RoleBinding
→ -5 SA → 0 Job Alembic.
- delete-policy: before-hook-creation (no hook-succeeded): el Deployment de
la fase principal necesita la NP viva en runtime.
- Comentario en la regla egress :443 aclarando que cubre kube-apiserver
(10.43.0.1) + Harbor (sin necesidad de regla adicional).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
set -e mataba el script con curl exit 6 (DNS transitorio en el primer
intento) antes de que el retry pudiera correr. Cambio:
- set -u: undefined vars siguen matando (correcto).
- set -e quitado: curl fail no mata el script.
- HTTP=$(curl ... || echo "000"): si curl exits non-zero, capturamos
un codigo HTTP "000" para que el retry siga corriendo.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
bitnami retiro los tags semanticos minor (1.30/1.29/etc.) de Docker Hub
2026-05; solo quedan latest + digests. El InitContainer fallaba con
ImagePullBackOff en el smoke E2E DO (run 1511/1512 del tenant
91c93c9c060a48febb7874c87c1ce993).
Cambio:
- image: bitnami/kubectl:1.30 -> curlimages/curl:8.20.0 (Docker Official,
tag estable).
- comando: kubectl get secret -> curl REST API kubernetes.default.svc con
SA token + CA cert montados en /var/run/secrets/kubernetes.io/serviceaccount.
- Misma logica: 48 iteraciones x 5s = 240s busy-wait.
- El Role/RoleBinding (role-db-secret-reader.yaml) ya da el permiso get
secrets al SA — sin cambios RBAC necesarios.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cierra GOLDEN-PATH-ADDONCLAIM-MISSING (P0 hands-off pipeline).
Cambios:
- helm/APP_NAME/templates/addonclaim.yaml (NEW): hook pre-install/pre-upgrade
weight -10, SIN delete-policy (sobrevive upgrades, evita disparar finalizer
cleanup-logical). Gated por .Values.database.enabled (default true).
- helm/APP_NAME/templates/role-db-secret-reader.yaml (NEW): Role + RoleBinding
weight -7 que permite al SA leer el Secret <release>-db-creds. Lo consume
el InitContainer wait-for-secret del Job Alembic.
- helm/APP_NAME/templates/job-alembic-upgrade.yaml: gated por
database.enabled, anade InitContainer wait-for-secret (48x5s=240s) que
espera a que addon-provisioner publique el Secret tras reconciliar el
AddonClaim. Absorbe la latencia del @kopf.timer (RECONCILE_INTERVAL 300s
+ initial_delay 60s) sin tocar el operator.
- helm/APP_NAME/values.yaml: bloque database completo (enabled, addonType,
databaseName, user.permissions, deletionPolicy Retain). Opt-out con
database.enabled=false + alembic.enabled=false.
- .gitea/workflows/APP_NAME-build.yaml: helm timeout 5m -> 7m (margen para
reconcile addon-provisioner + StatefulSet ready + DDL Job + Alembic).
- claim-mariadb.yaml (DELETED): obsoleto - estaba en la raiz del template
y nunca se renderizaba por helm. Reemplazado por addonclaim.yaml dentro
del chart helm.
- README.md: documenta nueva tabla de hook weights, opt-out database, y
trade-off del orphan AddonClaim post-uninstall (cleanup explicito).
Decision arquitectural: Opcion D modificada (Opus 4.6 consult).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sincroniza desde el monorepo IDP la corrección del hook-order del ServiceAccount
(hook pre-install/pre-upgrade, weight -5) que destraba el helm install del
golden-path sin --no-hooks. Cierre del 4º gap del pipeline tenant hands-off:
el smoke E2E valida ahora la cadena completa (addon-provisioner materializa
MariaDB; AddonClaim publica DATABASE_URL en apps).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Workflow <app>-build.yaml self-contained — sin uses: cross-repo al repo
privado coralware/IDP. requirements-dev.txt inline. image.repository apunta
al proyecto Harbor dedicado del tenant t-<tenant-id-short> (ADR-019 D-03).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- workflow: --namespace apps (antes tenant-${TENANT_ID_NODASHES}-apps)
- values.yaml networkPolicy.addonsNamespace: addons (antes con tenant-id)
ADR-054 establece namespaces funcionales en cluster tenant (RKE2 dedicado
por ADR-018). El cluster es la unidad de aislamiento; tenant-id en
namespace name es legacy del modelo multi-tenant en cluster compartido.