Retour à Réseau-Net Projet professionnel

Portail d'administration de la supervision

Interface web maison qui pilote une stack Prometheus / Grafana / Blackbox Exporter multi-clients : une base SQLite comme source de vérité, régénération automatique des configurations, alertes email HTML avec graphes intégrés et digest journalier.

Réseau-Net Sprint de 2 semaines Solo · pair avec Claude Code En production
Note de confidentialité : Cette page reste volontairement au niveau conceptuel : architecture, stack et choix d'ingénierie. Aucune information technique sensible (IPs, hostnames, chemins internes, secrets, identifiants ou configurations spécifiques à l'infrastructure Réseau-Net) n'est publiée.
Contexte

Pourquoi ce portail ?

Faire d'une stack Prometheus / Grafana un outil utilisable au quotidien par toute l'équipe

Réseau-Net supervise, pour ses clients, un ensemble de liens (fibres et 4G/5G) via une stack Prometheus + Blackbox Exporter + Grafana. La configuration se pilotait via des fichiers YAML et JSON éditables à la main, avec un risque d'erreur élevé et une dépendance forte à celui qui connaissait l'outil.

J'ai proposé et développé une interface web maison qui devient la source de vérité de la supervision : ajout/modification/suppression d'un lien, gestion des clients et de la liste de diffusion des alertes, tout se fait dans un outil simple, et l'ensemble des fichiers de configuration Prometheus et Grafana est régénéré automatiquement derrière.

Le portail intègre aussi un webhook d'alerte custom pour envoyer des emails HTML riches (avec graphes intégrés) que Grafana ne sait pas produire nativement, ainsi qu'un digest journalier automatique récapitulant l'état des liens.

Un déclic technique important : Grafana n'est pas conçu pour être la source de vérité de l'alerting quand on gère plusieurs dizaines de liens multi-clients. Le vrai enjeu du projet n'était pas de « faire du Grafana », mais de rendre la stack pilotable par toute l'équipe sans risquer de casser la configuration à chaque modification.

La règle d'or : Grafana sert uniquement à consulter les dashboards. Toutes les modifications passent par le portail ; les fichiers YAML sont regénérés à partir de la base SQLite, jamais édités à la main.

Développement en pair avec Claude Code : le projet a été conçu, prototypé et livré en ≈ 2 semaines grâce à un flux de travail en pair-programming avec un LLM. La vitesse d'itération a été volontairement mise au service d'une posture de sécurité assumée : segmentation réseau, HTTPS sur le réseau local uniquement, aucune exposition Internet, flux sortants restreints à l'ICMP. Voir ci-dessous.

Objectifs

Ce que le portail devait apporter

Quatre grands objectifs traduits en choix d'ingénierie concrets

01

Une seule source de vérité

Une base SQLite centralise clients, liens supervisés, opérateurs et liste de diffusion. Toutes les configs Prometheus/Grafana en dérivent.

02

Piloter sans toucher aux YAML

L'équipe peut ajouter/modifier/supprimer un lien via l'interface web. Les fichiers targets JSON et YAML d'alerting Grafana sont régénérés automatiquement.

03

Alertes HTML avec graphes

Contourner les limitations natives de Grafana en interceptant les alertes via un webhook custom, pour envoyer des emails HTML riches avec graphes intégrés.

04

Vue d'ensemble quotidienne

Un digest journalier automatique récapitule l'état des liens (UP/DOWN par client) pour l'équipe, sans avoir à ouvrir Grafana chaque matin.

Architecture

Flux logique de bout en bout

Comment une action dans le portail se propage jusqu'aux alertes des clients

1. Interface web (source de vérité)

FastAPI + HTMX l'équipe ajoute/modifie/supprime un lien

2. Base SQLite

Clients, liens, opérateurs, liste de diffusion, audit log

3. Régénération des configs

Prometheus (targets JSON) + Grafana (contact points, policies, alert rules) reload API

4. Sonde Blackbox + Prometheus

Probe ICMP vers chaque lien, métriques stockées, règles d'alerte évaluées

5. Alerte déclenchée

Grafana Alertmanager → webhook FastAPI + webhook Teams

6. Email HTML avec graphes

Rendu des panneaux Grafana en PNG, embarqués en CID inline, envoyés en SMTP direct

Un digest journalier planifié via systemd timer complète ce flux temps-réel avec un récap matinal.

Réalisations

Ce que j'ai conçu et développé

Huit blocs qui composent le portail, du backend au reverse proxy

Backend FastAPI + SQLite

Application FastAPI servie par Uvicorn, avec SQLite comme source de vérité pour les liens, clients, opérateurs, liste de diffusion et journal d'audit.

  • Routes CRUD complètes (liens, clients, opérateurs, membres)
  • Schéma de tables pensé pour l'intégrité (clés uniques, cascades)
  • Journal d'audit sur chaque action

Frontend HTMX + Bootstrap

Interface réactive sans framework JS lourd : HTMX pour les mises à jour partielles (édition inline, filtres, modales), Bootstrap 5 pour la structure et l'accessibilité.

  • Édition inline dans les tableaux
  • Modales et filtres pilotés par HTMX
  • Templates Jinja2 avec partials réutilisables

Régénération Prometheus

À chaque modification, les fichiers targets JSON sont réécrits (un par client) et Prometheus est rechargé via son API admin, sans redémarrage du container.

  • file_sd_configs par client (un JSON par slug)
  • Purge des séries orphelines lors d'une suppression
  • Reload à chaud via l'API Prometheus

Provisioning Grafana

Écriture des fichiers YAML de provisioning Grafana (contact points, policies, alert rules) directement depuis la base SQLite, puis reload via l'API.

  • Contact points reconstruits à chaque changement
  • Politique de routage par lien (pas de bundle par client)
  • Écriture en place (préservation du bind-mount Docker)

Webhook custom & email HTML

Interception des alertes Grafana par un webhook FastAPI, qui génère un email HTML riche et l'envoie en SMTP direct Grafana HTML-escape le message natif, ce contournement était nécessaire.

  • Protection du webhook par token (dans l'URL)
  • Rendu des panneaux Grafana via grafana-image-renderer
  • Graphes embarqués en CID inline (compatibles Outlook)
  • Dégradation propre si le renderer est indisponible

Notifications Teams

Second canal de notification : webhook Teams via Power Automate, avec templates Go côté Grafana pour construire un message lisible directement dans le chat de l'équipe.

  • Templates Go avec fallback sur labels multi-alertes
  • Lien direct vers le dashboard concerné

Digest journalier automatique

Script Python déclenché par un systemd timer chaque matin : interroge Prometheus, agrège les liens DOWN par client, et envoie un email récapitulatif à l'équipe.

  • Requête PromQL sur probe_success == 0
  • Regroupement par client avec IP, description, opérateur
  • Email « Tout est UP » si aucun incident en cours

Reverse proxy & sécurité

Nginx en reverse proxy avec Basic Auth pour l'interface humaine, endpoint webhook séparé (sans Basic Auth mais protégé par token) pour que Grafana puisse appeler sans credentials.

  • Basic Auth sur l'interface web (identifiants dédiés)
  • Endpoint webhook isolé, token en variable d'environnement
  • Service Uvicorn géré par systemd (auto-restart, logs journalctl)
Stack technique

Environnement du projet

Une stack open source, volontairement minimaliste, sans framework JS lourd

 Backend

Python 3 FastAPI Starlette Jinja2 SQLite requests

 Frontend

HTMX 1.9 Bootstrap 5.3 Bootstrap Icons HTML server-rendered

 Monitoring

Prometheus Blackbox Exporter Grafana grafana-image-renderer PromQL

 Infra & ops

Docker Compose Nginx systemd Uvicorn SMTP

 Intégrations

Microsoft Teams Power Automate Templates Go Webhooks

 Patterns

Source de vérité SQLite Config as data Reload à chaud Audit log
Sécurité & isolation

Une posture sécurité assumée dès le départ

La vitesse de développement en pair avec Claude Code n'a pas été un prétexte à négliger les fondamentaux

Segmentation réseau

Le portail tourne sur une VM dédiée, isolée dans son propre segment réseau, séparée du reste de l'infrastructure et des réseaux clients.

HTTPS sur le LAN uniquement

L'interface web est servie en HTTPS et n'est joignable que depuis le réseau local interne. Aucune exposition Internet, aucun accès distant public.

Flux sortants restreints à l'ICMP

La VM ne parle aux réseaux clients qu'en ICMP (sondes de disponibilité Blackbox). Aucun autre protocole n'est autorisé en sortie vers les clients.

Authentification & secrets

Basic Auth sur l'interface humaine, endpoint webhook isolé et protégé par un token stocké en variable d'environnement, hors dépôt Git.

Résultats

Ce que le portail a apporté

Un impact concret sur l'autonomie de l'équipe et la fiabilité de la supervision

Équipe autonome

N'importe quel membre de l'équipe peut désormais gérer la supervision, sans risquer de casser la config en éditant un YAML à la main.

Configs toujours cohérentes

Prometheus, Grafana alerting et liste de diffusion sont dérivés de la même base : impossible d'avoir un désalignement entre l'inventaire et les alertes.

Alertes actionnables

Chaque alerte contient les infos utiles + un graphe inline pour comprendre l'incident sans même ouvrir Grafana. Client mis en copie automatiquement.

Traçabilité complète

Le journal d'audit garde une trace horodatée de chaque ajout, modification ou suppression : qui a fait quoi, quand, sur quel lien.

Livraison en 2 semaines

Sprint de conception + développement + mise en production en ≈ 2 semaines en pair avec Claude Code, sans compromis sur les fondamentaux de sécurité (isolation, HTTPS local, ICMP-only).