Aller au contenu

Plan — nestor lit l'état réel d'un cluster prod (ADR 0090)

État : Actif (2026-06-22) · Fonde : ADR 0090 (Accepted).

ADR Accepted ⇒ implémentation incrémentale autorisée (ADR 0057 §plans).

Suivi des étapes : ✅ Étape 1 (champ kubeconfig du modèle). ✅ Étapes 2-3 (résolution kubeconfig prod + état réel K8s dans previewprouvé sur dirqual : 3 couches manquantes au lieu de 10). ✅ Étape 4 (couches déduites du réel via _observed_layers). ✅ Étape 1bis/5 (module prod_target + rapatriement assisté réutilisant _fetch_kubeconfig). ✅ Étape 4-bis (garde-fou anti-mutation : test_prod_preview_never_mutates). ⏳ Doc RUNBOOK + extension de la confirmation aux futures commandes de mutation.

Rendre nestor preview (et la lecture d’état) honnête sur un cluster prod : quand target_kind: prod, l’état réel est lu via kubectl (nœuds + couches), pas via les VMs Lima. Sans abaisser l’isolation banc/prod (ADR 0053/0084) : lecture seule, aucune voie de mutation prod ouverte.

  • Inclus : preview et les sondes d’état réel en target_kind: prod ; réutilisation des sondes discover (ADR 0074) ; choix du kubeconfig prod sûr.
  • Exclu (décision ultérieure, hors ADR 0090) : faire muter la prod par nestor (up/next/remove). L’install prod reste Ansible/RUNBOOK.

Trois fonctions de scripts/topology.py à conditionner par target_kind :

FonctionComportement actuel (prod)Cible (prod)
_real_vmsreturn [] → « VMs à créer : dirqual*»section VMs omise (machines hors nestor)
_ready_nodesgaté → vide sans KUBECONFIGlit kubectl get nodes via kubeconfig prod
_bench_kubeconfig/dev/null hors banckubeconfig: déclaré dans la topo (lecture)
couches présentesnon lues (PLAN = tout à monter)déduites du réel K8s (sondes _discover_*)

Étape 0 — Convention : un kubeconfig par stack, hors dépôt

Section intitulée « Étape 0 — Convention : un kubeconfig par stack, hors dépôt »

Un fichier ~/.kube/<stack>.config par cible (ex. ~/.kube/dirqual.config), hors de l’arbre du dépôt (credentials réels, jamais commités). Rapatriement depuis le control plane (manuel/documenté) : copier /etc/kubernetes/admin.conf de dirqual1~/.kube/dirqual.config, vérifier kubectl --kubeconfig ~/.kube/dirqual.config get nodes. Documenter dans le RUNBOOK. (Aucune modification de fichier versionné : c’est de la config locale opérateur.)

Étape 1 — Champ kubeconfig: dans la topologie + résolution sûre

Section intitulée « Étape 1 — Champ kubeconfig: dans la topologie + résolution sûre »

(a) Schéma : ajouter un champ optionnel kubeconfig: <chemin> au modèle de topologie (cluster_topology/model.py + schéma de validation) ; le *.example documente l’usage (~/.kube/<stack>.config), le .yaml réel (gitignoré) le renseigne (ADR 0023). (b) Résolution : étendre _bench_kubeconfig/_kubectl_env — en target_kind: prod, priorité KUBECONFIG exporté → kubeconfig: de la topo → échec clair (jamais ~/.kube/config). /dev/null anti-mutation conservé pour le banc. Preuve : tests unitaires (parsing du champ + ordre de résolution, stub env), aucun appel réseau.

Étape 1bis — Confirmation interactive + rapatriement assisté

Section intitulée « Étape 1bis — Confirmation interactive + rapatriement assisté »

(a) Confirmer la cible : avant une commande prod, lire l’endpoint API + les nœuds vus (kubectl, fonction pure stubable) et demander confirmation (« stack <nom><endpoint> <nœuds> ? [y/N] ») ; négatif ⇒ arrêt. En --no-input/CI : vérification stricte endpoint attendu vs résolu (pas de prompt). (b) Rapatriement assisté : si le kubeconfig: est absent/injoignable, proposer la copie scp <control>:/etc/kubernetes/admin.conf → ~/.kube/<stack>.config (control-plane lu dans bootstrap/hosts.yaml) + re-vérif get nodes. Preuve : tests unitaires (rendu de la confirmation, parsing endpoint/nœuds, construction de la commande de rapatriement) — tout stubé, aucun appel réseau ni mutation cluster.

Étape 2 — État réel polymorphe selon target_kind

Section intitulée « Étape 2 — État réel polymorphe selon target_kind »

preview : en prod, ne pas appeler _real_vms (omettre la section VMs) ; appeler _ready_nodes (kubectl) + les sondes couches. Fonction pure de composition de l’« état réel » testée avec un kubectl stubé (sortie get nodes/get ns injectée). Preuve : pnpm test:python.

Étape 3 — Couches présentes déduites du réel K8s

Section intitulée « Étape 3 — Couches présentes déduites du réel K8s »

Brancher les sondes discover (ADR 0074 : namespaces, CRD, SC, ressources) dans le calcul du PLAN : une couche dont les marqueurs réels existent est présente (pas « à monter »). Mapping couche→marqueur (ex. cephcephcluster, dataops→ns dagster/marquez, mlflow→ns mlflow). Preuve : table de mapping testée ; sur la prod réelle (lecture seule, manuel) preview doit refléter l’état déjà constaté (ceph…mlflow : seules dataops+mlflow absentes).

Étape 4 — Garde-fou anti-mutation (test d’isolation)

Section intitulée « Étape 4 — Garde-fou anti-mutation (test d’isolation) »

Test prouvant qu’une lecture prod (preview) ne peut pas déclencher une écriture (pas d’appel apply/launch_phase/limactl en chemin lecture). Préserve ADR 0053. Preuve : test unitaire + revue.

Documenter l’état réel polymorphe (lima = VMs+nœuds ; prod = nœuds K8s) dans la vue outils + l’aide preview. Mettre à jour le RUNBOOK (nestor sait lire la prod ; il ne la monte pas — Ansible).

  • Sans prod : pnpm test:python (sondes pures + stubs kubectl), pnpm lint.
  • Banc inchangé : nestor preview sur stack banc/lima rend le même résultat qu’avant (non-régression).
  • Lecture prod réelle (manuel, lecture seule) : nestor preview sur stack dirqual reflète kubectl get nodes/get ns — plus de « VMs à créer », PLAN = seules les couches réellement absentes.
  • Régression d’isolation (ADR 0053) → périmètre lecture seule strict + test anti-mutation (étape 4) ; mutation prod hors scope.
  • Confusion état polymorphe → doc explicite + messages preview clairs.
  • Mauvais kubeconfig prod → cible nommée et vérifiée, jamais implicite.
ÉtapeÉtat
0. Un kubeconfig par stack, hors dépôt✅ achevée
1. Champ kubeconfig: + résolution sûre✅ achevée
1bis. Confirmation interactive + rapatriement✅ achevée
2. État réel polymorphe selon target_kind✅ achevée
3. Couches présentes déduites du réel K8s✅ achevée
4. Garde-fou anti-mutation (test d’isolation)✅ achevée
5. Doc✅ achevée

Issues rattachées : —. La lecture-seule de la prod est livrée (nestor preview/ kubectl sur stack dirqual, garde _assert_inventory_safe). Le plan reste Actif : nestor évolue vers la MUTATION encadrée de la prod (ex. nestor ansible <playbook>, ADR 0098), prolongement naturel de ce pilotage.