Page de pilotage de la demo
Une page web pour piloter la demo sans terminal : demarrer k3s, deployer, verifier et retirer un mode, voir ses liens et ses comptes, lancer le chaos testing et en lire les verdicts.
demo/k3s/demo.sh ui # demarre cfg-demo-ui, affiche l'URL avec un jeton neuf
demo/k3s/demo.sh ui stop # l'arrete quand aucune action ne tourne ; --force : quand meme
ui affiche http://127.0.0.1:32001/#token=... et n’ouvre rien : copiez
l’URL dans le navigateur. Le jeton sert une fois ; relance, ui en tire un
neuf pour la page en marche (un autre onglet, un autre navigateur).
Ce qu’elle montre
| Onglet | Quoi |
|---|---|
| Control | l’etat de k3s, cluster-up et cluster-down ; par mode : deployer (preset, cases s3, oidc, proxy, otel), check, remove ; par mode deploye : liens (console, explorateur, Keycloak, console RustFS, Grafana), commande sftp a copier, identifiants au clic |
| Chaos | l’etat en direct de chaque pod (pret, /readyz, pairs, backends, detecteurs, bans), une carte par experience : hypothese, mecanisme et regles, injection, frise des signaux, verdict et delais, lien vers Grafana sur la periode du run avec --with-otel |
Le journal de l’action en cours arrive en direct sous les onglets. Une
action a la fois par mode ; cluster-up et cluster-down excluent toute
autre action. Les secrets n’y passent pas : deploy lance depuis la page
les remplace par (hidden: in the page), et la page masque toute valeur
secrete d’un env.sh qui apparaitrait dans une ligne. Le bouton
« Show credentials » les lit dans demo/k3s/.work/<mode>/env.sh, a la
demande.
Le modele de securite
Le conteneur cfg-demo-ui tient le socket Docker de l’hote : qui pilote
la page pilote Docker, l’equivalent de root sur le poste. La page n’est
donc jamais demarree d’office, et chaque requete passe ces barrieres :
| Barriere | Effet |
|---|---|
| ecoute | CFG_DEMO_BIND quand c’est une adresse de bouclage (127.0.0.1 par defaut, 127.x, ::1), aucune autre ; port CFG_DEMO_UI_PORT (CFG_DEMO_PORT_BASE + 1, 32001) |
| jeton | 32 octets aleatoires, tires a chaque ui, dans demo/k3s/.work/ui/token (mode 600) ; dans le fragment de l’URL (#token=), que le navigateur n’envoie a aucun serveur ; la page l’echange une fois (POST /api/session) contre un secret de session, et l’ote de la barre d’adresse ; le jeton est alors consomme |
| session | le secret, garde dans le sessionStorage de l’onglet, envoye en Authorization: Bearer a chaque requete de l’API ; aucun cookie, donc rien que le navigateur joindrait de lui-meme depuis une autre page ou un autre port ; sans lui, 401 (les fichiers de la page, sans secret, sont servis sans) |
en-tete Host | 127.0.0.1, localhost, [::1] ou l’adresse d’ecoute, avec le port : un nom DNS rebrousse vers 127.0.0.1 est refuse (403) |
| origine | chaque action est un POST JSON (Content-Type: application/json, 4096 octets au plus) de la page elle-meme : Origin (ou Sec-Fetch-Site) de la page ; sinon 403 |
| actions | une liste fixe de sous-commandes de demo.sh ; modes lus dans modes/, presets dans presets/, options parmi les quatre --with-*, experiences dans chaos.json ; aucun texte libre, demo.sh lance sans shell |
| conteneur | l’utilisateur et le groupe de l’hote (plus le groupe du socket), systeme de fichiers en lecture seule, aucune capacite ; le kit monte en lecture seule a son chemin, .work en ecriture |
| en-tetes | Content-Security-Policy sans source externe ni script en ligne, X-Frame-Options: DENY, Referrer-Policy: no-referrer, Cache-Control: no-store |
L’image, cfg-demo-ui:<empreinte>, est construite au premier ui depuis
demo/k3s/ui/Dockerfile : l’image Python du kit (python:3.13.9-alpine3.22),
plus bash, la CLI Docker et les coreutils (paquets Alpine). Le serveur
(demo/k3s/ui/server.py) n’utilise que la bibliotheque standard de Python ;
la page (index.html, app.js, style.css) ne charge rien d’ailleurs.
Le verrou d’une action vaut dans la page : un demo.sh lance dans un
terminal en meme temps n’est pas retenu. cluster-down laisse la page en
marche, et demo/k3s/.work/ui/ avec elle ; ui stop les retire. ui stop
refuse tant qu’une action de la page tourne ; --force arrete la page, qui
arrete d’abord chaque action, remise en etat d’une experience comprise
(300 s au plus). chaos defait au debut ce qu’une experience interrompue
aurait laisse.
Le test dans un navigateur
demo/k3s/demo.sh cluster-up
demo/k3s/ui/test/run.sh # demarre la page au besoin, tire un jeton neuf
run.sh lance demo/k3s/ui/test/ui.mjs dans l’image Playwright des tests
de la console (mcr.microsoft.com/playwright:v1.63.0-noble), Chromium sans
tete, sur le reseau de l’hote. Il verifie, en HTTP brut : 401 sans
session, avec une fausse ou avec le jeton de demarrage a sa place, 401
pour un mauvais jeton, 403 sous un autre Host ou depuis une autre
origine, le jeton refuse une fois echange, 415 hors JSON, 400 pour un
corps de plus de 4096 octets, une option ou une action hors liste, aucun
cookie. Puis, dans la page : le jeton ote de l’adresse, deploy single lance et son journal suivi jusqu’a la fin, les mots de passe ni dans
le journal ni dans la page, les identifiants au clic, les onglets au
clavier, l’etat du pod, chaos single auth-burst et sa carte (verdict,
frise, hypothese, regles), remove single. Une erreur de la console du
navigateur l’echoue. Le mode single doit etre libre ; journal et captures :
demo/k3s/.work/ui-test/.