Aller au contenu principal

Saturn

Saturn API de supervision

Saturn est l'API centrale de supervision de flotte. Elle orchestre l'inventaire des nodes, le dispatch d'actions et les integrations DNS/DHCP.

Le service est implemente en Go et expose principalement une API REST sur le port :8130. Pour certaines integrations internes, Saturn peut aussi communiquer en gRPC.

  • Inventaire : gestion des nodes, adresses IP et metadonnees d'exploitation.

  • Actions : mise en file, journalisation et dispatch des commandes operateur vers les nodes.

  • Reseau : relais DNS/DHCP via le service central-dnsdhcp.

  • Logs : consommation des logs via central-mercure (sans acces direct a Elasticsearch).

Endpoints principaux​

MéthodeCheminDescription
GET/healthSanté API + état PostgreSQL et API logs.
GET/api/nodesListe des nodes connus.
POST/api/nodes/upsertAjoute ou met à jour un node.
POST/api/nodes/{id}/actionsEnfile une action pour un node.
GET/api/actionsListe des actions récentes.
GET/api/logsRequête des logs via Mercure.

IAM natif: login email et bootstrap utilisateurs​

Le provider natif de Saturn impose une authentification par email uniquement:

  • l'identifiant HTTP Basic de /api/auth/login et /api/auth/token (grant password) doit etre un email;
  • l'email est aussi persiste comme username technique (alignement strict);
  • un changement d'email met a jour la cle de connexion.

Pour initialiser des comptes admin automatiquement au demarrage, Saturn peut charger un fichier JSON (idempotent: creation si absent, mise a jour sinon).

Variables d'environnement:

  • AUTH_BOOTSTRAP_USERS_ENABLED=true|false
  • AUTH_BOOTSTRAP_USERS_FILE=/data/config/users.json
  • AUTH_ADMIN_EMAIL=admin@leukos.local (fallback si aucun utilisateur existant)

Exemple users.json:

[
{
"email": "admin1@example.com",
"password": "StrongPass@123",
"display_name": "Admin One",
"roles": ["admin"]
}
]

Notes:

  • les roles du bootstrap sont forces a admin pour ces comptes;
  • au redemarrage, Saturn ne duplique pas les utilisateurs existants.

Comment Saturn se connecte aux autres APIs​

Saturn est expose en REST pour les clients amont, puis agit en client sortant vers les autres services de la flotte.

Source / cibleProtocoleExempleUsage
Venus -> SaturnHTTP RESTGET /api/nodesInventaire, actions, DNS/DHCP, logs.
Saturn -> MercureHTTP RESTGET /logs?node_id=node-01&level=errorLecture des logs agreges.
Saturn -> DNSDHCPgRPC interneUpsertDnsRecord, DeleteDhcpRecordCRUD DNS/DHCP via service dedie.
Saturn -> NodegRPC prioritaireRelaySet, ValveSet, DisplayOperationPilotage temps reel sur daemon node.
Saturn -> Node (fallback)HTTP RESTPOST /relay/on, POST /valve/openCompatibilite nodes sans gRPC actif.

Connexion aux nodes: gRPC puis fallback HTTP​

Le dispatcher Saturn applique une strategie en deux etapes:

  1. tentative gRPC sur le daemon node pour les domaines supportes;
  2. si indisponible, repli HTTP sur l'API locale node.
// Exemple d'intention: sequence simplifiee de dispatch.
func dispatchNodeAction(ctx context.Context, nodeIP string, action Action) error {
// 1) Tentative gRPC (ports historiques supportes)
if err := tryGRPC(ctx, nodeIP, 19080, action); err == nil {
return nil
}
if err := tryGRPC(ctx, nodeIP, 9080, action); err == nil {
return nil
}

// 2) Fallback HTTP pour compatibilite
endpoint := mapActionToHTTP(action) // ex: /relay/on, /valve/close
return postJSON(ctx, "http://"+nodeIP+":8080"+endpoint, action.Payload)
}

Exemple d'appel HTTP vers un node (fallback):

curl -X POST http://10.20.0.21:8080/relay/on \
-H 'Content-Type: application/json' \
-d '{"relay_id":"1","value":"on"}'

Donnees metier et reseau​

Saturn est le point d'entree metier pour la supervision, mais s'appuie sur des services infra specialises.

  • PostgreSQL (leukos_central) : persistance des utilisateurs, inventaire nodes, etat de connectivite et historique d'actions.
  • central-dnsdhcp : source de verite DNS/DHCP, consommee par Saturn en gRPC interne.
  • CoreDNS : resolution DNS locale de la flotte (*.leukos.lan), alimentee via les synchronisations DNS.

Integration DNS/DHCP​

Saturn ne porte pas la logique de stockage DNS/DHCP localement : il delegue les mutations et lectures au service dedie, puis orchestre la synchronisation DNS necessaire a l'exploitation.

Exemple d'operation API cote Saturn:

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

Exemples de code d'integration​

Appel Mercure depuis Saturn (REST)​

// Exemple d'adaptateur REST pour requeter les logs via Mercure.
func (c *LogsClient) QueryLogs(ctx context.Context, nodeID, level string, limit int) ([]LogItem, error) {
req, _ := http.NewRequestWithContext(
ctx,
http.MethodGet,
c.baseURL+"/logs?node_id="+url.QueryEscape(nodeID)+"&level="+url.QueryEscape(level)+"&limit="+strconv.Itoa(limit),
nil,
)
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode >= 400 {
return nil, fmt.Errorf("mercure returned status %d", resp.StatusCode)
}

var out struct{ Items []LogItem `json:"items"` }
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, err
}
return out.Items, nil
}

Appel DNS/DHCP depuis Saturn (gRPC)​

// Exemple d'appel gRPC interne vers le service DNS/DHCP.
func (c *DNSDHCPClient) UpsertDNS(ctx context.Context, host, ip string) error {
_, err := c.grpc.UpsertDnsRecord(ctx, &dnspb.UpsertDnsRecordRequest{
Hostname: host,
Ip: ip,
Enabled: true,
})
return err
}

Flux de commande node​

  1. Le frontend envoie une action à Saturn.
  2. Saturn persiste et marque l'action queued.
  3. Le dispatcher tente un routage gRPC pour les domaines supportés.
  4. En fallback, Saturn utilise HTTP vers l'API locale node si nécessaire.
  5. Le statut final est publié (sent ou failed).

Voir aussi​