# chart-vitrine Charts du projet vitrine déployé **par le control-plane Omnex** (jamais à la main) pour un client, sur abonnement de 1 à 12 mois. Même cluster, mêmes sauvegardes Velero que les démos (`deploy/chart-gestion`), mais un produit différent : les charts de mêmes noms (`backend`, `frontend`, `postgresql`, `redis`, `ingressroute`) vivent donc dans ce dossier séparé, monté dans le control-plane sur `/charts-vitrine` (volume du `docker-compose.yml`). `network-policy`, `resource-quota` et `registry-credentials` sont ceux de `chart-gestion`. | Chart | Rôle | |---|---| | `postgresql` | Postgres 16 (StatefulSet + PVC Longhorn), Service `postgres` | | `redis` | Redis 7 avec mot de passe, Service `redis` | | `backend` | API Go/Gin ; migrations (hook pre-install/upgrade) et compte admin (hook post-install) | | `frontend` | SPA Vite/React derrière nginx | | `ingressroute` | IngressRoute Traefik : `/api/` et `/uploads/` → backend, `/` → frontend, sur un même host | | `cert-manager/` | Manifestes bruts (pas un chart) : issuers DNS-01 et certificat wildcard partagé | ## Cycle de vie (internal/projects) 1. L'admin déploie depuis le dashboard : nom du client, **durée 1 à 12 mois**, compte admin (identifiant, mot de passe 12+ caractères) et **nombre d'admins** (`ADMIN_NUMBER`, 1 à 20). Le projet est servi sur `https://vitrine-.vitrine-omnex.club`. 2. `POST /projects/:id/extend {"months": 1..12}` ajoute des mois à partir de l'échéance (ou de maintenant si elle est dépassée). Le paiement est hors périmètre : l'admin renouvelle quand le client a payé. 3. À l'échéance le projet est **supprimé** (namespace, données et sauvegardes Velero), sans délai de grâce : il faut donc renouveler avant l'échéance. Un `DELETE /projects/:id` fait la même chose immédiatement. Sauvegardes : un `Schedule` Velero par namespace, créé au déploiement et supprimé avec le projet, identique à celui des démos (toutes les 15 min, conservé 24 h, File System Backup). ## Prérequis du cluster (à faire une seule fois) Ne pas réinstaller cert-manager, Velero, Longhorn, Traefik ni le WAF : ils sont partagés. 1. **Token Cloudflare** (`Zone:DNS:Edit` sur `vitrine-omnex.club`), jamais dans un manifeste : ```bash kubectl create secret generic cloudflare-api-token-vitrine -n cert-manager \ --from-literal=api-token='' ``` 2. **Issuers puis certificat wildcard partagé** : ```bash kubectl apply -f deploy/chart-vitrine/cert-manager/cluster-issuer.yml kubectl apply -f deploy/chart-vitrine/cert-manager/wildcard-certificate.yml kubectl get certificate -n traefik # wildcard-vitrine-tls : READY=True ``` Premier essai : remplacer l'issuer du certificat par `letsencrypt-dns-vitrine-staging`. 3. **WAF (terminaison TLS publique)** : le trafic entre par `gestion-waf-cluster` (nginx + ModSecurity), qui termine le TLS avec un certificat par domaine choisi par SNI. Le certificat des projets est déclaré dans `deploy/chart-gestion/waf-cluster/values.yaml` (`tls.extra`) : ```bash helm upgrade gestion-waf-cluster deploy/chart-gestion/waf-cluster -n traefik --reset-then-reuse-values ``` Le secret `wildcard-vitrine-tls` (étape 2) doit exister avant : sans lui les Pods du WAF ne démarrent pas. Vérifier : `echo | openssl s_client -connect :443 -servername x.vitrine-omnex.club | openssl x509 -noout -subject` (CN=vitrine-omnex.club attendu). Le TLSStore de Traefik (`tls.extraSecretNames`) référence aussi ce secret, mais il ne concerne que la connexion interne WAF → Traefik, non vérifiée. 4. **RBAC** : `kubectl apply -f deploy/rbac/control-plane.yml` (ajoute le droit sur les `jobs`, nécessaire aux hooks Helm de migration et de création du compte admin). 5. **DNS** (Cloudflare, enregistrements `A` en **DNS only**, pas « Proxied » : le WAF et le rate-limit ont besoin de l'IP réelle des clients) : `*.vitrine-omnex.club` → IPs des nœuds (le LoadBalancer écoute sur chacun). 6. **Images** : pousser `vitrine-backend` et `vitrine-frontend` sur un registry, puis renseigner `VITRINE_BACKEND_IMAGE` et `VITRINE_FRONTEND_IMAGE` (ex. `registry/vitrine-backend:1.0.0`) dans l'environnement du control-plane. ## Développement ```bash helm lint deploy/chart-vitrine/ --set secrets.JWT_SECRET=x --set host=a.vitrine-omnex.club --set auth.password=pw cd control-plane/api && go test ./internal/projects/ ./internal/demos/ ``` `TestVitrineValuesRenderWithCharts` génère les valeurs comme le control-plane et rend les charts avec helm : il échoue si un nom de Service ou une clé de valeurs diverge entre le Go et les charts. Le mode « autonome » (installation manuelle d'un seul projet, certificat par namespace) reste disponible dans `ingressroute` : `tls.secretName=wildcard-vitrine-tls` et `tls.certificate.enabled=true`.