Catalog Manager¶
AKKO Catalog Manager est le backend en libre-service et le module cockpit qui
permettent aux admins de gérer les catalogues Trino à chaud. Il s'appuie sur la
gestion dynamique des catalogues de Trino 481 (catalog.management=dynamic,
catalog.store=file) : ajouter, éditer ou supprimer un catalogue se fait
sans downtime et sans helm upgrade.
Refondu en 2026-06 (spec
catalog-onboarding-refonte-2026-06). L'ancienne API/api/admin/catalogset ses 4 surfaces cockpit superposées ont été retirées après la bascule ; l'API canonique est/api/catalogset le cockpit n'expose qu'UNE surface : le modulecatalog-onboarding.
Connecteurs supportés¶
La liste des connecteurs est pilotée par les données : le formulaire
cockpit rend ce que retourne GET /api/catalogs/connectors (pattern registry,
extensible en YAML via CONNECTOR_SPECS_DIR sans modifier le code).
| Catégorie | Connecteurs |
|---|---|
| Relationnel (JDBC) | PostgreSQL, MySQL, SQL Server, Oracle, ClickHouse, Redshift |
| Lakehouse | Iceberg (REST / Polaris), Iceberg (HMS), Hive + Kerberos, Delta Lake |
| NoSQL / Streaming | MongoDB, Cassandra, Elasticsearch, Kafka |
| Échappatoire | Personnalisé (connector.name + propriétés brutes) |
Architecture¶
Module cockpit pages/catalog-onboarding/ (MVC, surface unique)
│ HTTPS + cookie SSO
▼
nginx (akko-cockpit-react) /api/catalog-manager/ → injecte le Bearer
▼
Hôte FastAPI (akko-catalog-manager) + package catalog_manager
│ 1. vérifie le JWT → rôle akko-admin requis
│ 2. registry → builder par famille → propriétés (pattern Strategy)
│ 3. secrets → credential FILE sur le PVC catalogue partagé
│ (jamais dans le SQL — Trino journalise le CREATE CATALOG)
│ 4. CREATE CATALOG via /v1/statement en svc-catalog-manager
│ (OPA : identité machine catalog_admin, moindre privilège)
│ 5. saga avec compensation : tout échec annule proprement
│ 6. audit JSON corrélé structuré (secrets caviardés)
▼
Trino 481 — coordinator RW + workers RO sur le PVC /etc/trino/catalog
catalogues plateforme photographiés dans .baseline/ (restore)
Décisions clés :
- Formulaire ⟷ SQL bidirectionnel : le cockpit affiche le
CREATE CATALOGexact pendant la saisie, et re-parse vos éditions SQL vers le formulaire. Le SQL affiché est une projection — le submit envoie{connector, name, config}et le backend régénère le SQL : un drift d'affichage ne peut jamais exécuter autre chose. - Pas d'onglet permissions : l'onboarding enregistre le catalogue (visible des admins par défaut). QUI lit QUOI se gère dans le composant Accès aux données (RBAC plateforme ≠ accès data).
- Édition = plan DROP + CREATE : Trino n'a pas d'
ALTER CATALOG. Le module affiche le plan honnêtement et le backend restaure la définition précédente si le re-CREATE échoue. Les secrets ne sont jamais relus : ressaisissez-les à l'édition. - Suppression / restauration : les catalogues plateforme (provenance
platform) sont photographiés dans un baseline sur le PVC. En supprimer un affiche une bannière de restauration ;POST /api/catalogs/restorerecrée les manquants. Les catalogues client exigent une confirmation par saisie du nom (définitif).
Ajouter un catalogue (cockpit)¶
- Connectez-vous avec le rôle
akko-admin. - Barre latérale → Sources de données.
- + Ajouter une source → choisissez un connecteur, remplissez les champs (l'œil révèle le mot de passe) — ou éditez directement le SQL.
- ⚡ Tester la connexion lance une sonde TCP de pré-vol.
- Créer la source — Trino valide le connecteur au
CREATE CATALOG; le catalogue est actif sur tout le cluster en ~5 s.
Ajouter un catalogue (API)¶
curl -X POST https://cockpit.mon-entreprise.example/api/cockpit/catalog-manager/api/catalogs \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"connector": "postgresql",
"name": "client_pg_01",
"config": {
"host": "db.client.example", "port": "5432",
"database": "ventes", "user": "trino_readonly",
"password": "<caviardé>"
}
}'
# → 201 {name, connector, provenance, sql} (le sql ne contient AUCUN secret)
Les noms de catalogue sont des identifiants SQL Trino nus :
^[a-z][a-z0-9_]{0,40}$ (pas de tiret), system et information_schema
sont réservés, et Trino n'a pas de IF NOT EXISTS — les doublons sont
rejetés avant le CREATE.
API complète¶
| Méthode · chemin | Rôle |
|---|---|
GET /api/catalogs/connectors |
registry des connecteurs (pilote le formulaire) |
GET /api/catalogs/meta |
constantes plateforme pour le codec SQL frontend |
GET /api/catalogs |
liste — live ∪ store ∪ baseline manquants (missing: true) |
GET /api/catalogs/{name} |
détail, propriétés SANS secrets (pré-remplissage édition) |
POST /api/catalogs/preview |
validation + SQL généré, aucun effet de bord |
POST /api/catalogs |
création (saga, credential file, audit) |
PUT /api/catalogs/{name} |
mise à jour = DROP+CREATE avec rollback automatique |
DELETE /api/catalogs/{name} |
idempotent ; retourne restorable + leaky_connector |
POST /api/catalogs/restore |
re-CREATE des catalogues plateforme manquants |
POST /api/catalogs/test |
sonde TCP de pré-vol (timeout 3 s) |
GET /api/catalogs/{name}/status |
compte SHOW SCHEMAS live |
POST /api/catalogs/sql |
mode expert — accepte UNIQUEMENT CREATE/DROP CATALOG |
Hive + Kerberos — comment le keytab arrive à Trino¶
Deux voies distinctes, toutes deux prouvées live :
Voie plateforme (gérée par le chart) — les catalogues de fédération
livrés avec la plateforme (ex. la démo Cloudera) : le keytab vit dans un
Secret Kubernetes monté sur les pods Trino par le chart ; krb5.conf et
les confs hadoop sont des montages niveau JVM/plateforme. C'est ce qui
fait tourner la fédération Cloudera (6,3 M de lignes).
Voie self-service (cockpit / API) — pour les catalogues créés à chaud :
- Sources de données → connecteur Hive → options avancées → activer Authentification Kerberos.
- Renseigner service principal + client principal.
- Coller le keytab en base64 dans le champ Keytab (base64)
(
base64 -w0 mon.keytab), ou envoyerconfig.keytab_b64viaPOST /api/catalogs.
Mécanique backend : le base64 est décodé en binaire et écrit à côté
des credential files sur le PVC catalogue partagé — le seul chemin lisible
par le coordinator ET les workers (les workers ouvrent leurs propres
connexions metastore/HDFS). Le SQL généré référence ce chemin mais ne
contient jamais le keytab (Trino journalise chaque CREATE CATALOG en
intégralité). Le set de propriétés émis est le miroir du catalogue de
fédération prouvé live : auth KERBEROS metastore + fs.hadoop.enabled=true
+ hive.config.resources (confs hadoop montées plateforme, pilotées par
env) + HDFS kerbérisé principal/keytab, impersonation désactivée.
Cycle de vie des tickets : la JVM Trino acquiert et renouvelle les tickets depuis le keytab automatiquement — aucune opération d'expiration à gérer.
Situations d'échec (toutes vérifiées contre le vrai metastore kerbérisé)¶
| Situation | Comportement |
|---|---|
| Mauvais client principal (absent du keytab) | CREATE rejeté par Trino en ~1,5 s, saga annulée, zéro résidu, erreur affichée dans le formulaire |
| Kerberos activé sans keytab fourni | même rejet immédiat + rollback |
| Base64 invalide dans le champ keytab | 400 avant même d'atteindre Trino |
| Metastore injoignable | la sonde TCP de pré-vol le signale avant le submit |
| Keytab + principals valides | catalogue actif, schémas du metastore kerbérisé navigables dans le drill-down de la ligne |
Couverture E2E (tests/e2e/playwright/test_e2e_catalogs_page.py) :
test_26 crée un catalogue Hive+Kerberos via l'interface avec le VRAI
keytab de la démo et prouve le handshake par le drill-down des schémas ;
test_27 prouve le rejet immédiat + rollback sur mauvais principal. Le
keytab est extrait du Secret du cluster au moment du run — jamais commité.
Voir demos/cloudera-simulation/bootstrap-akko-catalog.sh pour la
variante API scriptée.
Modèle de sécurité¶
- Les écritures exigent le rôle realm
akko-admin(JWT vérifié contre le JWKS Keycloak avec discovery OIDC). - Les mots de passe JDBC vont dans un credential file référencé par
credential-provider.type=FILE— jamais dans les propriétés du catalogue, jamais dans leCREATE CATALOG(journalisé intégralement). - Côté Trino, l'identité de service
svc-catalog-managerest une identité machinecatalog_admin: trueUNIQUEMENT : elle gère le cycle de vie des catalogues mais ne peut lire aucune table (NIST AC-6). Elle est seedée viaakko-init.opaSeedPoliciespour que la synchro Keycloak→OPA ne la perde jamais. - Audit : chaque opération émet du JSON structuré corrélé, secrets caviardés.
Dépannage¶
| Symptôme | Cause | Correctif |
|---|---|---|
422 trino_rejected Access Denied: Cannot create catalog |
OPA a perdu le seed svc-catalog-manager |
vérifier akko-init.opaSeedPolicies, relancer le Job opa-sync |
500 Error loading catalogs on worker |
credential file illisible sur les workers | PVC monté RO sur les workers ; fichiers 0644 |
| coordinator en CrashLoop après changement de config | catalog.config-dir / catalog.store.file.path posés |
AUCUN des deux n'est valide en Trino 481 — le dir du file store est toujours /etc/trino/catalog (symlink du launcher) |
| catalogue plateforme supprimé absent | comportement attendu — restaurez-le | bannière → Restaurer depuis le baseline ou POST /api/catalogs/restore |