Aller au contenu principal

API du central

L'API centrale expose des endpoints REST pour l'inventaire des nodes, le dispatch d'actions et la synchronisation DNS CoreDNS. Elle s'appuie sur PostgreSQL (données métier nodes/actions) et délègue les logs à l'API logs Python (central-mercure), qui est le seul composant à dialoguer avec Elasticsearch.

En complément, un microservice indépendant central-dnsdhcp (Go) expose le CRUD DNS/DHCP via HTTP, avec sa base PostgreSQL dédiée (distincte de vpass). Saturn sert de façade REST pour le frontend et relaie DNS/DHCP vers ce service en gRPC interne.

API REST (central/saturn/cmd/saturn/main.go)

MéthodeCheminDescription
GET/healthSanté API + état PostgreSQL et API logs.
GET/api/nodesListe des nodes connus (PostgreSQL).
POST/api/nodes/upsertAjoute/met à jour un node (id, nom, IP).
POST/api/nodes/{id}/actionsEnfile une action pour un node.
GET/api/actionsListe les actions récentes (filtre node_id optionnel).
GET/api/logsRequête des logs (limit, node_id, level) via l'API logs.
GET/api/dns/recordsListe des enregistrements DNS (relayé vers central-dnsdhcp).
POST/api/dns/records/upsertAjoute/met à jour un enregistrement DNS (relayé vers central-dnsdhcp).
DELETE/api/dns/records/{hostname}Supprime un enregistrement DNS.
POST/api/dns/syncGénère hosts.leukos depuis les records DNS renvoyés par central-dnsdhcp.
GET/api/dhcp/recordsListe des baux DHCP (relayé vers central-dnsdhcp).
POST/api/dhcp/records/upsertAjoute/met à jour un bail DHCP (relayé vers central-dnsdhcp).
DELETE/api/dhcp/records/{client_id}Supprime un bail DHCP.

API DNS/DHCP (central/dnsdhcp/cmd/dnsdhcp/main.go)

MéthodeCheminDescription
GET/healthSanté service + PostgreSQL dédié DNS/DHCP.
GET/api/dns/recordsListe DNS records.
POST/api/dns/recordsCrée un DNS record.
GET/api/dns/records/{id}Lit un DNS record.
PUT/api/dns/records/{id}Met à jour un DNS record.
DELETE/api/dns/records/{id}Supprime un DNS record.
GET/api/dhcp/recordsListe DHCP records.
POST/api/dhcp/recordsCrée un DHCP record.
GET/api/dhcp/records/{id}Lit un DHCP record.
PUT/api/dhcp/records/{id}Met à jour un DHCP record.
DELETE/api/dhcp/records/{id}Supprime un DHCP record.

Mécanisme de commande node

Le central reçoit une action logique puis la transforme en commande node :

  1. POST /api/nodes/{id}/actions depuis le frontend central.
  2. Persistance en base (queued) puis prise en charge par le dispatcher.
  3. Routage vers le daemon gRPC du node pour les domaines supportés (relay, valve, display) avec fallback ports 19080 puis 9080.
  4. Fallback HTTP http://<node_ip>:8080/relay/... ou /valve/... pour compatibilité des nodes sans daemon gRPC.
  5. Le domaine display (LCD) est gRPC uniquement et cible par défaut le plugin arduino_atmega2560.
  6. Mise à jour du statut d'action (sent ou failed).

DNS source de vérité (Option 2)

Le central applique une architecture "DB -> fichier DNS" :

  1. les records DNS sont persistés dans la base dédiée DNS/DHCP (central-dnsdhcp) ;
  2. l'API génère central/coredns/hosts.leukos à chaque modification ;
  3. CoreDNS recharge automatiquement ce fichier (reload 5s).

Cette approche garde la traçabilité et évite de gérer DNS en écriture directe dans le serveur.

Logs nodes -> Mercure -> Elasticsearch

Le endpoint GET /api/logs de l'API centrale ne touche pas Elasticsearch directement : il appelle l'API logs Python (http://central-mercure:8140) via l'adaptateur internal/adapters/logsapi.

L'ingestion n'est pas exposée par Saturn : les nodes publient leurs logs directement vers Mercure (POST /logs), qui les met en file Kafka puis les indexe dans Elasticsearch.

C'est l'API logs qui indexe et requête les index journaliers leukos-node-logs-YYYY.MM.DD.

Pour la corrélation machine, les logs doivent inclure :

  • node_id au niveau du payload,
  • meta.machine_id (ID machine),
  • meta.mac (adresse MAC principale).

Exemples REST

# Santé API + stockages
curl http://central:8130/health

# Lister les nodes connus
curl http://central:8130/api/nodes

# Upsert d'un node
curl -X POST http://central:8130/api/nodes/upsert \
-H 'Content-Type: application/json' \
-d '{"id":"node-01","name":"Serre A","ip":"10.20.0.21"}'

# Enfiler une action node
curl -X POST http://central:8130/api/nodes/node-01/actions \
-H 'Content-Type: application/json' \
-d '{"action":"relay/on","params":{"relay_id":"1","value":"on"}}'

# Envoyer un message LCD vers le plugin par défaut arduino_atmega2560
curl -X POST http://central:8130/api/nodes/node-01/actions \
-H 'Content-Type: application/json' \
-d '{"action":"display","params":{"operation":"Bonjour LeukOS"}}'

# Ingestion d'un log node (direct Mercure)
curl -X POST http://mercure:8140/logs \
-H 'Content-Type: application/json' \
-d '{"node_id":"node-01","level":"error","message":"mqtt connect failed","meta":{"machine_id":"f7f2d7b7f8c54c17b1a2fdb4c0ec8e90","mac":"dc:a6:32:11:22:33"}}'

# Upsert DNS record + sync
curl -X POST http://central:8130/api/dns/records/upsert \
-H 'Content-Type: application/json' \
-d '{"hostname":"node-01.leukos.lan","ip":"10.20.0.21","enabled":true}'

curl -X POST http://central:8130/api/dns/sync