API d'administration
Les routes du port d'administration de la passerelle - sondes, configuration en vigueur, simulation, journaux, métriques - avec un appel et sa réponse.
RéférenceExploitationDepuis la version 0.1.0
Sur cette page
API d'administration : contrat OpenAPILe contrat complet de cette API : paramètres, corps, réponses et schémas.
La passerelle sert son administration sur un port à elle, :9090 par défaut
(FLEXWAY_ADMIN_ADDR), jamais sur le port du trafic. Le contrat complet de cette surface est publié
avec la documentation, au format OpenAPI 3.1 (admin.openapi.yaml) ; cette page en donne l'usage.
Prudence
Ce port ne doit jamais être routable de l'extérieur : /config liste les émetteurs et les amonts,
/errors les erreurs de tous les tenants, /simulate décrit chaque décision. Ne l'ouvrez qu'à
l'orchestrateur, au collecteur de métriques et à la console. En Kubernetes, le chart lui donne son
propre Service ClusterIP et une NetworkPolicy activée par défaut.
| Route | Rôle | Depuis |
|---|---|---|
GET /healthz |
Vivacité du processus | 0.1.0 |
GET /readyz |
Prêt à servir | 0.1.0 |
GET /config |
Configuration en vigueur, secrets masqués | 0.1.0 |
GET /metrics |
Métriques au format Prometheus | 0.2.0 |
POST /simulate |
Décision sur une requête décrite, sans l'amont | 1.0.0 |
POST /simulate/mqtt |
Décision de l'écouteur MQTT sur un paquet décrit, sans le courtier | 1.7.0 |
GET /events |
Journal des évènements de la réplique | 1.2.0 |
GET /errors |
Journal des erreurs récentes de la réplique | 1.3.0 |
GET /sparkplug/nodes |
Table des nœuds Sparkplug B de la réplique | 1.7.0 |
GET /healthz
Le processus est vivant - jamais un avis sur sa configuration : un processus vivant mais pas prêt doit
être laissé tranquille, pas redémarré en boucle. Toujours 200.
curl -s http://localhost:9090/healthz
# {"status":"ok","uptime_sec":42}GET /readyz
Une configuration est chargée et servie. 200 avec le nombre d'opérations ; 503 avec la raison avant
le premier chargement et dès le début d'un arrêt (la réplique sort de la rotation avant de drainer).
curl -s http://localhost:9090/readyz
# 200 {"status":"ready","operations":3}
# 503 {"status":"not ready","reason":"no snapshot loaded yet"}GET /config
Chaque clé de flexway.yaml telle que chargée, les valeurs secrètes masquées, plus ce que la passerelle
en déduit : build (version et commit), config_version, config_digest, last_reload, catalog
(les opérations servies), chains (la chaîne de politiques de chaque opération et sa provenance) et,
quand ils sont configurés, agents, kafka, ai, a2a, mcp_federation. 503 not_ready tant
qu'aucune configuration n'est chargée.
curl -s http://localhost:9090/config | jq '{build, config_digest, last_reload}'GET /metrics
L'exposition Prometheus des métriques de la passerelle (text/plain). Leurs noms et dimensions sont une
surface stable depuis 1.0.0 : voir Observer.
curl -s http://localhost:9090/metrics | grep '^flexway_'POST /simulate
Ce que la passerelle ferait d'une requête décrite : routage, origine, autorisation contre l'identité
décrite (aucun jeton n'est vérifié), liste blanche, validation, chaîne de politiques - puis arrêt avant
l'amont : aucun jeton échangé, aucun seau ni quota débité, rien compté. method, host et path sont
obligatoires ; headers et identity (issuer, subject, tenant, scopes, roles) facultatifs.
curl -s http://localhost:9090/simulate -d '{"method":"GET","host":"api.example.com","path":"/orders?status=open",
"identity":{"issuer":"customers","subject":"alice","tenant":"acme","scopes":["orders:read"]}}'200 avec verdict (served ou refused), status, code d'un refus, operation, upstream,
chain, les politiques appliquées et la requête sortante quand elle est servie ; 400 malformed_request si la description est incomplète.
POST /simulate/mqtt
Ce que l'écouteur MQTT des appareils ferait d'un paquet décrit (publish, subscribe ou will, le
testament d'un CONNECT) d'un appareil décrit (identity : kind token, api_key ou certificate,
id d'une clé ou d'un client auth.mtls, issuer, subject, tenant, scopes, claims, champs du
certificat) : opérations que l'identité satisfait, canaux aux valeurs liées écrites, jokers contenus,
groupes $share/, QoS, Response Topic - puis arrêt avant le courtier : rien n'est ouvert, ni débit ni
quota débité, rien compté. packet, topic et identity sont obligatoires. 404 sans écouteur MQTT.
curl -s http://localhost:9090/simulate/mqtt -d '{"packet":"publish","topic":"plant/acme/press-07/telemetry","qos":1,
"identity":{"kind":"api_key","id":"press-07"}}'200 avec verdict (served ou refused), reason_code et cause d'un refus, operation,
upstream, le topic ou filtre written vers le courtier, la qos qu'il voit et le client_id lié ;
400 malformed_request si la description est incomplète.
GET /events
Ce qui s'est passé sur la réplique qui répond : rechargements (reload), transitions des
coupe-circuits (breaker), délestage (shedding), chaînes d'agents refusées (delegation). Les 128
derniers évènements de chaque sorte, du plus récent au plus ancien, en mémoire - perdus au redémarrage.
Jamais un tenant ni rien de ce qu'un appelant a envoyé.
curl -s http://localhost:9090/events | jq '.events[0]'
# {"at":"...","kind":"reload","result":"loaded","version":"7fbb3dc21e1b"}GET /errors
Les erreurs récentes de la réplique qui répond, en trois anneaux de 256 (upstream, refused,
internal), du plus récent au plus ancien, au plus 20 écritures par seconde et par sorte (au-delà,
l'erreur est comptée dans dropped de sa sorte). Chaque entrée porte l'opération, l'amont, le tenant
vérifié, le statut, le code, l'étape, la cause, la durée et la trace quand elle est échantillonnée ;
jamais le chemin reçu, les en-têtes ni le corps.
curl -s http://localhost:9090/errors | jq '.errors[0]'GET /sparkplug/nodes
La table des nœuds Sparkplug B et des applications hôtes qui traversent la réplique qui répond : état (online,
offline, moved, unknown), bdSeq, écarts, nombre d'appareils (devices_online, devices_total), commandes
admises et refusées ; ?tenant= filtre un tenant, ?tenant=&node= rend ce seul nœud avec la liste de ses appareils.
La liste ne porte jamais les appareils : au plus max_nodes entrées aux champs bornés (un identifiant fait 255
octets au plus).
Bornée par observability.sparkplug, perdue au redémarrage ; 404 sans écouteur MQTT. Les noms de nœuds n'existent
que là, jamais dans une métrique (Sparkplug B et OPC UA PubSub JSON).
curl -s 'http://localhost:9090/sparkplug/nodes?tenant=acme' | jq '.nodes[0].state'Route inconnue
Toute autre route répond 404 en application/problem+json (RFC 9457), comme toute erreur de cette
surface :
{
"type": "https://flexway.dev/problems/not_found",
"title": "No operation is declared for this route",
"status": 404,
"detail": "No such admin route.",
"instance": "/debug/pprof/",
"code": "not_found"
}