82 lines
4.8 KiB
Markdown
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`.
|