Volver a la wiki

Guía de Interconexionado — CreaRack Pro

Guía de Interconexionado — CreaRack Pro

Sistema completo de documentación de conexiones físicas entre dispositivos. Versión: v1.0.41 (14-03-2026) — Cable Report Generator


1. Visión General

CreaRack Pro permite documentar todas las conexiones físicas de un datacenter:

Tipo de conexiónOrigenDestinoEjemplo
Profile → PortDispositivo descubierto (AP, cámara, UPS…)Puerto de switch en rackAP-Office-1 → Switch-01:12
Device → DeviceDispositivo en rack (switch, firewall, servidor…)Otro dispositivo en rackCore-SW:24 → FW-01:eth0

Ambos tipos conviven en el mismo modelo (PortConnection) y se visualizan de forma unificada en la tabla de puertos del Rack Editor.

¿Por qué documentar conexiones?


2. Arquitectura

2.1 Modelo: PortConnection

Ubicado en network/models.py. Un solo modelo cubre ambos tipos de conexión:

PortConnection
├── organization (FK → Organization)     # Aislamiento multi-tenant
├── device (FK → racks.Device)           # Dispositivo origen (el que tiene el puerto)
├── port_key (CharField)                 # Puerto en el dispositivo origen
│
├── profile (OneToOne → DeviceProfile)   # ← Tipo 1: dispositivo descubierto
├── connected_device (FK → racks.Device) # ← Tipo 2: otro dispositivo de rack
├── connected_port_key (CharField)       # Puerto en el destino (solo tipo 2)
│
├── cable_type (CharField)               # Cat5e, Cat6, Cat6a, Fiber SM/MM, DAC...
├── cable_color (CharField)              # Azul, Rojo, Amarillo...
├── cable_length (CharField)             # 1m, 3ft, 10m...
│
├── notes (CharField)                    # Notas libres
└── created_at (DateTimeField)           # Timestamp de creación

2.2 Regla XOR

Exactamente uno de profile o connected_device debe tener valor. Nunca ambos, nunca ninguno.

✅ profile=AP-01, connected_device=NULL        → Conexión profile-based
✅ profile=NULL, connected_device=Firewall-01   → Conexión device-to-device
❌ profile=AP-01, connected_device=Firewall-01  → Violación de constraint
❌ profile=NULL, connected_device=NULL           → Violación de constraint

Esto se garantiza con un CheckConstraint a nivel de base de datos (port_conn_one_target).

2.3 Constraints

ConstraintTipoEfecto
unique_together: (device, port_key)UniqueUn puerto solo puede tener una conexión como origen
port_conn_one_targetCheckXOR: profile o connected_device, nunca ambos
port_conn_unique_dest_portUnique condicionalUn puerto destino no puede recibir dos conexiones distintas

2.4 Ocupación de puertos

Un puerto se considera ocupado si aparece en cualquiera de estas situaciones:

El endpoint available-ports descarta ambos casos al listar puertos disponibles.


3. Flujos Operativos

3.1 Conexión Profile → Port (dispositivos descubiertos)

Caso de uso: Un AP, cámara, UPS u otro dispositivo descubierto via Auto-Provision se asigna a un puerto de switch.

Dónde se hace:

UbicaciónBotónAcción
Wireless — Detalle de AP“Assign Port”Abre PortAssignModal
Wireless — SidebarClick en badge de puertoAbre PortAssignModal
Wireless — Tabla de grupo“Assign” por filaAbre PortAssignModal
Observatory — Tab manual“Assign Port”Abre PortAssignModal
UPS Monitor — Detalle“Assign Port”Abre PortAssignModal

Flujo paso a paso:

1. Navega a Wireless Monitor
2. Selecciona un AP (ej: "AP-Office-1")
3. En el detalle del AP, click "Assign Port"
4. PortAssignModal se abre:
   ┌─ Assign Port — AP-Office-1 ──────────────────┐
   │                                                │
   │  Rack:    [Core Rack ▼]                        │
   │  Switch:  [Switch-01 (48 ports) ▼]             │
   │  Port:    [12 - GigabitEthernet0/12 ▼]         │
   │                                                │
   │  [Check LLDP]                                  │
   │                                                │
   │              [Cancel]        [Assign]          │
   └────────────────────────────────────────────────┘
5. (Opcional) Click "Check LLDP" → auto-selecciona rack/switch/puerto si hay datos LLDP
6. Click "Assign" → conexión creada

Resultado visible:

3.2 Conexión Device → Device (interconexiones entre racks)

Caso de uso: Documentar uplinks, enlaces troncales, conexiones entre switches, firewalls, servidores, etc.

Dónde se hace: Rack Editor → Properties Panel → Port Config → botón “Assign”

Flujo paso a paso:

1. Abre un rack en el Editor (ej: /editor/5)
2. Selecciona un dispositivo con puertos (ej: "Core-Switch")
3. En Properties Panel, sección Port Config, localiza un puerto vacío
4. En la columna "Device" del puerto, click en el botón "Assign"
5. ConnectionModal se abre:
   ┌─ Port Connection — Core-Switch Port 24  ───────┐
   │                                                │
   │  Source: Core-Switch (Core Rack) → Port 24     │
   │                                                │
   │  Scope:   [Same Rack ▼]                        │
   │  Device:  [Firewall-01 ▼]                      │
   │  Port:    [eth0 ▼]                             │
   │                                                │
   │  Cable Info                                     │
   │                                                │
   │  Notes:   [Uplink troncal al firewall]         │
   │                                                │
   │              [Cancel]        [Connect]         │
   └────────────────────────────────────────────────┘
6. Selecciona el dispositivo destino
7. Si el destino tiene puertos SNMP, selecciona del dropdown
   Si no tiene puertos, escribe manualmente (ej: "eth0", "GE1/0/1")
8. Cable Info (siempre visible) → Type: Cat6a, Color: Blue, Length: 2m
9. Click "Connect" → conexión creada

Resultado visible (tabla de puertos, font-size 14px):

3.3 Conexión Cross-Rack

Cuando el dispositivo destino está en otro rack:

1. En ConnectionModal, cambia Scope a "Cross-Rack"
2. Aparece un dropdown "Rack" con todos los racks excepto el actual
3. Selecciona el rack destino (ej: "DMZ Rack")
4. El dropdown "Device" carga los dispositivos de ese rack
5. Continúa normalmente

3.4 Eliminar una conexión

Ambos tipos de conexión se eliminan con el mismo endpoint:

DELETE /api/network/port-connections/{connection_id}

4. API Reference

4.1 Endpoints de Profile Connections (existentes)

MétodoURLDescripción
GET/api/network/port-connectionsListar conexiones profile-based
POST/api/network/port-connectionsCrear conexión profile → port
DELETE/api/network/port-connections/{id}Eliminar cualquier conexión
GET/api/network/port-connections/switchesListar switches con puertos
GET/api/network/port-connections/available-ports/{device_id}Puertos libres de un dispositivo
GET/api/network/port-connections/suggest/{profile_id}Auto-suggest via LLDP/CDP

4.2 Endpoints de Device Connections (nuevos)

GET /api/network/port-connections/device?device_id=X

Lista conexiones device-to-device en ambas direcciones (outgoing + incoming).

Response 200: Array de DeviceConnectionOut

[
  {
    "id": 15,
    "device_id": 42,
    "device_name": "Core-Switch",
    "rack_id": 5,
    "rack_name": "Core Rack",
    "port_key": "24",
    "port_label": "GigabitEthernet0/24",
    "connected_device_id": 67,
    "connected_device_name": "Firewall-01",
    "connected_rack_id": 8,
    "connected_rack_name": "DMZ Rack",
    "connected_port_key": "eth0",
    "cable_type": "Cat6a",
    "cable_color": "Blue",
    "cable_length": "2m",
    "notes": "Uplink troncal",
    "created_at": "2026-03-14T10:30:00+00:00",
    "direction": "outgoing"
  },
  {
    "id": 18,
    "device_id": 42,
    "device_name": "Core-Switch",
    "rack_id": 5,
    "rack_name": "Core Rack",
    "port_key": "sfp_1",
    "port_label": "SFP 1",
    "connected_device_id": 90,
    "connected_device_name": "Dist-Switch",
    "connected_rack_id": 12,
    "connected_rack_name": "Floor 2 Rack",
    "connected_port_key": "sfp_2",
    "cable_type": "Fiber SM",
    "cable_color": "",
    "cable_length": "15m",
    "notes": "Inter-floor uplink",
    "created_at": "2026-03-14T11:00:00+00:00",
    "direction": "incoming"
  }
]

El campo direction indica la perspectiva:

POST /api/network/port-connections/device

Crea una conexión device-to-device.

Request body (DeviceConnectionIn):

{
  "device_id": 42,
  "port_key": "24",
  "connected_device_id": 67,
  "connected_port_key": "eth0",
  "cable_type": "Cat6a",
  "cable_color": "Blue",
  "cable_length": "2m",
  "notes": "Uplink troncal"
}
CampoTipoRequeridoDescripción
device_idintSíDispositivo origen
port_keystrSíPuerto en el origen
connected_device_idintSíDispositivo destino
connected_port_keystrNoPuerto en el destino (vacío si el destino no tiene ports SNMP)
cable_typestrNoTipo de cable
cable_colorstrNoColor del cable
cable_lengthstrNoLongitud del cable
notesstrNoNotas libres

Validaciones:

ReglaError
device_id ≠ connected_device_id"Cannot connect a device to itself"
Dispositivo origen pertenece al tenant"Source device not found"
Dispositivo destino pertenece al tenant"Destination device not found"
Puerto origen no ocupado (como source)"Port X is already assigned"
Puerto origen no ocupado (como incoming)"Port X is already used as incoming connection"
Puerto destino no ocupado (como source)"Destination port X is already assigned"
Puerto destino no ocupado (como incoming)"Destination port X is already used"

GET /api/network/port-connections/rack-devices?rack_id=X

Lista todos los dispositivos de un rack (para poblar dropdowns).

Response 200: Array de RackDeviceOut

[
  { "device_id": 42, "device_name": "Core-Switch", "rack_id": 5, "rack_name": "Core Rack", "port_count": 48 },
  { "device_id": 43, "device_name": "Patch-Panel", "rack_id": 5, "rack_name": "Core Rack", "port_count": 0 },
  { "device_id": 44, "device_name": "UPS-01", "rack_id": 5, "rack_name": "Core Rack", "port_count": 0 }
]

port_count = 0 significa que el dispositivo no tiene puertos SNMP escaneados. En ese caso, el ConnectionModal ofrece un input de texto libre para el puerto destino.


5. Ejemplos Prácticos

5.1 Datacenter pequeño (1 rack)

┌──────────────────── Rack: "Servidor Principal" ──────────────────────┐
│                                                                      │
│  U42  [ Patch Panel 24p ]                                            │
│  U41  [ Core-Switch-01  ] ← 48 puertos SNMP escaneados               │
│  U40  [ Firewall-01     ] ← 4 puertos, sin SNMP (manual)             │
│  U38  [ Servidor-DB     ] ← 2 puertos, sin SNMP                      │
│  U36  [ UPS-APC-01      ] ← Descubierto via Auto-Provision           │
│  ...                                                                 │
│  (10 APs descubiertos via Auto-Provision en la red)                  │
└──────────────────────────────────────────────────────────────────────┘

Conexiones a crear:

Profile connections (via PortAssignModal desde Wireless/Observatory/UPS):
  Core-Switch-01:1  → AP-Recepcion     (profile-based, LLDP auto-suggest)
  Core-Switch-01:2  → AP-Sala-Reuniones (profile-based)
  Core-Switch-01:3  → AP-Oficina-1      (profile-based)
  Core-Switch-01:4  → AP-Oficina-2      (profile-based)
  Core-Switch-01:5  → Camera-Entrada    (profile-based)
  Core-Switch-01:20 → UPS-APC-01        (profile-based, desde UPS Monitor)

Device connections (via ConnectionModal desde Rack Editor):
  Core-Switch-01:47 → Firewall-01:WAN1   (Cat6a, Blue, 0.5m, "Uplink LAN→FW")
  Core-Switch-01:48 → Servidor-DB:eth0   (Cat6a, Red, 1m, "DB Server link")
  Firewall-01:LAN   → Core-Switch-01:47  ← Se muestra automáticamente (bidireccional)

5.2 Datacenter mediano (3 racks, cross-rack)

┌─── Rack: "Core" ──┐   ┌─── Rack: "DMZ" ───┐   ┌── Rack: "Floor 2" ──┐
│ Core-Switch-01    │   │ FW-Perimeter      │   │ Dist-Switch-02      │
│ Core-Switch-02    │   │ Web-Server-01     │   │ AP-Controller       │
│ UPS-Core          │   │ Web-Server-02     │   │ UPS-Floor2          │
└───────────────────┘   └───────────────────┘   └─────────────────────┘

Conexiones device-to-device cross-rack:

Core-Switch-01:sfp_1 → FW-Perimeter:eth0     (Fiber SM, 5m, "Core→DMZ uplink")
Core-Switch-01:sfp_2 → Dist-Switch-02:sfp_1  (Fiber SM, 25m, "Core→Floor2 trunk")
Core-Switch-02:48    → Core-Switch-01:47      (DAC, 0.5m, "Stack link")
FW-Perimeter:eth2    → Web-Server-01:eth0     (Cat6a, Yellow, 1m, "DMZ segment")
FW-Perimeter:eth3    → Web-Server-02:eth0     (Cat6a, Yellow, 1m, "DMZ segment")

Lo que ve el usuario en el Rack Editor (font-size 14px):

Al seleccionar Core-Switch-01 en el Rack “Core”:

Port Config
┌──────┬──────┬────────────────────────────────────────────────────────────┬───────┬────────┬──────────────┐
│ LED  │  #   │ Description                                              │ Speed │ Mode   │ Device       │
├──────┼──────┼────────────────────────────────────────────────────────────┼───────┼────────┼──────────────┤
│  🟢  │  1   │ AP-Recepcion (profile link)                               │ 1G    │ access │ AP-Recepcion │
│  🟢  │  2   │ AP-Sala-Reuniones (profile link)                          │ 1G    │ access │ AP-Sala      │
│  ⚫  │  6   │ -                                                        │ auto  │ access │ [Assign]     │
│  ...                                                                                                    │
│  🟢  │ 47   │ Core-Switch-02 → 48 · DAC 0.5m                           │ 10G   │ trunk  │ Core-SW-02   │
│  🟢  │ 48   │ Servidor-DB → eth0 · Cat6a Red 1m · DB Server link       │ 1G    │ access │ Servidor-DB  │
├──────┼──────┼────────────────────────────────────────────────────────────┼───────┼────────┼──────────────┤
│  🟢  │ S1   │ FW-Perimeter → eth0 · Fiber SM 5m · Core→DMZ uplink      │ 10G   │ trunk  │ FW-Perimeter │
│  🟢  │ S2   │ Dist-Switch-02 → sfp_1 · Fiber SM 25m · Floor2 trunk     │ 10G   │ trunk  │ Dist-SW-02   │
└──────┴──────┴────────────────────────────────────────────────────────────┴───────┴────────┴──────────────┘

Diseño de columnas para device-to-device:

Detalle expandible: click en la fila abre VLAN ID, SNMP Description, Speed, Mode

5.3 Dispositivos sin SNMP (puertos manuales)

No todos los dispositivos tienen puertos escaneados via SNMP. Por ejemplo, un servidor Linux o un firewall sin agente SNMP configurado no tendrán model_data.ports.

Comportamiento del ConnectionModal:

Si el destino tiene ports SNMP:
  Port: [eth0 ▼] [GE1/0/1 ▼] [sfp_1 ▼]  ← Dropdown con puertos disponibles

Si el destino NO tiene ports SNMP:
  Port: [_______________]  ← Input libre de texto
         (escribe: "eth0", "GE1", "WAN1", etc.)

El puerto escrito manualmente se guarda como connected_port_key y se muestra en la tabla de puertos del dispositivo origen, pero no aparecerá en la tabla de puertos del destino si este no tiene Port Config visible.


6. Metadatos de Cable

Los campos de cable son opcionales pero recomendados para documentación profesional:

CampoValores comunesEjemplo
cable_typeCat5e, Cat6, Cat6a, Fiber SM, Fiber MM, DAC, Twinax, OtherCat6a
cable_colorCualquier texto libreBlue, Red, Yellow
cable_lengthCualquier texto libre1m, 3ft, 15m

Convenciones recomendadas:

Uplinks / Trunk:       Fiber SM o DAC
Dispositivos de red:   Cat6a (azul)
Servidores:            Cat6a (rojo)
DMZ / Seguridad:       Cat6a (amarillo)
Management / IPMI:     Cat6 (verde)
Dispositivos IoT:      Cat5e (gris)

Los metadatos de cable se muestran en la columna Description de la tabla de puertos:

Firewall-01 → eth0 · Cat6a Blue 2m · Uplink nota
   (naranja)  (blanco)     (gris)       (gris)

7. Visualización Bidireccional

Cuando se crea una conexión device-to-device, automáticamente es visible desde ambos lados:

Se crea:  Core-Switch:24 → Firewall-01:eth0

Tabla de puertos de Core-Switch, puerto 24:
  Device: Firewall-01 (naranja)
  Description: Firewall-01 → eth0 · Cat6a Blue 2m

Tabla de puertos de Firewall-01, puerto eth0:
  Device: Core-Switch (naranja)
  Description: Core-Switch → 24 · Cat6a Blue 2m

Same-rack: click selecciona el otro dispositivo in-place
Cross-rack: click navega al rack del otro dispositivo

Esto se logra porque el endpoint GET /port-connections/device?device_id=X busca en ambas direcciones:

Los campos se invierten en la respuesta para que la vista sea siempre desde la perspectiva del dispositivo consultado.


8. Comparativa de Modales

AspectoPortAssignModalConnectionModal
PropósitoAsignar DeviceProfile a puerto de switchConectar dos dispositivos de rack
Se abre desdeWireless, Observatory, UPS MonitorRack Editor (botón “Assign” en port table)
FlujoSelecciona rack → switch → puertoSelecciona scope → dispositivo → puerto
DestinoUn DeviceProfile (AP, cámara, UPS…)Un racks.Device (switch, firewall, servidor…)
Puerto destinoN/A (el profile no tiene puertos propios)Dropdown SNMP o input libre
Cable metadataNoSí (type, color, length)
Cross-rackSí (dropdown de racks)Sí (scope “Cross-Rack”)
LLDP suggestSí (botón “Check LLDP”)No (conexiones manuales)
Ubicación JSstatic/js/services/PortAssignModal.jsstatic/js/editor/ConnectionModal.js

9. Referencia de Archivos

ArchivoPropósito
network/models.pyModelo PortConnection (profile + device-to-device)
network/migrations/0041_portconnection_device_to_device.pyMigración: profile nullable, campos device-to-device, constraints
network/api/port_connections.py9 API endpoints (6 profile + 3 device-to-device)
network/services/port_suggestion.pyAlgoritmo LLDP/CDP auto-match
static/js/services/PortAssignModal.jsModal para conexiones profile-based
static/js/editor/ConnectionModal.jsModal para conexiones device-to-device
static/js/editor/PropertiesPanelRenderer.jsloadPortConnections() — renderiza ambos tipos en la tabla de puertos (Device col + Description col)
static/js/editor/devices.jswindow.selectDeviceById() — selección in-place para same-rack navigation
static/js/editor/ui_panels.jsPasa rackId/rackName a loadPortConnections
network/services/cable_report.pyCable Report Generator (collect, markdown, html)
network/api/cable_report.py3 API endpoints: JSON, Markdown download, HTML standalone
static/css/pages/editor.cssEstilos: .port-assign-btn, .port-device-link (naranja #f59e0b), port table 14px base

10. Cable Report Generator

10.1 Visión General

El Cable Report Generator exporta toda la información de interconexionado como documentación descargable — para auditorías, entrega a clientes, o documentación interna.

Formatos disponibles:

FormatoEndpointUso
JSONGET /api/network/cable-reportIntegración programática
MarkdownGET /api/network/cable-report/markdownDescarga .md (attachment)
HTMLGET /api/network/cable-report/htmlPágina standalone con Mermaid diagrams

10.2 Scopes

ScopeParámetrosDescripción
allscope=allTodas las conexiones de la organización
rackscope=rack&id=XSolo conexiones de un rack específico
groupscope=group&id=XSolo racks de un RackGroup específico

10.3 Contenido del Reporte

Cada reporte incluye:

10.4 Acceso desde el Editor

El Rack Editor incluye un botón “Cable Report” (amarillo, btn-export) en el header:

[Rack Properties] [Paste Master] [Cable Report]

Click → abre el reporte HTML del rack actual en nueva pestaña.

10.5 HTML Standalone

El HTML generado es un documento independiente (no usa templates Django):

10.6 Ejemplo de Salida

# Cable Report — Core Rack

Organization: Acme Corp | Scope: Rack | Generated: 2026-03-14

## Summary
| Total Connections | 24 |
| Profile           | 18 |
| Device            | 6  |

## Connections
| # | Device      | Port  | Type    | Target       | Cable  | Color | Length |
|---|-------------|-------|---------|--------------|--------|-------|--------|
| 1 | Switch-01   | Gi0/1 | Profile | AP-Lobby     | Cat6   | Blue  | 3m     |
| 2 | Switch-01   | SFP 1 | Device  | FW-01:eth0   | Fiber  | —     | 5m     |

## Topology (Mermaid)
graph LR
    R1["Core Rack"] -->|"2x Fiber SM"| R2["DMZ Rack"]

10.7 Archivos

ArchivoPropósito
network/services/cable_report.pyService: collect_cable_data, format_markdown, format_html
network/api/cable_report.py3 API endpoints (JSON, Markdown, HTML)

11. Roadmap (Diferido)

FeatureDescripciónPrioridad
Port Occupancy BarBarra visual de % puertos usados/libres en properties panelMedia
Cable AuditComparar vecinos LLDP vs conexiones documentadas, alertar discrepanciasMedia
Connection DiagramDiagrama visual (force-graph) de todas las conexiones de un rackBaja
Bulk Cable ImportCSV import para planes de cableado masivosBaja
Cable LabelsEtiquetas imprimibles A-end / B-endBaja
Auto-suggest LLDP bidireccionalCuando dos rack devices se ven mutuamente via LLDP, auto-crear suggestionMedia
Botón Unassign en port tableClick en dispositivo conectado → opción de desconectar desde el EditorMedia
Cable Report PDF exportExportar reporte directamente como PDF sin browser printBaja

Última actualización: 14-03-2026 (Cable Report Generator + Connection UX improvements)

Véase también

Subir