Merge pull request 'feat!: a VM's vmid is a string, and its config can describe its hardware' (#1) from feature/vmid-as-string into main

This commit was merged in pull request #1.
This commit is contained in:
2026-10-01 18:59:36 +00:00
9 changed files with 189 additions and 21 deletions
+29
View File
@@ -0,0 +1,29 @@
"""reboot_host: the contract for restarting the device itself.
netOrk used to restart a host by sending ``/sbin/reboot`` through a driver's
private ``_send_command``. A driver that talks to an API instead has no such
method, and the caller swallowed the resulting AttributeError, so the reboot
"succeeded" without happening. A declared contract lets netOrk ask first.
"""
from __future__ import annotations
import inspect
from napalm_device_types import DeviceTypeDriver, HostRebootMixin
def test_every_device_type_driver_carries_the_declaration():
assert issubclass(DeviceTypeDriver, HostRebootMixin)
def test_declared_not_implemented():
"""hasattr is netOrk's capability probe; only a driver that implements it
may answer True."""
assert not hasattr(DeviceTypeDriver, "reboot_host")
def test_declaration_documents_the_contract():
source = inspect.getsource(HostRebootMixin)
assert "def reboot_host(self) -> None" in source
assert "RuntimeError" in source
+70
View File
@@ -0,0 +1,70 @@
"""A VM's ``vmid`` is a string on every hypervisor.
Proxmox numbers its guests, but VMware identifies them by UUID or MoRef
(``"vm-42"``). An ``int`` in the contract forced netOrk to call ``int()`` on
whatever came back, which cannot represent the second kind at all. The
provisioning dicts already carried ``vmid`` as a string; these pin the
read-side dicts to the same type.
"""
from __future__ import annotations
from typing import get_type_hints
import pytest
from napalm_device_types.models import (
VMConfigDict,
VMDict,
VMProvisionResultDict,
)
@pytest.mark.parametrize("model", [VMDict, VMConfigDict, VMProvisionResultDict])
def test_vmid_is_a_string(model):
assert get_type_hints(model)["vmid"] is str
class TestVMConfigCarriesWhatAHardwareViewShows:
"""netOrk's VM hardware view used to read Proxmox's raw config through the
driver's private API. The contract has to carry those details so a second
hypervisor can fill the same view -- optionally, since not every platform
has every one of them."""
OPTIONAL = {
"os_name",
"cpu_type",
"sockets",
"cores_per_socket",
"firmware",
"machine",
"passthrough",
}
def test_hardware_details_are_optional_fields(self):
assert self.OPTIONAL <= VMConfigDict.__optional_keys__
def test_contract_core_stays_required(self):
assert "vmid" in VMConfigDict.__required_keys__
assert "disks" in VMConfigDict.__required_keys__
def test_passthrough_entry_shape(self):
from napalm_device_types.models import VMPassthroughDict
assert get_type_hints(VMPassthroughDict) == {"slot": str, "kind": str, "config": str}
class TestGuestAgentDeclaration:
"""netOrk's cloud-init installed qemu-guest-agent on every new VM. A VMware
guest reports its IP through open-vm-tools instead; the hypervisor says
which, and netOrk stops hard-coding one of them."""
def test_default_is_qemu_guest_agent(self):
from napalm_device_types import HypervisorDriver
assert HypervisorDriver.GUEST_AGENT_PACKAGES == ("qemu-guest-agent",)
assert HypervisorDriver.GUEST_AGENT_RUNCMD == ("systemctl enable --now qemu-guest-agent",)
def test_attributes_are_not_methods(self):
from napalm_device_types import HypervisorDriver
assert not callable(vars(HypervisorDriver)["GUEST_AGENT_PACKAGES"])