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.
99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
"""The machine's identity and AMT's firmware, from the recorded NUC9 (AMT 12.0.67)."""
|
|
|
|
import pytest
|
|
|
|
from napalm_amt.parsers import (
|
|
parse_firmware,
|
|
parse_platform_guid,
|
|
parse_software_identity,
|
|
parse_system_identity,
|
|
uuid_from_base64,
|
|
)
|
|
|
|
from ..conftest import instances
|
|
|
|
|
|
def test_software_identity_gives_the_amt_version_with_its_build():
|
|
identity = parse_software_identity(instances("CIM_SoftwareIdentity.pull.xml"))
|
|
assert identity["amt"] == "12.0.67.1579"
|
|
assert identity["flash"] == "12.0.67"
|
|
|
|
|
|
def test_software_identity_without_build_keeps_the_version():
|
|
identity = parse_software_identity([{"InstanceID": "AMT", "VersionString": "11.8.50"}])
|
|
assert identity["amt"] == "11.8.50"
|
|
|
|
|
|
def test_software_identity_of_nothing_is_empty():
|
|
assert parse_software_identity([]) == {"amt": "", "flash": ""}
|
|
|
|
|
|
def test_platform_guid_is_the_smbios_uuid():
|
|
# AMT sends the SMBIOS UUID's bytes as stored; the first three groups are
|
|
# little-endian, as dmidecode and Intel's own console decode them.
|
|
(package,) = instances("CIM_ComputerSystemPackage.pull.xml")
|
|
assert parse_platform_guid(package["PlatformGUID"]) == "55e3ae13-bfd2-61bb-17a0-88aedd7037ea"
|
|
|
|
|
|
def test_get_uuid_and_platform_guid_agree():
|
|
(out,) = instances("AMT_SetupAndConfigurationService.GetUuid.xml")
|
|
assert uuid_from_base64(out["UUID"]) == "55e3ae13-bfd2-61bb-17a0-88aedd7037ea"
|
|
|
|
|
|
@pytest.mark.parametrize("guid", ["", "zz", "13AEE355", "0" * 32, "F" * 32])
|
|
def test_platform_guid_placeholders_and_garbage_are_empty(guid):
|
|
assert parse_platform_guid(guid) == ""
|
|
|
|
|
|
def test_system_identity_comes_from_the_chassis():
|
|
identity = parse_system_identity(
|
|
instances("CIM_Chassis.pull.xml"), instances("CIM_Card.pull.xml")
|
|
)
|
|
assert identity == {
|
|
"manufacturer": "Intel(R) Client Systems",
|
|
"model": "NUC9V7QNX",
|
|
"serial_number": "JRQN0243007J",
|
|
"board_model": "NUC9V7QNB",
|
|
"board_serial": "KNQN0221020W",
|
|
}
|
|
|
|
|
|
def test_system_identity_falls_back_to_the_board_for_placeholders():
|
|
chassis = [
|
|
{
|
|
"Manufacturer": "Default string",
|
|
"Model": "To Be Filled By O.E.M.",
|
|
"SerialNumber": "Default string",
|
|
}
|
|
]
|
|
card = [{"Manufacturer": "LENOVO", "Model": "3102", "SerialNumber": "L1HF8AB01XY"}]
|
|
identity = parse_system_identity(chassis, card)
|
|
assert identity["manufacturer"] == "LENOVO"
|
|
assert identity["model"] == "3102"
|
|
assert identity["serial_number"] == "L1HF8AB01XY"
|
|
|
|
|
|
def test_system_identity_of_nothing_is_empty():
|
|
assert parse_system_identity([], []) == {
|
|
"manufacturer": "",
|
|
"model": "",
|
|
"serial_number": "",
|
|
"board_model": "",
|
|
"board_serial": "",
|
|
}
|
|
|
|
|
|
def test_firmware_lists_amt_and_the_bios():
|
|
firmware = parse_firmware(
|
|
parse_software_identity(instances("CIM_SoftwareIdentity.pull.xml")),
|
|
instances("CIM_BIOSElement.pull.xml"),
|
|
)
|
|
assert firmware == [
|
|
{"name": "Intel AMT", "version": "12.0.67.1579", "updateable": None},
|
|
{"name": "BIOS", "version": "QNCFLX70.0054.2020.0810.2227", "updateable": None},
|
|
]
|
|
|
|
|
|
def test_firmware_skips_what_is_unknown():
|
|
assert parse_firmware({"amt": "", "flash": ""}, []) == []
|