CreaRack-SL

Restore selectivo por rack + informe de verificación del restore (v1.71.0)

User value

Hasta v1.71.0, restaurar un backup completo era todo o nada: se subía el ZIP y aparecía el contenido entero de la organización origen, sin poder elegir qué entraba ni saber de antemano qué había dentro. Task #236 (PR-2) resuelve las dos partes del problema:

  1. Elegir qué racks restaurar. Al seleccionar el ZIP, CreaRack lo inspecciona primero (sin tocar la base de datos) y muestra de qué organización era, cuándo se hizo, sus conteos y la lista de racks — con checkboxes para marcar cuáles quieres traer. Todo lo que cuelga de un rack no elegido (sus devices, cables, monitorización, colocaciones de mapa) se queda fuera limpiamente. Lo transversal (stencils, grupos, scripts, ITSM, Signage) viaja siempre y deduplica solo. Marcar todo equivale al restore completo clásico de siempre.
  2. El restore rinde cuentas. Al terminar, en vez de recargar la página a ciegas, aparece un modal con un informe esperado-vs-creado por entidad: qué declaraba la maleta (ya filtrada por la selección), qué se creó de verdad, y qué ya existía o se omitió por deduplicación.

Es la pieza que permite mudar racks concretos entre organizaciones (caso “Dos Casas”, task #235) sin podar ~100 racks a mano.

Cómo usarla

  1. Admin → Backup & Restore → seleccionar fichero ZIP.
  2. El cliente llama a POST /api/racks/restore/full/preview (nuevo endpoint, no persiste nada) y abre el modal restore-select-modal con la lista de racks y el resumen del manifest.
  3. El usuario marca los racks a restaurar (botón “All/None” para marcar/desmarcar todos) y confirma.
  4. POST /api/racks/restore/full recibe además rack_ids (CSV de IDs de la maleta); vacío o todo-marcado = restore completo clásico.
  5. La tarea Huey run_full_restore aplica el restore y guarda {counts, verification, selective} en el resultado del AsyncJob.
  6. Al terminar el polling, el modal restore-report-modal muestra el veredicto y la tabla esperado/creado/ya-existía por entidad, con un botón “Close & Reload”.

Implementación

  • racks/api/export/restore_selection.py (nuevo): filter_backup_selection(data, rack_ids) poda en sitio el dict del backup a los racks elegidos — devices, config backups, monitoring targets/alerts/patterns, device profiles, port connections, placements y anotaciones de mapa con algún extremo excluido. build_restore_verification(data, created_counts) compara lo esperado (vía core.services.backup_verify.counts_from_backup_data, de [[entity—racks—service—apply-full-restore-from-zip]] PR-1) contra lo creado; complete=True solo si coincide todo, ok=False si se creó de más (anomalía real).
  • racks/api/export/restore.py: apply_full_restore_from_zip(org, zip_path, rack_ids=None) aplica la poda ANTES de restaurar (para que la verificación compare contra un esperado exacto) y devuelve {counts, verification} en vez de solo counts. Nuevo endpoint POST /api/racks/restore/full/preview inspecciona el ZIP sin persistir nada. restore_full acepta el nuevo campo rack_ids: str = Form("").
  • racks/tasks.py: run_full_restore(job_id, org_id, zip_path, rack_ids=None) propaga la selección y guarda verification + selective en el resultado del job.
  • Frontend (static/js/base.js, templates/base.html, static/css/components.css): los dos modales nuevos (selector de racks e informe) sustituyen el flujo de confirm()+reload de [[feature—backup-restore—additive-restore-confirmation-v1-66-2]].
  • i18n: strings nuevos con capa ES añadida vía script dedicado (scripts/i18n/add_restore_selective_strings.py, polib), check_po.py en 0 errores en django.po y djangojs.po.
  • Tests (tests/api/test_restore_selective.py, 5 casos): preview sin efectos secundarios, rechazo de ZIP corrupto, poda verificada objeto a objeto (cable cruzado fuera, target del rack excluido fuera), flujo API completo con verificación en el result del job (incluye el caso deduplicación → already_existed_or_skipped, no falso complete), y restore completo sin selección intacto. Área verificada en Docker: 28 tests + mypy en verde.

Commits relacionados

  • 348a3add — feat(backups): restore selectivo por rack + informe de verificación del restore (task #236, PR-2) - v1.71.0 (#398).
  • 0bc49bb1 — feat(backups): manifest + verificación de integridad en la creación (task #236, PR-1) - v1.69.0 (#396) — introduce core/services/backup_verify.py, base del informe de este PR.
  • c4174fac — feat(backups): la maleta completa — cables, salas DCIM, ITSM y Signage entran al backup (task #236, PR-1.5) - v1.70.0 (#397).

Véase también

  • [[feature—racks—backup-restore-async-v156]]
  • [[feature—backup-restore—additive-restore-confirmation-v1-66-2]]
  • [[entity—racks—service—apply-full-restore-from-zip]]
  • [[entity—racks—endpoint—backup-full-start]]
  • [[entity—core—service—backup-service]]
  • [[crearack-tech—admin—backup-restore]]