mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 12:30:13 +03:00
nodes: per-node netmiko_device_type (controller-only)
netmiko_device_type follows the CONTROLLER_ONLY_PROPERTIES pattern (like console_auto_start): a node created from a template inherits the template value, PUT /nodes can override it inside a topology, updates never round-trip to the compute, and the value persists in the project topology file.
This commit is contained in:
parent
9260108f53
commit
d64f47afa4
@ -57,6 +57,7 @@ class Node:
|
||||
"ports",
|
||||
"category",
|
||||
"console_auto_start",
|
||||
"netmiko_device_type",
|
||||
]
|
||||
|
||||
def __init__(self, project, compute, name, node_id=None, node_type=None, template_id=None, **kwargs):
|
||||
@ -112,6 +113,7 @@ class Node:
|
||||
self._port_segment_size = 0
|
||||
self._first_port_name = None
|
||||
self._console_auto_start = False
|
||||
self._netmiko_device_type = None
|
||||
|
||||
# This properties will be recomputed
|
||||
ignore_properties = ("width", "height", "hover_symbol")
|
||||
@ -212,6 +214,14 @@ class Node:
|
||||
def console_auto_start(self, val):
|
||||
self._console_auto_start = val
|
||||
|
||||
@property
|
||||
def netmiko_device_type(self):
|
||||
return self._netmiko_device_type
|
||||
|
||||
@netmiko_device_type.setter
|
||||
def netmiko_device_type(self, val):
|
||||
self._netmiko_device_type = val
|
||||
|
||||
@property
|
||||
def properties(self):
|
||||
return self._properties
|
||||
@ -833,6 +843,7 @@ class Node:
|
||||
"console": self._console,
|
||||
"console_type": self._console_type,
|
||||
"console_auto_start": self._console_auto_start,
|
||||
"netmiko_device_type": self._netmiko_device_type,
|
||||
"aux": self._aux,
|
||||
"aux_type": self._aux_type,
|
||||
"properties": self._properties,
|
||||
|
||||
@ -116,6 +116,11 @@ class NodeBase(BaseModel):
|
||||
console_auto_start: Optional[bool] = Field(
|
||||
False, description="Automatically start the console when the node has started"
|
||||
)
|
||||
netmiko_device_type: Optional[str] = Field(
|
||||
None,
|
||||
description="Device type for Netmiko-based automation tools, overrides the template value",
|
||||
pattern=r"^[a-z0-9_]+$",
|
||||
)
|
||||
aux: Optional[int] = Field(None, gt=0, le=65535, description="Auxiliary console TCP port")
|
||||
aux_type: Optional[ConsoleType] = None
|
||||
properties: Optional[dict] = Field(default_factory=dict, description="Properties specific to an emulator")
|
||||
|
||||
@ -142,6 +142,7 @@ def test_json(node, compute):
|
||||
"tags": [],
|
||||
"custom_adapters": [],
|
||||
"console_auto_start": False,
|
||||
"netmiko_device_type": None,
|
||||
"ports": [
|
||||
{
|
||||
"adapter_number": 0,
|
||||
@ -179,6 +180,7 @@ def test_json(node, compute):
|
||||
"custom_adapters": [],
|
||||
"tags": [],
|
||||
"console_auto_start": False,
|
||||
"netmiko_device_type": None,
|
||||
}
|
||||
|
||||
|
||||
@ -383,6 +385,36 @@ async def test_update_only_controller(node, compute):
|
||||
assert not node._project.emit_notification.called
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_netmiko_device_type(node, compute):
|
||||
"""
|
||||
netmiko_device_type is a controller-only property: updating it must not
|
||||
call the compute and must be visible in the node json.
|
||||
"""
|
||||
|
||||
compute.put = AsyncioMagicMock()
|
||||
node._project.emit_notification = AsyncioMagicMock()
|
||||
node._project.dump = MagicMock()
|
||||
|
||||
await node.update(netmiko_device_type="cisco_ios_telnet")
|
||||
assert not compute.put.called
|
||||
assert node.netmiko_device_type == "cisco_ios_telnet"
|
||||
assert node.asdict()["netmiko_device_type"] == "cisco_ios_telnet"
|
||||
|
||||
|
||||
def test_netmiko_device_type_from_template_kwargs(compute, project):
|
||||
"""
|
||||
A node created with the template properties as kwargs inherits
|
||||
netmiko_device_type without sending it to the compute.
|
||||
"""
|
||||
|
||||
node = Node(project, compute, "test", node_type="vpcs", netmiko_device_type="nokia_srl")
|
||||
assert node.netmiko_device_type == "nokia_srl"
|
||||
# controller-only: must not leak into the compute properties
|
||||
assert "netmiko_device_type" not in node.properties
|
||||
assert node.asdict(topology_dump=True)["netmiko_device_type"] == "nokia_srl"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_no_changes(node, compute):
|
||||
"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user