Author SHA1 Message Date
christianmanivong 841881018c Merge feature/nic-mac-address: optional explicit MAC on NICConfigDict 2026-07-08 09:09:18 +02:00
christianmanivong f5c286a713 feat(hypervisor): add optional explicit mac to NICConfigDict
Lets a caller pin a NIC's MAC address ahead of VM creation, needed to
create a matching DHCP static reservation before the VM even exists.
2026-07-08 09:09:14 +02:00
christianmanivong 6c4ff65710 Merge feature/node-scoped-image-storage: get_image_storages() + storage param 2026-07-07 22:35:35 +02:00
christianmanivong f9b8a54673 feat(hypervisor): add StorageTargetDict and get_image_storages(), storage param on create_vm_from_cloud_init
Lets callers select which node-available storage pool a new VM's root
disk lands on, instead of always trusting the driver's auto-detected
default.
2026-07-07 22:35:33 +02:00
christianmanivong d9a23e08f2 Merge feature/create-vm-from-image: create_vm_from_cloud_init downloads images directly 2026-07-07 10:38:03 +02:00
2 changed files with 40 additions and 1 deletions
+27 -1
View File
@@ -19,6 +19,7 @@ from napalm_device_types.models import (
NetworkTargetDict,
PackageDict,
SnapshotDict,
StorageTargetDict,
StorageVolumeDict,
VMConfigDict,
VMDict,
@@ -556,6 +557,7 @@ class HypervisorDriver(DeviceTypeDriver):
image_checksum: str | None = None,
ssh_public_keys: List[str] | None = None,
disk_resize_gb: int | None = None,
storage: str | None = None,
download_timeout: int = 300,
timeout: int = 180,
) -> VMProvisionResultDict:
@@ -581,7 +583,9 @@ class HypervisorDriver(DeviceTypeDriver):
nics (list[NICConfigDict]) - list of network interface configurations.
First NIC is primary (DHCP by default); subsequent NICs are optional.
Each entry specifies bridge, optional vlan_tag (access) or trunk_vlan_tags,
and dhcp flag.
dhcp flag, and an optional explicit mac address (omit to let the
hypervisor auto-generate one; needed when a caller must know the
MAC ahead of time, e.g. to create a matching DHCP reservation).
cloud_init_config (dict) - user-data dict (will be rendered to YAML).
Should include hostname, bootstrap_token, runcmd, and any custom config.
image_checksum (string | None) - expected checksum of the downloaded
@@ -591,6 +595,10 @@ class HypervisorDriver(DeviceTypeDriver):
If None or empty, no SSH key injection is performed.
disk_resize_gb (int | None) - resize root disk to this size in GB.
If None, disk remains the downloaded image's native size. Default None.
storage (string | None) - name of the storage pool to place the root
disk on (a name returned by ``get_image_storages()``). If None,
the driver auto-detects the first enabled, node-available storage
whose content includes "images".
download_timeout (int) - maximum seconds to wait for the image download
(skipped entirely if already cached on the hypervisor). Default 300.
timeout (int) - maximum seconds to wait for the remaining provisioning
@@ -688,3 +696,21 @@ class HypervisorDriver(DeviceTypeDriver):
per-kind rules).
"""
raise NotImplementedError
def get_image_storages(self) -> List[StorageTargetDict]:
"""
List the storage pools a new VM's root disk may be placed on, scoped to
the specific node the VM will be created on.
Returns only storages that are actually usable for this purpose right
now: content includes "images", administratively enabled, and — for
hypervisors where storage can be restricted to a subset of cluster
nodes — available on this node specifically. A storage configured
cluster-wide but restricted to other nodes must not appear here, since
passing its name to ``create_vm_from_cloud_init(storage=...)`` would fail.
Returns:
List[StorageTargetDict] - each entry's ``name`` is directly usable
as ``create_vm_from_cloud_init``'s ``storage`` argument.
"""
raise NotImplementedError
+13
View File
@@ -713,6 +713,7 @@ class NICConfigDict(TypedDict):
vlan_tag: NotRequired[int | None] # Access VLAN (None = untagged)
trunk_vlan_tags: NotRequired[list[int]] # Trunk VLAN list (alternative to vlan_tag)
dhcp: NotRequired[bool] # Enable DHCP (default True for first NIC, False for others)
mac: NotRequired[str] # Explicit MAC address (omit to let the hypervisor auto-generate one)
class VMProvisionResultDict(TypedDict):
@@ -749,3 +750,15 @@ class NetworkTargetDict(TypedDict):
kind: str # "bridge" or "vnet"
vlan_aware: bool # True if a NICConfigDict.vlan_tag may be set on top of this target
fixed_vlan_tag: NotRequired[int | None] # vnet only: the VLAN ID already baked into it
class StorageTargetDict(TypedDict):
"""A selectable storage pool for a new VM's root disk (``create_vm_from_cloud_init``'s
``storage`` argument), scoped to the specific node the VM will be created on —
a storage restricted to other cluster nodes must not appear here.
"""
name: str # Storage pool name, usable directly as create_vm_from_cloud_init(storage=...)
type: str # Backend type: "dir", "lvmthin", "zfspool", "nfs", etc.
total_gb: float # Total capacity in gigabytes
available_gb: float # Free capacity in gigabytes