8.9 KiB
Integración CloudRestoreAS ↔ PANEL_BASES_ANEXO24
Variables de entorno y configuración
Panel (.env) |
CloudRestoreAS (pestaña Config → PANEL) | Debe coincidir |
|---|---|---|
CLOUDRESTORE_API_TOKEN |
panel.api_token |
Sí — mismo valor en todas las instalaciones |
ENCRYPTION_KEY |
— | Solo panel (cifra credenciales de restore_targets) |
URL del panel (ej. https://panel:3000) |
panel.api_url |
Sí — base URL sin barra final |
| — | panel.instance_key |
Nombre de este servidor en el panel (restore_targets.name) |
Generar token:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Generar clave de cifrado (panel):
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
BACKUP_PATH del panel es independiente: lista respaldos en el dashboard. Cada CloudRestoreAS reporta su carpeta local vía instance-config (clave = nombre del servidor).
Enrutamiento automático (todos los CRA)
No hay modos que configurar. Todo CRA con panel hace lo mismo:
- Llega un ZIP a la carpeta de entrada.
GET resolve-route?filename=X&instance=<esta instancia>— el panel identifica el nodo y el servidor asignado.- Si
action=restore_local→ extract + RESTORE aquí (credenciales SQL de este servidor en el panel). - Si
action=forward→ SFTP del ZIP alinput_folderdel destino (credenciales SSH del destino). - Mover ZIP a
processed; reportarcompletedoforwarded.
flowchart TB
ZIP[ZIP en carpeta local]
CRA[Any CRA con instance_key]
Panel["resolve-route"]
SFTP[SFTP al destino]
SQL[RESTORE local]
ZIP --> CRA --> Panel
Panel -->|restore_local| SQL
Panel -->|forward| SFTP
Aplica igual en Alfa, Omega o un hub donde llegan todos los ZIP:
| Situación | Qué hace el CRA |
|---|---|
| Nodo asignado a esta instancia | RESTORE local |
| Nodo asignado a otro servidor | SFTP ZIP al destino |
La decisión la toma el panel (nodo + asignación en Gestión BD), no el operador.
Qué configura cada instalación
| Campo | Para qué |
|---|---|
| URL + token del panel | Conectar al panel |
| Instancia | Identidad de este servidor (restore_targets.name) |
| Carpeta entrada | Dónde vigila ZIPs esta máquina |
El selector de instancia se llena desde GET /api/restore/target-catalog. No hay límite de servidores.
Hub donde llegan todos los ZIP
Ejemplo: máquina Alfa recibe todos los archivos y también tiene bases propias:
- Panel: servidor Alfa registrado; bases de Alfa/Omega/Gamma asignadas en Gestión BD.
- CRA en Alfa: instancia Alfa, misma URL/token que el resto.
- ZIP de base Alfa → RESTORE local.
- ZIP de base Omega → SFTP a carpeta de Omega (card Reportada).
- CRA Omega detecta el ZIP y restaura localmente.
No hay paso extra ni modo especial.
Sin panel (legacy local)
Si panel.api_url está vacío, CloudRestoreAS usa nodos SQLite locales y SQL de la pestaña Config (sin reparto automático).
Config legacy panel.mode
Valores antiguos (orchestrator, hub_restore, colocated) se ignoran. Se registra un aviso en log y se usa siempre resolve-route. El modo hub que subía .bak por SFTP ya no aplica.
Contrato API (/api/restore/*)
Autenticación: Authorization: Bearer <CLOUDRESTORE_API_TOKEN>.
GET /api/restore/target-catalog
Cliente: panel_client.list_restore_target_names()
| Respuesta 200 | Descripción |
|---|---|
targets[] |
{ "id", "name" } — sin credenciales |
GET /api/restore/resolve-route?filename=<zip>&instance=<nombre>
Cliente: panel_client.resolve_route()
| Query | Obligatorio | Descripción |
|---|---|---|
filename |
Sí | Nombre del ZIP (panel resuelve nodo desde el stem) |
instance |
Sí | Instancia de este CRA (restore_targets.name) |
| Respuesta 200 | Descripción |
|---|---|
action |
restore_local o forward |
db_name |
Base resuelta |
node_key |
Nodo en panel |
target |
Servidor destino (SQL/SSH + input_folder) |
| Código | Significado |
|---|---|
| 404 | Sin nodo/base o sin servidor asignado |
| 503 | Destino sin input_folder reportado |
GET /api/restore/target-for?database=<db_name>&instance=<nombre>
Usado por utilidades legacy; el flujo principal de jobs usa resolve-route.
POST /api/restore/job-result
status: completed | failed | forwarded.
POST /api/restore/instance-config
Reporte de carpeta de entrada e identidad del agente (instance_key = nombre del servidor).
Es best-effort: un fallo aquí nunca bloquea una restauración.
{
"input_folder": "D:\\Backups\\Entrada",
"processed_folder": "D:\\Backups\\Procesados", // opcional; el panel la deriva si falta
"host_name": "WIN-RESTORE-01",
"app_version": "1.1.0", // versión instalada → cloudrestore_status.app_version
"platform": "windows", // "windows" | "linux"
"arch": "x86_64", // "x86_64" | "arm64"
"instance_key": "Alfa" // = restore_targets.name
}
platform y arch le dicen al panel qué artefacto le corresponde a este servidor al
instalar o actualizar: a24c.cras_releases se llavea por version + platform + arch. Un
agente viejo que no las mande sigue funcionando; el panel cae al texto libre de
restore_targets.os para la primera instalación.
Respuesta: 200 { "ok": true, "trace_id": "…" }.
POST /api/restore/agent-sync
Dispara la sincronización del catálogo de versiones contra Gitea. Lo usa
publish-release.sh --notify-panel para que una versión recién publicada aparezca de
inmediato, sin esperar a que un admin abra /versiones-cras.
Body vacío ({}). Respuesta: 200 { "ok": true, "discovered": N, "versions": N }.
Distribución de versiones (Gitea → PANEL → servidor)
Los binarios se publican en el registro de paquetes genéricos de Gitea; el panel los
descubre leyendo su API, los cachea verificando el sha256 que Gitea calcula, e instala
por SSH/SFTP en el servidor destino.
build local → Gitea (generic packages) → PANEL (caché + instalador SSH) → servidor
- Publicar: ver BUILD.md §5 (
publish-release.sh). - Instalar/actualizar: panel → Versiones CRAS (
/versiones-cras) → Sincronizar con Gitea → Activar → Instalar en el servidor. - El panel siembra
config/.envconapi_url,api_tokeneinstance_keydurante la instalación, así que el servidor queda operativo sin configuración manual. - El servidor destino no descarga nada de internet: el binario es autocontenido y los bytes llegan del panel por SFTP.
Tablas involucradas: a24c.cras_releases (catálogo de versiones publicadas) y
a24c.cras_install_runs (bitácora de instalaciones con progreso paso a paso).
Agregar servidores adicionales
- Panel → Servidores de Restauración → + Nuevo servidor (incluye credenciales SSH)
- Gestión de Bases de Datos → dropdown servidor por base
- Panel → Versiones CRAS → Instalar en ese servidor (siembra el
.envsolo)
El camino manual sigue disponible: instalar el CRA a mano → Config → instancia → Guardar (card Reportada).
Despliegue inicial
Orden de arranque (migraciones automáticas)
- a24c-postgres — volumen Postgres.
- a24c-backend — aplica
alembic upgrade headal iniciar (incluye tablas CRA:restore_targets,restore_job_logs,cloudrestore_status,restore_target_id). - Panel (
docker compose up) — espera el esquema CRA en Postgres antes de abrir el puerto 3000.
No hace falta ejecutar database/migrations/*.sql a mano: la fuente de verdad es Alembic en a24c.
Panel
cd ~/dev/PANEL_BASES_ANEXO24
cp .env.example .env
docker compose up -d
Servidores de restauración + asignación de bases en Gestión BD.
Cada Windows con CloudRestoreAS
| Config | Valor |
|---|---|
| URL PANEL | misma en todos |
| API Token | mismo en todos |
| Instancia | nombre de este servidor en panel |
| Carpeta Entrada | local de esta máquina |
Verificaciones
| Paso | Qué comprobar |
|---|---|
| Cards en panel | Reportada con carpeta |
| ZIP propio | RESTORE local |
| ZIP ajeno en esta carpeta | SFTP al destino; bitácora forwarded |
| Destino recibe ZIP | RESTORE local allí |
Troubleshooting
- Sin reportar: CRA destino no guardó config o no alcanza el panel.
- 503 en forward: destino sin
input_folderreportado. - Job diferido: panel caído, sin
instance_key, o base sin asignación. - 401: token distinto entre panel y CRA.
Prueba local
Un CRA con instance_key igual al nombre en panel. El panel muestra una card por servidor; las no reportadas aparecen como Sin reportar.