Files
omnex/deploy/chart-vitrine/README.md
T
Xor290 8d857faa45
ci-api / test (push) Successful in 23m32s
ci-web / test (push) Successful in 14m7s
chore: build
2026-09-20 18:52:09 +02:00

82 lines
4.8 KiB
Markdown

# 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-<id>.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='<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 <ip>: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/<chart> --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`.