chart 0.3.0: AddonClaim FUERA del chart Helm (ADR-066 del IDP)
Some checks failed
__APP_NAME__ — build & deploy / Calidad + build + push (push) Failing after 14s
__APP_NAME__ — build & deploy / Helm upgrade --install (push) Has been skipped

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.
This commit is contained in:
2026-05-25 14:28:17 -05:00
parent bba5720975
commit 13b9fae61c
9 changed files with 214 additions and 71 deletions

View File

@@ -1,6 +1,14 @@
apiVersion: v2
name: __APP_NAME__
# Helm chart del Golden Path web-backend/python.
# 0.3.0 (2026-05-25): ADR-066 — AddonClaim sale del chart y vive en
# manifests/addonclaim.yaml. El workflow del tenant lo aplica con
# kubectl apply ANTES de helm upgrade --install. Razon: en chart 0.2.x el
# AddonClaim era hook pre-install,pre-upgrade weight -10 → el default Helm
# `before-hook-creation` borraba el claim en cada upgrade → el finalizer
# cleanup-logical rotaba credenciales y atoraba el release en
# pending-upgrade. Desacoplar el lifecycle del CRD del lifecycle del
# release Helm resuelve el bug de raiz.
# 0.2.0 (2026-05-19): cambio Ingress controller Traefik (IngressRoute CRD)
# → rke2-ingress-nginx (networking.k8s.io/v1 Ingress). Razón:
# TENANT-INGRESS-CONTROLLER-MISMATCH (APERTURA COVE Sesión 3). El cluster
@@ -8,7 +16,7 @@ name: __APP_NAME__
# adicional. tlsSecretName por default = apps-wildcard-tls (Gap 3).
description: Helm chart del Golden Path web-backend/python
type: application
version: 0.2.0
version: 0.3.0
appVersion: "0.1.0"
keywords:
- fastapi

View File

@@ -1,39 +0,0 @@
{{- if .Values.database.enabled }}
# AddonClaim — declara la intencion de la app de tener una BD (default MariaDB).
# Lo materializa addon-provisioner (CRD idp.coralware.cloud/v1alpha1):
# - reconcilia este claim cada RECONCILE_INTERVAL (default 300s) por TenantProfile.
# - crea BD logica + user + grant via Job DDL efimero en el cluster tenant.
# - publica el Secret `{{ .Values.database.secretName }}` en este ns (`apps`)
# con DATABASE_URL / DATABASE_HOST / DATABASE_PORT / DATABASE_USER /
# DATABASE_PASSWORD / DATABASE_NAME (contrato §2.3 del OpenSpec).
#
# Ordering con los hooks del chart (clave para que Alembic encuentre el Secret):
# weight -10 (este AddonClaim)
# -> weight -5 (ServiceAccount)
# -> weight 0 (Job Alembic — espera al Secret via InitContainer wait-for-secret)
#
# delete-policy: NO se declara intencionalmente.
# - Asi el AddonClaim sobrevive entre `helm upgrade` (re-apply idempotente).
# - Evita disparar el finalizer `cleanup-logical` en cada upgrade (que dropearia
# el user y regeneraria el password, causando ventana de downtime).
# - Trade-off documentado: `helm uninstall` deja el AddonClaim orfano y MariaDB
# sigue aprovisionada. Es coherente con `deletionPolicy: Retain` (default):
# borrar BD productiva debe ser decision explicita, no side-effect del uninstall.
# Cleanup explicito: `kubectl delete addonclaim {{ .Release.Name }}-db -n apps`.
apiVersion: idp.coralware.cloud/v1alpha1
kind: AddonClaim
metadata:
name: {{ .Release.Name }}-db
labels:
{{- include "app.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-10"
spec:
addonType: {{ .Values.database.addonType | default "mariadb" | quote }}
databaseName: {{ .Values.database.databaseName | default (printf "%s_db" (.Release.Name | replace "-" "_")) | quote }}
user:
permissions: {{ .Values.database.user.permissions | default "rw" | quote }}
secretName: {{ .Values.database.secretName | quote }}
deletionPolicy: {{ .Values.database.deletionPolicy | default "Retain" | quote }}
{{- end }}

View File

@@ -5,9 +5,11 @@
# visible para `kubectl logs job/...` y diagnostico.
#
# InitContainer `wait-for-secret`:
# - El AddonClaim (hook weight -10) ya fue aplicado, pero addon-provisioner es
# timer-based (RECONCILE_INTERVAL 300s, initial_delay 60s) y materializa el
# Secret `{{ .Values.database.secretName }}` de forma asincrona.
# - El AddonClaim ya fue aplicado por el workflow del tenant ANTES del
# `helm upgrade --install` (ADR-066, vive FUERA del chart en
# manifests/addonclaim.yaml). addon-provisioner es timer-based
# (RECONCILE_INTERVAL 300s, initial_delay 60s) y materializa el Secret
# `{{ .Values.database.secretName }}` de forma asincrona.
# - El InitContainer hace busy-wait hasta que el Secret existe — absorbe la
# latencia del reconcile dentro del pod, sin tocar el operator ni
# bajar RECONCILE_INTERVAL global.

View File

@@ -12,7 +12,10 @@
# NetworkPolicy nunca se aplica en la fase principal.
#
# Weight ordering (mas chico = antes):
# -10 AddonClaim -> -8 NetworkPolicy -> -7 Role/RoleBinding -> -5 SA -> 0 Job Alembic
# -8 NetworkPolicy -> -7 Role/RoleBinding -> -5 SA -> 0 Job Alembic
# (El AddonClaim vive FUERA del chart desde 0.3.0 — ADR-066. Lo aplica el
# workflow del tenant ANTES de `helm upgrade --install`, asi que en la fase
# de hooks ya existe y addon-provisioner ya esta reconciliando.)
#
# delete-policy: before-hook-creation (NO hook-succeeded): la fase principal del
# Deployment necesita la NetworkPolicy viva en runtime; solo se borra/recrea al

View File

@@ -4,11 +4,13 @@
# (hook pre-install/pre-upgrade weight 0) que hace busy-wait hasta que
# addon-provisioner publica el Secret tras reconciliar el AddonClaim.
#
# Hook weight "-7" — entre AddonClaim (-10) y SA (-5):
# Hook weight "-7" — entre NetworkPolicy (-8) y SA (-5):
# - Garantiza que RBAC exista antes de que el SA del hook -5 se materialice
# y antes de que el Job -0 intente leer el Secret.
# - delete-policy: before-hook-creation para que sea idempotente entre upgrades
# sin dejar Roles huerfanos.
# (El AddonClaim ya no es hook del chart desde 0.3.0 — ADR-066. Lo aplica el
# workflow del tenant ANTES del `helm upgrade --install`.)
#
# Scope minimo: solo lectura (get/watch) del Secret `<release>-db-creds`, no
# secrets cluster-wide ni del ns `addons`. El root Secret de MariaDB vive en