Aller au contenu principal

Venus

Venus stack

L'interface de supervision est une application Vue 3 + Vite intégrée directement au package unique venus : un seul package.json et un seul node_modules pilotent à la fois le backend NestJS et le frontend Vue.

Le dossier web/ ne contient plus que les sources (index.html + src/) ; toute la configuration (Vite, Vitest, tsconfig web) vit à la racine de venus.

Venus dialogue en GraphQL sur /graphql (même origine), puis relaie les flux vers les services métier.

  • Saturn : inventaire, actions, DNS et DHCP.

  • Mercure : consultation et traitement des logs.

Venus sert le SPA compilé (web/dist) via ServeStaticModule, en excluant /graphql. Il n'y a plus de conteneur central-web distinct.

Stack NestJS + GraphQL​

La couche Venus combine un backend NestJS et une passerelle GraphQL dans le meme service.

  • NestJS structure les modules metier, les resolvers et les adaptateurs.
  • GraphQL expose un point d'entree unifie (/graphql) pour le frontend.
  • BFF : Venus agrege les donnees Saturn et Mercure pour limiter la complexite cote UI.

Arborescence​

central/venus/
├── package.json # package unique (Nest + Vue)
├── tsconfig.json # config serveur (NestJS, CommonJS)
├── tsconfig.web.json # config frontend (Vue, ESM)
├── nest-cli.json
├── vite.config.ts # root = web/, sortie web/dist
├── vitest.config.ts
├── src/ # backend NestJS (gateway GraphQL/CQRS)
└── web/
├── index.html
└── src/
├── main.ts # bootstrap de l'application
├── router/ # routes UI
├── views/ # pages de supervision
├── services/api.ts # client GraphQL
└── components/ # composants UI

Build & développement​

  • npm run build — construit le web (build:web : vue-tsc + vite build → web/dist) puis le serveur (build:server : nest build → dist).
  • npm run dev — lance en parallèle vite build --watch et nest start --watch.
  • npm run test:web — tests unitaires Vitest.

En conteneur, l'override docker-compose.central.dev.yml exécute ces deux processus dans un seul conteneur central-venus (plus de service séparé).

Accès API (GraphQL)​

Le frontend central consomme l'endpoint GraphQL de venus :

  • URL par défaut : /graphql (même origine, servie par venus)
  • variable d'environnement optionnelle : VITE_VENUS_URL

Exemples d'opérations côté web :

  • health
  • nodes
  • actions
  • enqueueAction
  • queryLogs
  • dnsRecords, upsertDnsRecord, deleteDnsRecord, syncDns
  • dhcpRecords, upsertDhcpRecord, deleteDhcpRecord

Fonctionnement détaillé de Venus​

Venus joue un rôle de couche d'orchestration entre le frontend et les services backend.

  • Les resolvers GraphQL reçoivent la requête UI et appliquent la validation d'entrée.
  • Les services NestJS traduisent la requête GraphQL en appels REST vers Saturn ou Mercure.
  • Les réponses sont normalisées pour exposer un contrat stable au frontend.
  • Les erreurs backend sont transformées en erreurs GraphQL explicites pour l'interface.

Cycle typique d'une requête :

  1. La vue frontend envoie une query ou mutation sur /graphql.
  2. Le resolver Venus route vers le service métier concerné.
  3. Le service appelle Saturn ou Mercure.
  4. Venus reformate et retourne la réponse GraphQL au frontend.

Documentation des queries​

Query health​

Permet de vérifier rapidement la disponibilité de Venus et des dépendances critiques.

query Health {
health {
status
timestamp
dependencies {
name
status
latencyMs
}
}
}

Query nodes​

Retourne la liste des nodes visibles dans la flotte avec leur état.

query Nodes($limit: Int, $search: String) {
nodes(limit: $limit, search: $search) {
id
name
ip
status
lastSeenAt
}
}

Variables possibles :

{
"limit": 50,
"search": "zone-nord"
}

Query queryLogs​

Interroge les logs via Mercure, avec filtres par node, niveau et période.

query QueryLogs($nodeId: String, $level: String, $limit: Int) {
queryLogs(nodeId: $nodeId, level: $level, limit: $limit) {
items {
timestamp
nodeId
level
message
}
total
}
}

Variables possibles :

{
"nodeId": "node-01",
"level": "error",
"limit": 100
}

Query dnsRecords​

Lit les enregistrements DNS gérés par la flotte.

query DnsRecords($zone: String) {
dnsRecords(zone: $zone) {
id
host
type
value
ttl
}
}

Documentation des mutations​

Mutation enqueueAction​

Enfile une action opérateur vers un node (pilotage relais, vannes, etc.).

mutation EnqueueAction($input: EnqueueActionInput!) {
enqueueAction(input: $input) {
actionId
status
queuedAt
}
}

Exemple de variables :

{
"input": {
"nodeId": "node-01",
"type": "relay.toggle",
"payload": {
"relayId": "r1",
"state": true
}
}
}

Mutation upsertDnsRecord​

Crée ou met à jour un enregistrement DNS.

mutation UpsertDnsRecord($input: UpsertDnsRecordInput!) {
upsertDnsRecord(input: $input) {
id
host
value
ttl
}
}

Mutation deleteDnsRecord​

Supprime un enregistrement DNS par identifiant.

mutation DeleteDnsRecord($id: ID!) {
deleteDnsRecord(id: $id) {
success
message
}
}

Mutation upsertDhcpRecord​

Crée ou met à jour une entrée DHCP.

mutation UpsertDhcpRecord($input: UpsertDhcpRecordInput!) {
upsertDhcpRecord(input: $input) {
id
mac
ip
hostname
}
}

Mutation deleteDhcpRecord​

Supprime une entrée DHCP.

mutation DeleteDhcpRecord($id: ID!) {
deleteDhcpRecord(id: $id) {
success
message
}
}

Bonnes pratiques d'utilisation​

  • Utiliser des variables GraphQL plutôt que des valeurs en dur.
  • Demander uniquement les champs nécessaires pour réduire la charge réseau.
  • Limiter queryLogs avec limit et filtres (nodeId, level) pour les vues temps réel.
  • Prévoir un rafraîchissement progressif (polling) avec gestion des erreurs réseau côté UI.

Organisation UI​

Le frontend central est orienté parc de nodes :

  • liste des nodes connectés ;
  • statut réseau ;
  • actions de pilotage ;
  • accès aux logs agrégés.
  • administration DNS et DHCP depuis le menu Infrastructure.
  • vue Network → Flotte listant les machines du réseau ayant émis un health state Kafka (voir Flotte & santé réseau).

La vue Network → Flotte s'actualise automatiquement par polling HTTP GraphQL (fleet) toutes les 15 s, avec pause quand l'onglet navigateur est caché puis reprise avec refresh immédiat au retour au premier plan.

La vue Network → Flotte → Détail instance affiche aussi les logs récents du node (logs GraphQL filtrés par nodeId), issus de Mercure/Kafka. Un filtre de niveau (info, warn, error, debug) est disponible dans cette section pour cibler rapidement les événements opérationnels.

Cette vue inclut aussi un bloc Capteur eau (microcontrôleur) qui lit les métriques remontées par l'agent via meta.plugin_metrics (ex: water_raw, moisture). Sans trame série émise par le microcontrôleur, le bloc reste en mode "aucune mesure".

Authentification​

L'authentification est portée par Saturn (fournisseur native) : utilisateurs, rôles hiérarchiques, sessions et tokens sont stockés en PostgreSQL (tables iam_*). Le fournisseur se choisit dans l'env du conteneur Saturn : AUTH_PROVIDER=native|none.

  • Login : HTTP Basic uniquement ; verrouillage après AUTH_MAX_LOGIN_ATTEMPTS échecs.
  • Tokens : access token JWT HS256 (AUTH_ACCESS_TOKEN_TTL), refresh token opaque haché en base, rotation à chaque refresh ; un refresh token rejoué hors fenêtre de grâce (10 s) révoque toute la session. Durée max de session : AUTH_SESSION_MAX_TTL.
  • Endpoints OAuth2 : /api/auth/token, /api/auth/revoke (RFC 7009), /api/auth/introspect (RFC 7662), /api/auth/userinfo, /api/auth/config.
  • Permissions : ressource:action avec jokers * et ressource:*. Rôles composites seedés : admin ⊃ operator ⊃ viewer. Saturn contrôle chaque route REST ; Venus contrôle les opérations non Saturn (logs, fleet, health, iam).
  • Canal machine : POST /api/consignes/sync (agents) reste sans authentification utilisateur.
  • Admin : menu Sécurité → Utilisateurs & accès (utilisateurs, rôles, sessions).
  • Bootstrap : au premier démarrage, l'utilisateur AUTH_ADMIN_USERNAME est créé avec AUTH_ADMIN_PASSWORD (ou un mot de passe aléatoire affiché une fois dans les logs).