CreaRack-SL

ADR: Eliminar python-nmap (abandonada) → subprocess + xml.etree stdlib

ADR: Eliminar python-nmap (abandonada) → subprocess + xml.etree stdlib

Contexto

discover_nmap en network/services/device_discovery/service.py es el método de la Stage 1.5 del pipeline de Auto-Provision que realiza OS detection y service detection mediante el binario nmap. Hasta esta sesión dependía del wrapper Python python-nmap 0.7.1.

En la sesión 30 del Supercontexto (2026-04-26), durante el cierre del Cluster J2 de Fase B post-audit, se detectó que python-nmap llevaba 4 años sin releases (último: 0.7.1, octubre 2021) y fue clasificada como deuda técnica activa. Se evaluaron 3 alternativas antes de decidir.

Alternativas evaluadas

AlternativaLicenciaEstadoDecisión
python-nmap 0.7.1 (actual)GPL-3.0Abandonada — sin releases desde oct 2021❌ Eliminar
python3-nmap (nmap3)GPL-3.0Sin releases > 1 año❌ Descartada — no mejora ni licencia ni mantenimiento
python-libnmapApache 2.0Soporte oficial solo hasta Python 3.8; proyecto en Python 3.14❌ Descartada — riesgo de incompatibilidad futura
subprocess + xml.etree.ElementTree (stdlib)PSF (parte de CPython)Mantenida por upstream Python indefinidamente✅ Elegida

Decisión

Migrar a stdlib: invocar el binario nmap directamente con subprocess.run y parsear su salida XML con xml.etree.ElementTree.

Rationale

Las tres alternativas wrapper evaluadas están todas en estado de mantenimiento limitado o nulo, similar al python-nmap original. Reemplazar una dependencia abandonada por otra con los mismos síntomas no resuelve la deuda — solo la pospone. La stdlib es mantenida por upstream Python de forma indefinida y no introduce ninguna dependencia externa nueva.

Implementación

Archivo: network/services/device_discovery/service.py — método discover_nmap

Cambios clave:

  • Detección del binario en PATH con shutil.which("nmap") — falla con error claro si no está disponible.
  • Invocación: nmap -oX - <args> <ip> via subprocess.run(capture_output=True, text=True, timeout=120).
  • Fallback preservado: intenta -sV -T4 -F --version-light; si falla, reintenta con -sV -T4 -F.
  • Timeout explícito de 120 segundos (antes implícito en python-nmap).
  • Parser XML manual con xml.etree.ElementTree:
    • host/hostnames/hostname[@name] → hostname
    • host/os/osmatch[@name] → os_family
    • host/os/osmatch/osclass[@osfamily] → nmap_fingerprint
    • host/ports/port[@protocol=tcp][state/@state=open] → open_ports + services
  • Firma de salida idéntica: mismo dict con claves os_family, os_vendor, hostname, open_ports, services, nmap_fingerprint. Sin breaking changes para los consumidores del método.

Otros archivos modificados:

ArchivoCambio
requirements.txtLínea python-nmap>=0.7.1 eliminada
core/licenses_data/python.pyEntrada python-nmap removida del inventario de licencias
core/licenses_data/infrastructure.pyDescripción del binario nmap actualizada: “invoked via subprocess server-side; XML output parsed with stdlib xml.etree”
CLAUDE.md (tabla de red)python-nmap 0.7.1 → nmap (binario) 7.x con anotación del método

Smoke test

Parser validado con XML sintético (hostname Cisco IOS + TCP ports + filtrado de UDP/closed states). Test real con binario activo se delega a STAGE/PROD (requiere nmap en PATH y host accesible).

Consecuencias

Positivas:

  • Deuda técnica eliminada permanentemente, sin sustituirla por otra deuda futura.
  • Cero dependencias externas para el scanner — solo stdlib + binario de sistema.
  • Control total sobre el parser XML: filtros explícitos (solo TCP, solo state=open).
  • Timeout explícito y detección de binario ausente con mensajes de error claros.

A vigilar:

  • El binario nmap debe estar en PATH en todos los entornos (Local Agent, STAGE, PROD). Ya estaba documentado como dependencia de infra operator-installed en core/licenses_data/infrastructure.py.
  • Cambios futuros en el formato XML de salida de nmap requerirán actualizar el parser manualmente (sin abstracción de wrapper).

Contexto Supercontexto

  • Sesión: 30 (2026-04-26)
  • Cluster cerrado: J2 (de Fase B post-audit Supercontexto)
  • Clusters Fase B pendientes tras esta sesión: C (auth/crypto, requiere tests STAGE) y F (Redis/huey 3.0, esperar 1-2 meses madurez)
  • Versión: v1.0.58+

Véase también

  • [[crearack—network—discovery]]
  • [[crearack—network—network-tools]]
  • [[entity—network—model—deviceprofile]]
  • [[entity—network—model—vendorprofile]]