CreaRack-SL

Organización de demostración - seed_demo_org

Propósito

La organización de demostración (seed_demo_org) es un conjunto de datos sintéticos que permite demostrar CreaRack Pro sin necesidad de hardware real ni conexiones SNMP. Todos los datos son fabricados por plantillas y generadores, no se leen de equipos reales.

Introducida en la v1.140.0 (task #327), es la Fase 1 de 5 del plan de arquitectura de demo. Se amplía en los lotes E y F con más funcionalidad y datos.

Arquitectura

is_demo flag (v1.140.0, commit a850c832)

El modelo Organization introduce un campo is_demo (booleano, default False) que marca organizaciones de demostración:

  • Propósito: Segregar datos de demo del panel de métricas del Workspace (no cuentan en informes de plataforma).
  • Filtrado: /metrics, /finops y /perf-review excluyen orgs con is_demo=True.
  • Efecto: Con ninguna org marcada, las cifras no cambian.
  • Migración: 0035_organization_is_demo.py añade el campo.

Comando seed_demo_org (v1.141.0, commit 807eaaa43)

Comando Django repetible que construye la organización de demo desde cero:

python manage.py seed_demo_org [--dry-run] [--wipe]

Flags:

  • --dry-run: simula sin crear
  • --wipe: borra la org existente y recrea (idempotente)

Protecciones:

  • Se niega a tocar una org sin is_demo=True (fail-safe)
  • No envía correos
  • Reutiliza BlueprintService para consistencia
  • No crea nada al desplegar (manual con comando)

Esqueleto: 3 sedes, 11 filas, 80 racks (v1.141.0)

La estructura físca se define en core/demo_org/spec.py:

  • 3 sedes: DC1 (principal), DC2, Logistics
  • Filas por sede: DC1=8, DC2=2, Logistics=1
  • Racks totales: 80 (distribuidos por fila y altura)
  • Reutilización de BlueprintService: Los racks se crean validando solapes igual que el editor

Equipos: 512 equipos por plantilla, 430 cables (v1.142.0, commit 1862203d)

El módulo core/demo_org/devices.py fabrica:

  • 512 equipos por plantilla: Servidores, switches, UPS, etc., con posiciones calculadas por el validador de solapes del producto
  • 430 cables en DC1: Red LAN, alimentación, etc.
  • Tolerancia: Repetible aunque se añadan racks a mano (bulk_create idempotente)
  • Modelos: Reutiliza perfiles reales de VendorProfile.deep_discovery_oids

Monitorización: 441 equipos, 170 APs, inventario fabricado (v1.143.0, commit 403be026)

El módulo core/demo_org/network.py genera datos de monitorización:

  • 441 equipos monitorizados: Con métricas simuladas (CPU, memoria, disco)
  • 170 puntos de acceso WiFi: Con clientes conectados
  • Fichas de red (NetworkCard): Inventario fabricado desde VendorProfile.deep_discovery_oids (no consulta equipos reales)
  • Alertas y thresholds: Configurados automáticamente
  • Linaje: Directo a bib_wiki_pages, sin notify_agents (no hay transacciones)

Localización por is_demo, no por nombre (v1.157.0, B-61, mega-auditoría 24-09-2026)

get_demo_org() (core/demo_org/seed.py) buscaba la organización de demo por su nombre (spec.ORG_NAME, “Kestrelmoor Group”) y se negaba a tocarla si esa organización no tenía is_demo=True. Un cliente que renombrara la suya al mismo nombre bloqueaba la siembra, el Agente fantasma y la historia de gráficas con un error de “organización homónima”. Ahora la búsqueda es directa por is_demo=True: el nombre ya no importa para encontrarla. La siembra se sigue negando a crear la demo si ya existe otra organización (sin marcar) con spec.ORG_NAME — el caso que sí hay que evitar es tener dos organizaciones indistinguibles por nombre.

Lectura y conteo dentro de rls_bypass(), y avisos legibles si fallan (v1.157.0, B-64, mega-auditoría 24-09-2026)

perf_review (core/management/commands/perf_review.py, _get_tenant_stats) cuenta racks/equipos/media de todas las organizaciones — como cualquier informe de plataforma, necesita rls_bypass() (antes el try/except envolvía un bloque que ya podía estar viendo 0 filas por RLS sin decirlo) y ahora además excluye is_demo=True, igual que core/workspace_api.py. Si esa sección falla, el informe escribe Tenant usage unavailable: <motivo> en vez de salir vacía sin explicación. Y seed_demo_org (el comando que rellena historial/métricas de la demo) ahora comprueba que get_demo_org() no devuelva None antes de seguir, con un CommandError legible en vez de un AttributeError más abajo.

Relacionado, no exclusivo de demo: el mismo hallazgo de auditoría (B-24) detectó que unassign_ghost_profiles (network/management/commands/unassign_ghost_profiles.py, limpieza de fichas de red fantasma en todas las organizaciones) leía y escribía sin rls_bypass(): con el GUC de organización sin fijar, las tablas con FORCE RLS devuelven 0 filas silenciosamente, así que el comando podía decir “total: 0” sin haber fallado ni haber mirado nada. Ahora corre dentro de rls_bypass(), como seed_demo_org. Límite honesto: el rol de la aplicación trae ese valor a “todas” por defecto, así que en PROD probablemente ya funcionaba; no está comprobado si la limpieza de fichas de la tarea #305 llegó a aplicarse antes de este fix.

El Agente fantasma: telemetría continua de la demo, y su gráfica Interface Errors vacía (v1.164.2, commit 0c5d8270)

Aparte de seed_demo_org (que construye la org una sola vez), scripts/demo/ghost_agent.py es un proceso aparte que envía telemetría continua a la organización de demostración — late cada pocos minutos como si fuera el Agente real instalado en un datacenter, para que las gráficas de monitorización de la demo se vean vivas. Los valores los calcula core/demo_org/signals.py (funciones como ping, ap_clients, interface_errors).

Hasta la v1.164.2 esa telemetría mandaba snmp_errors/snmp_discards fijos a 0 en los switches (salvo durante la escena errors, un pico deliberado), y no los mandaba en absoluto para puntos de acceso ni pantallas SpinetiX — la gráfica “Interface Errors” del panel de monitorización salía vacía para esos equipos (lo detectó Edu, 25-09-2026). El fix añade interface_errors() en signals.py: genera el goteo típico de una interfaz sana (casi siempre 0, con rachas cortas de errores y descartes que suben con la carga, muy por debajo del umbral de 100/min que sí dispara la escena errors). Y build_metrics (en ghost_agent.py) ahora manda los cuatro contadores de interfaz (entrada, salida, errores, descartes) también a puntos de acceso y pantallas, como hace el Agente real (terminal/agent/sentinel/snmp_bandwidth.py).

Fases de ampliación

Fase 1 (Lote D): Hoy — esqueleto, equipos, monitorización. 4 commits, ~1200 LOC. Fase 2-5 (Lotes E, F y posteriores): Datos de cliente, historiales, eventos, alarmas, reportes pre-hechos, integraciones demostradas.

Estado en producción

No crea nada al desplegar (no hay datos pre-inicializados). Requiere invocación manual del comando seed_demo_org.

Véase también

  • [[feature—monitoring—out-of-service-devices]]
  • [[feature—monitoring—configurable-charts]]
  • [[feature—monitoring—group-reports]]
  • [[concept—saas—multi-tenancy]]
  • [[feature—network—deep-discovery-batching]]