Files
napalm-amt/napalm_amt/parsers/protocols.py
T
christianmanivong 0052ba7884 feat: Intel AMT driver over WS-Management (0.1.0)
An `amt` driver (napalm_amt.AmtDriver), a ManagementControllerDriver for the
management controller of Intel vPro machines, with its own lean WS-Management
client (requests + ElementTree, HTTP Digest, ports 16992/16993).

It reads the machine's identity, hardware with the SMBIOS system UUID, firmware
(AMT with build, BIOS), power state and the hardware event log, reports what AMT
listens on (plain HTTP or TLS, KVM incl. port 5900, IDE-R), and switches the
machine's power. AMT cannot be reset over WS-Management, so there is no
reboot_host. Discovery recognises AMT by its ports and its Server header.

Tested against Intel's published AMT 12 recordings (go-wsman-messages,
Apache-2.0, see NOTICE). `python -m napalm_amt.record` records a real AMT
read-only; the first test devices are two Lenovo ThinkCentre M910x.
2026-10-18 14:55:32 +02:00

62 lines
2.4 KiB
Python

"""What AMT listens on, in the role's ``get_management_protocols`` shape.
AMT has no IPMI, SSH or SNMP. It answers WS-Management and its web UI on 16992 (plain
HTTP, Digest auth) until TLS is set up, then on 16993; with TLS, plain connections from the
network are refused unless ``AcceptNonSecureConnections`` says otherwise. The KVM console,
serial-over-LAN and IDE/USB redirection (virtual media) go over the redirection port 16994,
or 16995 with TLS; KVM can also listen on the standard VNC port 5900.
"""
from __future__ import annotations
from typing import Any
from napalm_amt.parsers.common import is_true, text, to_int
from napalm_amt.wsman import PORT, TLS_PORT
_Instance = dict[str, Any]
_REDIRECTION_PORT = 16994
_REDIRECTION_TLS_PORT = 16995
_VNC_PORT = 5900
#: CIM_KVMRedirectionSAP.EnabledState: 2 enabled, 6 enabled but offline (no session yet).
_KVM_ENABLED = {2, 6}
#: AMT_RedirectionService.EnabledState: 32768 none, 32769 IDE-R, 32770 SOL, 32771 both.
_IDER_ENABLED = {32769, 32771}
def _network_tls(tls_settings: list[_Instance]) -> _Instance:
"""The TLS setting for the network ("802.3"); the LMS one only covers local access."""
return next((t for t in tls_settings if "802.3" in text(t.get("InstanceID"))), {})
def parse_management_protocols(
tls_settings: list[_Instance],
redirection: _Instance,
kvm_settings: _Instance,
kvm_saps: list[_Instance],
) -> dict[str, dict[str, Any]]:
network_tls = _network_tls(tls_settings)
tls = is_true(network_tls.get("Enabled"))
plain = not tls or is_true(network_tls.get("AcceptNonSecureConnections"))
redirection_port = _REDIRECTION_TLS_PORT if tls else _REDIRECTION_PORT
kvm_enabled = text(kvm_settings.get("EnabledByMEBx")).lower() != "false" and any(
to_int(sap.get("EnabledState")) in _KVM_ENABLED for sap in kvm_saps
)
vnc = is_true(kvm_settings.get("Is5900PortEnabled"))
ider = (
to_int(redirection.get("EnabledState")) in _IDER_ENABLED
and text(redirection.get("ListenerEnabled")).lower() != "false"
)
return {
"ipmi": {"enabled": False, "port": 623},
"ssh": {"enabled": False, "port": 22},
"http": {"enabled": plain, "port": PORT},
"https": {"enabled": tls, "port": TLS_PORT},
"snmp": {"enabled": False, "port": 161},
"kvm": {"enabled": kvm_enabled, "port": _VNC_PORT if vnc else redirection_port},
"virtual_media": {"enabled": ider, "port": redirection_port},
}