feat: AddonClaim + InitContainer wait-for-secret en chart helm
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>
This commit is contained in:
50
helm/APP_NAME/templates/role-db-secret-reader.yaml
Normal file
50
helm/APP_NAME/templates/role-db-secret-reader.yaml
Normal file
@@ -0,0 +1,50 @@
|
||||
{{- if .Values.database.enabled }}
|
||||
# Role + RoleBinding que permiten al SA de la app leer el Secret `<release>-db-creds`
|
||||
# en el ns `apps`. Lo consume el InitContainer `wait-for-secret` del Job Alembic
|
||||
# (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):
|
||||
# - 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.
|
||||
#
|
||||
# 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
|
||||
# `addons` y nunca debe ser accesible desde `apps` (ADR-052 §6.1).
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-db-secret-reader
|
||||
labels:
|
||||
{{- include "app.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-7"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: [{{ .Values.database.secretName | quote }}]
|
||||
verbs: ["get", "watch", "list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-db-secret-reader
|
||||
labels:
|
||||
{{- include "app.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-7"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-db-secret-reader
|
||||
{{- end }}
|
||||
Reference in New Issue
Block a user