Un seul binaire Go : API de la console, fichiers de la console React, proxy vers le catalogue Keystone.
Go Console React amontopenkeel-skyline
Le module
OpenKeel implementation in Go of OpenStack skyline-apiserver, the back end of the Skyline dashboard, generated from the reverse-specification of branch stable/2026.2 by the generate-go-from-spec skill. skyline-console runs unchanged against it: same routes under /api/openstack/skyline/api/v1, same session cookie and JWT, same profile, list and error bodies. What is reproduced and what differs is in docs/CONFORMANCE.md; the security checklist, including the session key handling, is in docs/SECURITY.md.
One image and one process do what the Python container did with nginx and gunicorn:
the Skyline API (login, TOTP, WebSSO, profile, project and region switch, aggregated lists of servers, volumes, snapshots and ports, policies for the UI, settings, Prometheus queries, and the OpenKeel addition GET /extension/server_metrics: CPU, memory and disk usage of the project's instances for the console's Metrics page);
the skyline-console files under /, with the single-page fallback; they are built into the image (/usr/share/skyline-console) from the stable/2026.2 sources;
the reverse proxy /api/openstack/<region>/<service>/ to the OpenStack APIs of the Keystone catalog, re-read every minute (no restart when the catalog changes).
Peers: Keystone (openkeel-keystone), Nova, Cinder, Glance, Neutron through the catalog, Prometheus, and a small MariaDB Galera database (revoked_token, settings).
Name: openkeel-skyline, not openkeel-skyline-apiserver, because the project covers the Skyline server side as a whole (the API and the nginx of the Python container) while skyline-console stays upstream. The binary keeps the upstream name skyline-apiserver; the reverse-specification is reverse-spec-skyline-apiserver/.
Go module: github.com/openkeel/openkeel-skyline
Binary: skyline-apiserver (API, console and proxy on port 9998, health and readiness on 9090)
Configuration: YAML, see config/config.example.yaml
Setting up a development environment, the database and the tests: docs/GETTING-STARTED.md
Database schema, migrations and upgrades: docs/DATABASE.md
Extrait de openkeel-skyline/README.md (en anglais).
API REST
30 opérations de l'API REST d'origine (routes et actions de corps), et leur état dans OpenKeel.
La cible est la skyline-console inchangée : les scénarios enregistrés sont rejoués avec leurs appels sortants, les politiques et les jetons de session sont comparés à Python, et la console compilée est rejouée contre Go.
Rejeu des échanges enregistrés
Rejeu E2E avec appels sortants
Les scénarios enregistrés donnent le même statut, le même corps et les mêmes cookies, et les mêmes appels non Keystone vers OpenStack dans le même ordre.
Exécution
make e2e contre internal/fakeos, sur go-mysql-server et MariaDB 11.4.
Dernier résultat 44 / 45 identiques sur les deux moteurs, 1 différence volontaire ; 118 appels sortants au lieu de 222.
Source : openkeel-skyline/docs/CONFORMANCE.md
Tests unitaires et golden tests
Vecteurs de politique et JWT de session
Toutes les règles de politique embarquées décident comme oslo.policy, et le jeton de session est identique à l'octet près à celui de python-jose.
Exécution
internal/skypolicy/testdata/policy-vectors.json et internal/session/session_test.go.
Dernier résultat 1 862 règles × 7 personas identiques ; JWT identique à l'octet près pour la même charge utile et la même clé.
Source : openkeel-skyline/docs/CONFORMANCE.md
Contrat client
Rejeu smoke de skyline-console
Les requêtes enregistrées avec la console compilée obtiennent les statuts enregistrés, et les appels relayés atteignent leurs endpoints avec les en-têtes attendus.
Exécution
test/e2e/console_test.go avec E2E_CONSOLE_DIR sur les fichiers de console de l'image.
Dernier résultat 35 / 35.
Source : openkeel-skyline/docs/CONFORMANCE.md
De bout en bout sur un lab
Exécution en direct contre le Keystone Go
Connexion, profil, politiques, changement de projet, endpoints contrib, texte de mot de passe erroné, déconnexion et proxy Keystone fonctionnent contre openkeel-keystone.
Exécution
Exécution en direct contre un Keystone Go alimenté par MariaDB, endpoint d'identité uniquement.
Dernier résultat Politiques d'admin système : 1 817 / 1 860 autorisées, comme Python face à son simulacre.
Source : openkeel-skyline/docs/CONFORMANCE.md
Concurrence sur Galera
Concurrence sur MariaDB Galera
Les premières écritures concurrentes d'un même paramètre et les déconnexions concurrentes restent cohérentes sur trois nœuds.
Exécution
make galera-test sur galera1 à galera3.
Dernier résultat Réussi, 3 exécutions sur 3 : une ligne, même valeur sur chaque nœud, 0 × 5xx.
Source : openkeel-skyline/docs/CONFORMANCE.md
Scénario
Suite Cypress de skyline-console
La propre suite Cypress de la console contre les services Go.
Exécution
Nécessite les services Go dans un cluster kind (Skyline Python dans kind : 31 / 34).
Dernier résultat Non exécuté.
Source : openkeel-skyline/docs/CONFORMANCE.md
Écarté de la réécriture
Skyline devient un seul binaire Go qui sert la console, son API et le proxy, sans nginx généré, sans l'option CORS ni les routes de documentation FastAPI.
Mécanique interne simplifiée
nginx et skyline-nginx-generator
Pourquoi c'est écarté
Le serveur Go sert le build de la console et relaie les API OpenStack avec les règles de chemins du générateur.
Pourquoi la solution n'est pas affectée
Les changements du catalogue sont relus toutes les 60 s au lieu d'exiger un redémarrage, et le démarrage n'échoue plus quand Keystone est indisponible.
Source : openkeel-skyline/docs/CONFORMANCE.md
Obsolète ou inutilisé en amont
Origines autorisées CORS
Pourquoi c'est écarté
La console est servie depuis la même origine, et l'option empêche de toute façon le démarrage sur Starlette 1.x.
Pourquoi la solution n'est pas affectée
Aucun pour la console, servie depuis la même origine que son API.
Source : openkeel-skyline/docs/CONFORMANCE.md
Mécanique interne simplifiée
Routes de documentation FastAPI et générateurs hors ligne
Pourquoi c'est écarté
/docs, /redoc et openapi.json ne sont pas servis, et les générateurs policy-manager, swagger et sample-config sont des outils hors ligne du paquet Python.
Pourquoi la solution n'est pas affectée
Le document OpenAPI se trouve dans la reverse-spec et les règles de politique sont intégrées ; la console n'utilise pas ces routes.
Source : openkeel-skyline/docs/CONFORMANCE.md
Seul ce qui a été écarté par choix de conception figure ici ; le travail pas encore fait se trouve dans les Known gaps du docs/CONFORMANCE.md du module. Tous les modules
Interactions de Skyline
Vue « service » générée par la skill diagramme depuis le modèle d'OpenKeel.