Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions tests/test_node_image_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,36 @@ def test_remove_dropfolder_image() -> None:
assert session.delete.mock_calls[0].args[0] == "images/manage/image.qcow2"


def test_reload_definitions() -> None:
"""reload_definitions returns report with node and image definition changes.

NOTE: LLM-generated test -- verify for correctness.
"""
session = MagicMock()
defs = NodeImageDefinitions(session)
expected_report = {
"node_definitions": {
"unchanged": ["iosv", "nxosv"],
"updated": ["asav"],
"new": ["custom-node"],
"removed": ["old-node"],
"failed": [],
},
"image_definitions": {
"unchanged": ["iosv-159-3"],
"updated": [],
"new": ["custom-image"],
"removed": [],
"failed": ["Error loading bad-image.yaml"],
},
}
session.put.return_value.json.return_value = expected_report

report = defs.reload_definitions()
assert report == expected_report
assert session.put.mock_calls[0].args[0] == defs._URL_TEMPLATES["reload_defs"]


# everything except str or dict is invalid
INVALID_DEFINITIONS: dict[str, Any] = {
"none": None,
Expand Down
27 changes: 26 additions & 1 deletion virl2_client/models/node_image_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar

from ..exceptions import InvalidContentType, InvalidImageFile
from ..utils import get_url_from_template
from ..utils import _requires_version, get_url_from_template

if TYPE_CHECKING:
import httpx
Expand All @@ -49,6 +49,7 @@ class NodeImageDefinitions:
"upload": "images/upload",
"image_list": "list_image_definition_drop_folder",
"image_manage": "images/manage/{filename}",
"reload_defs": "reload_definitions",
}

def __init__(self, session: httpx.Client) -> None:
Expand Down Expand Up @@ -313,6 +314,30 @@ def remove_image_definition(self, definition_id: str) -> None:
url = self._url_for("image_def", definition_id=definition_id)
self._session.delete(url)

@_requires_version("2.10.0")
def reload_definitions(self) -> dict[str, dict[str, list[str]]]:
"""
Reload node and image definitions from disk.
Comment thread
tmikuska marked this conversation as resolved.

Triggers a re-scan of node and image definition YAML files,
returning a report of changes (unchanged, updated, new, removed, failed).

Requires CML server >= 2.10.

Requires admin permission.

Example::

report = client_library.definitions.reload_definitions()
print(f"New node definitions: {report['node_definitions']['new']}")
print(f"Updated image definitions: {report['image_definitions']['updated']}")

:returns: Report dict with node_definitions and image_definitions keys,
each containing lists of unchanged, updated, new, removed, and failed entries.
"""
url = self._url_for("reload_defs")
return self._session.put(url).json()


def print_progress_bar(
cur: int, total: int, start_time: float, length: int = 50
Expand Down
Loading