Saltar a contenido

Intercambio del metadata sin sesión#

El intercambio del metadata sin sesión deja que un script o la integración continua exporten el metadata de una conexión como paquete, lo analicen en otra y lo importen, sin cookies ni contraseñas. Sirve para automatizar el paso de desarrollo a pruebas y a producción, y para guardar el metadata en un repositorio de código.

Antes de empezar#

  • La credencial la crea quien tiene Administración del Sistema, a nombre de un usuario que tenga Administración del Metadata (véase Credenciales de servicio). Su ámbito es Intercambio del metadata y va sola.
  • Lo que se hace es lo mismo que Exportar e importar del editor del metadata, con las mismas reglas y el mismo informe. Conviene conocer antes ese proceso en la aplicación (véase el capítulo del metadata).
  • En cada petición se vuelven a leer los privilegios del titular: si pierde Administración del metadata, la credencial deja de servir (403 NOT_ALLOWED).

Funciona también en una instalación que solo entra con el inicio de sesión único, donde no hay contraseñas que poner en un script.

Crear la credencial#

  1. Vaya a Administración › Credenciales y pulse Nueva credencial….
  2. En Ámbito, elija Intercambio del metadata.
  3. Elija el Titular: un usuario con Administración del metadata. Los demás aparecen sin poder elegirse.
  4. Escriba el Nombre del cliente («Integración continua del metadata») y la caducidad: 90 días por defecto, como mucho 365.
  5. Pulse Crear credencial y guarde el secreto en el almacén de secretos de la integración continua.

Consejo

Cree un usuario dedicado, con Administración del metadata y nada más, como titular de la credencial del script. Así la auditoría distingue lo que hace el script de lo que hacen las personas, y puede quitarle el privilegio sin afectar a nadie.

Rutas#

Todas van bajo /api/metadata-exchange/v1, con Authorization: Bearer ect_…. La cookie de sesión no sirve.

Ruta Qué hace
GET /connections Las conexiones que puede usar el titular: [{ id, name, engine, hasMetadata }]. Si la credencial se limita a unas, solo esas.
GET /connections/{c}/export?rowFilters=&diagram=&groupings= El paquete, un .zip. La cabecera X-ECenter-Export-Summary resume lo que lleva.
POST /connections/{c}/imports[?preview=true][&confirmed=true] Sube el paquete y lanza el análisis (preview=true) o la importación: 202 { job, status } con Location.
GET /connections/{c}/imports/{job}[?wait=30s][&format=csv] El informe del trabajo cuando termina, o 202 si sigue tras esperar wait (10 s si no se dice; como mucho 30 s). Con format=csv, el informe en CSV.

Opciones de la exportación:

Parámetro Por defecto Qué hace
rowFilters false Lleva también los universos.
diagram true Lleva la disposición del diagrama de relaciones.
groupings true Lleva las agrupaciones con sus valores.

El paquete no lleva nada de la instalación (ni la URL de la conexión, ni su usuario, ni logins), y dos exportaciones del mismo metadata dan el mismo fichero: se puede versionar en Git y comparar.

El recorrido#

1. Exportar#

export ECENTER_URL=https://desarrollo.ecenter.example.org
export ECENTER_METADATA_TOKEN=ect_…
curl -s "$ECENTER_URL/api/metadata-exchange/v1/connections/$ORIGEN/export" \
  -H "Authorization: Bearer $ECENTER_METADATA_TOKEN" -o metadata.zip

2. Analizar en el destino#

Se sube el paquete como multipart/form-data con dos partes: package (el zip) y, opcionalmente, options (JSON).

curl -s -X POST "$ECENTER_URL/api/metadata-exchange/v1/connections/$DESTINO/imports?preview=true" \
  -H "Authorization: Bearer $ECENTER_METADATA_TOKEN" \
  -F "package=@metadata.zip;type=application/zip" \
  -F 'options={"missing":"KEEP"};type=application/json'
{ "job": "4b1d…", "status": "QUEUED" }
Opción Qué hace
schemas Empareja el nombre lógico de un esquema del paquete con un esquema del destino: { "COMERCIAL": "PROD_COMERCIAL" }.
privileges Empareja a mano la clave de un privilegio del paquete con un privilegio del destino.
createPrivileges true crea, sin asignarlos a ningún rol, los privilegios del paquete que falten.
missing KEEP (por defecto) conserva lo que está en el destino y no en el paquete; REMOVE lo elimina.
diagram IF_EMPTY (solo si el destino no tiene disposición), REPLACE o KEEP.
basis La base de un análisis anterior (abajo).

3. Leer el informe#

curl -s "$ECENTER_URL/api/metadata-exchange/v1/connections/$DESTINO/imports/4b1d…?wait=30s" \
  -H "Authorization: Bearer $ECENTER_METADATA_TOKEN"

Mientras el trabajo sigue, responde 202; repita la petición. Al terminar, 200 con el informe:

{
  "outcome": "ANALYZED",
  "basis": "sha256:9f2c…",
  "tallies": [
    { "kind": "FACT_TABLE", "inPackage": 8, "created": 1, "changed": 2, "unchanged": 5,
      "onlyInTarget": 0, "removed": 0, "pairedByName": 0 } ],
  "issues": [ { "severity": "WARNING", "code": "NOT_IN_CATALOG", "kind": "FACT_TABLE",
                "element": "Devoluciones",
                "message": "La tabla PROD_COMERCIAL.DEVOLUCIONES no existe en la base de datos" } ],
  "impact": { },
  "requiresConfirmation": true
}
  • outcome: ANALYZED, IMPORTED, REJECTED (hay errores), METADATA_IN_USE, METADATA_IMPACT (el cambio afecta a documentos que lo usan) o METADATA_CHANGED (el destino cambió desde el análisis).
  • issues[].severity: ERROR impide importar; WARNING hay que confirmarlo; INFO es para saberlo.
  • requiresConfirmation: hay avisos o un impacto que una persona debería revisar.
  • El informe nunca trae condiciones de universos ni fragmentos de SQL.

4. Importar#

Con la base del análisis, para que la importación no entre si el destino ha cambiado entre medias:

curl -s -X POST "$ECENTER_URL/api/metadata-exchange/v1/connections/$DESTINO/imports" \
  -H "Authorization: Bearer $ECENTER_METADATA_TOKEN" \
  -F "package=@metadata.zip;type=application/zip" \
  -F 'options={"missing":"KEEP","basis":"sha256:9f2c…"};type=application/json'

El paquete viaja en cada petición: el servidor no lo guarda entre el análisis y la importación. Si el análisis pedía confirmación, la importación necesita además confirmed=true; antes de añadirlo en un script, piense si de verdad quiere aceptar sin revisar lo que ha cambiado.

El script de ejemplo#

El repositorio trae tools/demo-data/metadata_promote.py, en Python y sin dependencias, que hace todo el recorrido como lo haría la integración continua y solo importa si no hay nada que confirmar:

export ECENTER_URL=https://ecenter.example.org
export ECENTER_METADATA_TOKEN=ect_…
python3 tools/demo-data/metadata_promote.py --source "Desarrollo" --target "Producción" --analyze-only
Opción Qué hace
--source, --target La conexión de origen y la de destino, por su nombre o su identificador.
--analyze-only Solo analiza; nunca importa.
--package, --save Promociona un paquete guardado en lugar de exportar el origen; guarda el exportado en un fichero.
--row-filters, --no-diagram, --no-groupings Las opciones de la exportación.
--remove-missing Elimina del destino lo que no está en el paquete.
--create-privileges Crea sin asignar los privilegios que falten.

Sus códigos de salida sirven para decidir en la integración continua:

Código Significado
0 Promocionado (o, con --analyze-only, analizado sin nada que confirmar).
2 Hay algo que confirmar: decídalo una persona en el asistente de importación de la aplicación. No se ha aplicado nada.
3 Errores o algo que lo impide. No se ha aplicado nada.
4 El destino ha cambiado desde el análisis: vuelva a lanzarlo.
1 Ha fallado la API o la red.

Errores#

HTTP code Cuándo
400 INVALID_PACKAGE No es un zip, falta el manifiesto o un fichero no se lee.
400 UNSUPPORTED_FORMAT El paquete es de una versión más nueva de ECenter.
400 INVALID_REQUEST Las opciones no son válidas.
403 NOT_ALLOWED El titular ya no tiene Administración del metadata, o la credencial no incluye la conexión.
404 NOT_FOUND La conexión o el trabajo no existen, o el trabajo no es de esta credencial.
409 IMPORT_IN_PROGRESS Hay otra importación o restauración en curso en esa conexión.
409 JOB_CANCELED El trabajo se canceló (por ejemplo, al revocar la credencial). No dejó nada.
410 RESULT_EXPIRED El informe ya no se conserva.
413 PACKAGE_TOO_LARGE El paquete pasa de los topes.
500 JOB_FAILED El trabajo ha fallado.

Seguridad y auditoría#

  • El trabajo corre con la identidad del titular y solo lo ve esa misma credencial: desde una sesión del mismo usuario, 404.
  • Revocar la credencial, o inhabilitar, bloquear o borrar al titular, corta en la petición siguiente y cancela sus análisis e importaciones en curso. Un trabajo cancelado no deja nada: un análisis se deshace siempre, y una importación se deshace entera.
  • Las copias del metadata y restaurarlas no van por esta superficie: se hacen en la aplicación.
  • La auditoría anota cada exportación e importación con el canal API y la referencia de la credencial; los análisis no se anotan.

Véase también#