Fix SSH reconnection and improve interface description parsing in CiscoMacTableParser

This commit is contained in:
xavs
2026-03-11 17:43:26 +01:00
parent 54ce126e20
commit 5576cb209f
2 changed files with 25 additions and 18 deletions
+3
View File
@@ -1,5 +1,8 @@
CHANGELOG.md
2026/03/11
Fix SSH reconnection and improve interface description parsing in CiscoMacTableParser
2026/02/09
Refactor Cisco MAC Monitor: Implement HTTPS service and restructure code
+22 -18
View File
@@ -260,17 +260,18 @@ class CiscoMacTableParser:
def _get_interface_descriptions(self, ssh_connector: CiscoSSHConnector):
"""Obtiene las descripciones de las interfaces"""
try:
# Reconectar la sesión SSH para evitar errores de sesión inactiva
ssh_connector.disconnect()
if not ssh_connector.connect():
self.logger.warning("No se pudo reconectar para obtener descripciones de interfaces")
return
command = "show interface description"
output = ssh_connector.execute_command(command)
# Si el comando no es válido, intentar alternativa
if "Invalid input" in output or not output.strip():
# Intentar obtener descripciones una por una (más lento pero funciona en IOS antiguos)
self.logger.debug("show interface description no disponible, usando método alternativo")
return
self._parse_interface_descriptions(output)
except Exception as e:
self.logger.warning(f"Error obteniendo descripciones de interfaces: {str(e)}")
@@ -281,22 +282,25 @@ class CiscoMacTableParser:
line_stripped = line.strip()
if not line_stripped or line_stripped.startswith('-') or 'Interface' in line_stripped:
continue
# Format: Interface Status Protocol Description
# Fa0/1 up up User Port
# Usamos split con máximo 3 splits para preservar la descripción completa
parts = line.split(None, 3) # Split en whitespace, máximo 4 partes
if len(parts) >= 1:
interface = parts[0]
description = ""
if len(parts) >= 4:
description = parts[3].strip()
# Si esta interfaz ya existe en nuestro diccionario, actualizar descripción
# El formato Cisco es: Interface Status Protocol Description (Description puede tener espacios o estar vacía)
match = re.match(r'^(\S+)\s+(\S+)\s+(\S+)\s*(.*)$', line_stripped)
if match:
interface = match.group(1)
status_raw = match.group(2)
protocol_raw = match.group(3)
description = match.group(4).strip() if match.group(4) else ""
# Normalizar status (up/down/disabled/unknown)
status = self._normalize_status(status_raw)
# Actualizar o crear la interfaz en el diccionario
if interface in self.interface_info:
self.interface_info[interface].status = status
self.interface_info[interface].description = description
else:
self.interface_info[interface] = InterfaceInfo(
name=interface,
status=status,
description=description
)
def _normalize_status(self, status_raw: str) -> str:
"""Normaliza el estado de la interfaz a up/down/disabled/unknown"""