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.
58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
"""AMT's own network ports (``AMT_EthernetPortSettings``).
|
|
|
|
AMT shares the machine's network controller: the wired port has the host's MAC address
|
|
and, in DHCP mode, the host's IP address too. A port without a MAC address is a wireless
|
|
port on a machine without a WLAN card.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ipaddress
|
|
from typing import Any
|
|
|
|
from napalm_amt.parsers.common import is_true, text
|
|
|
|
_Instance = dict[str, Any]
|
|
_WIRELESS = "3" # PhysicalConnectionType: 0 integrated LAN, 1 discrete LAN, 2 dock, 3 WLAN
|
|
|
|
|
|
def _mac(value: str) -> str:
|
|
mac = value.replace("-", ":").lower()
|
|
return "" if not mac.replace(":", "").strip("0") else mac
|
|
|
|
|
|
def _prefix(mask: str) -> int | None:
|
|
if not mask:
|
|
return None
|
|
try:
|
|
return ipaddress.IPv4Network(f"0.0.0.0/{mask}").prefixlen
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def parse_ethernet_ports(ports: list[_Instance]) -> list[dict[str, Any]]:
|
|
"""The ports in use: name (``wired``/``wireless``), MAC, link, DHCP, whether AMT shares
|
|
the host's IP address, and its own address where AMT reports one."""
|
|
parsed: list[dict[str, Any]] = []
|
|
for port in ports:
|
|
mac = _mac(text(port.get("MACAddress")))
|
|
if not mac:
|
|
continue
|
|
name = "wireless" if text(port.get("PhysicalConnectionType")) == _WIRELESS else "wired"
|
|
if any(p["name"] == name for p in parsed):
|
|
name = f"{name}{len(parsed)}"
|
|
dhcp = is_true(port.get("DHCPEnabled"))
|
|
ip = text(port.get("IPAddress"))
|
|
parsed.append(
|
|
{
|
|
"name": name,
|
|
"mac_address": mac,
|
|
"link_up": is_true(port.get("LinkIsUp")),
|
|
"dhcp": dhcp,
|
|
"shared_ip": is_true(port.get("SharedDynamicIP" if dhcp else "SharedStaticIp")),
|
|
"ip": ip,
|
|
"prefix_length": _prefix(text(port.get("SubnetMask"))) if ip else None,
|
|
}
|
|
)
|
|
return parsed
|