Skip to content

Commit

Permalink
Release/v2.7.1 (#104)
Browse files Browse the repository at this point in the history
* Update version to 2.7.1

* Re-added api/* to the doc source tree removed by mistake

* Updated deps

* Updated PCL version and deprecated offline support

* Updated deps

* Fixed various problems in user and group modules

* Added missing properties into user methods

* Updated urllib3 to non-vulnerable version
  • Loading branch information
tmikuska authored Jul 25, 2024
1 parent 5bf320f commit 2b9e98f
Show file tree
Hide file tree
Showing 9 changed files with 578 additions and 504 deletions.
985 changes: 516 additions & 469 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "virl2_client"
version = "2.7.0"
version = "2.7.1"
description = "VIRL2 Client Library"
authors = ["Simon Knight <[email protected]>", "Ralph Schmieder <[email protected]>"]
license = "Apache-2.0"
Expand Down
24 changes: 12 additions & 12 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@ certifi==2024.2.2 ; python_full_version >= "3.8.1" and python_full_version < "4.
cfgv==3.4.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
colorama==0.4.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and sys_platform == "win32"
distlib==0.3.8 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
exceptiongroup==1.2.0 ; python_full_version >= "3.8.1" and python_version < "3.11"
filelock==3.13.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
exceptiongroup==1.2.1 ; python_full_version >= "3.8.1" and python_version < "3.11"
filelock==3.14.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
flake8==7.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
h11==0.14.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
httpcore==1.0.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
httpcore==1.0.5 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
httpx==0.26.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
identify==2.5.35 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
idna==3.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
identify==2.5.36 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
idna==3.7 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
iniconfig==2.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
mccabe==0.7.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
nodeenv==1.8.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
packaging==23.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
platformdirs==4.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pluggy==1.4.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
packaging==24.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
platformdirs==4.2.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pluggy==1.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pre-commit==3.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pycodestyle==2.11.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pyflakes==3.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pytest==7.4.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
pyyaml==6.0.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
respx==0.20.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
setuptools==69.1.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
sniffio==1.3.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
setuptools==69.5.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
sniffio==1.3.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
tomli==2.0.1 ; python_full_version >= "3.8.1" and python_version < "3.11"
typing-extensions==4.9.0 ; python_full_version >= "3.8.1" and python_version < "3.11"
virtualenv==20.25.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
typing-extensions==4.11.0 ; python_full_version >= "3.8.1" and python_version < "3.11"
virtualenv==20.26.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
3 changes: 2 additions & 1 deletion tests/test_client_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,8 @@ def test_import_lab_offline(
topology_file_path = test_dir / "test_data/sample_topology.json"
with open(topology_file_path) as fh:
topology_file = fh.read()
client_library.import_lab(topology_file, "topology-v0_0_4", offline=True)
with pytest.deprecated_call():
client_library.import_lab(topology_file, "topology-v0_0_4", offline=True)


def test_convergence_parametrization(client_library_server_current, mocked_session):
Expand Down
2 changes: 1 addition & 1 deletion virl2_client/models/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def auth_flow(

def logout(self, clear_all_sessions=False) -> bool:
"""
Log out the user. Invalidates the current token.
Log out the user (invalidate the current token).
:param clear_all_sessions: Whether to clear all sessions.
:returns: Whether the logout succeeded.
Expand Down
3 changes: 1 addition & 2 deletions virl2_client/models/cl_pyats.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ def _load_pyats_testbed(self, testbed_yaml: str) -> Testbed:

def sync_testbed(self, username: str, password: str) -> None:
"""
Sync the testbed from the server.
This fetches the latest topology data from the server.
Sync the testbed (the latest topology data) from the server.
:param username: The username to be inserted into the testbed data.
:param password: The password to be inserted into the testbed data.
Expand Down
14 changes: 7 additions & 7 deletions virl2_client/models/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from typing import TYPE_CHECKING

from ..utils import UNCHANGED, get_url_from_template
from ..utils import get_url_from_template

if TYPE_CHECKING:
import httpx
Expand Down Expand Up @@ -109,9 +109,9 @@ def update_group(
self,
group_id: str,
name: str | None = None,
description: str | None = UNCHANGED,
members: list[str] | None = UNCHANGED,
labs: list[dict[str, str]] | None = UNCHANGED,
description: str | None = None,
members: list[str] | None = None,
labs: list[dict[str, str]] | None = None,
) -> dict:
"""
Update a group.
Expand All @@ -126,11 +126,11 @@ def update_group(
data: dict[str, str | list] = {}
if name is not None:
data["name"] = name
if description is not UNCHANGED:
if description is not None:
data["description"] = description
if members is not UNCHANGED:
if members is not None:
data["members"] = members
if labs is not UNCHANGED:
if labs is not None:
data["labs"] = labs
url = self._url_for("group", group_id=group_id)
return self._session.patch(url, json=data).json()
Expand Down
39 changes: 30 additions & 9 deletions virl2_client/models/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from typing import TYPE_CHECKING, Any

from ..utils import UNCHANGED, get_url_from_template
from ..utils import UNCHANGED, _Sentinel, get_url_from_template

if TYPE_CHECKING:
import httpx
Expand All @@ -49,7 +49,7 @@ def _url_for(self, endpoint, **kwargs):
"""
return get_url_from_template(endpoint, self._URL_TEMPLATES, kwargs)

def users(self) -> list[str]:
def users(self) -> list[dict]:
"""
Get the list of available users.
Expand Down Expand Up @@ -83,9 +83,12 @@ def create_user(
pwd: str,
fullname: str = "",
description: str = "",
email: str = "",
admin: bool = False,
groups: list[str] | None = None,
resource_pool: str | None = None,
opt_in: bool | None = None,
tour_version: str = "",
) -> dict:
"""
Create a new user.
Expand All @@ -94,58 +97,76 @@ def create_user(
:param pwd: Desired password.
:param fullname: Full name.
:param description: Description.
:param email: Email address.
:param admin: Whether to create an admin user.
:param groups: List of groups to which the user should be added.
:param resource_pool: Resource pool to which the user should be added.
:param opt_in: Whether the user has seen the initial contact dialog.
:param tour_version: The version of the Workbench tour the user has completed.
:returns: User object.
"""
data = {
"username": username,
"password": pwd,
"fullname": fullname,
"description": description,
"email": email,
"admin": admin,
"groups": groups or [],
"resource_pool": resource_pool,
"opt_in": opt_in,
"tour_version": tour_version,
}
url = self._url_for("users")
return self._session.post(url, json=data).json()

def update_user(
self,
user_id: str,
fullname: str | None = UNCHANGED,
description: str | None = UNCHANGED,
groups: list[str] | None = UNCHANGED,
fullname: str | None = None,
description: str | None = None,
email: str | None = None,
groups: list[str] | None = None,
admin: bool | None = None,
password_dict: dict[str, str] | None = None,
resource_pool: str | None = UNCHANGED,
resource_pool: str | None | _Sentinel = UNCHANGED,
opt_in: bool | None | _Sentinel = UNCHANGED,
tour_version: str | None = None,
) -> dict:
"""
Update an existing user.
:param user_id: User UUID4.
:param fullname: Full name.
:param description: Description.
:param email: Email address.
:param admin: Whether to create an admin user.
:param groups: List of groups to which the user should be added.
:param password_dict: Dictionary containing old and new passwords.
:param resource_pool: Resource pool to which the user should be added.
:param opt_in: Whether the user has seen the initial contact dialog.
:param tour_version: The version of the Workbench tour the user has completed.
:returns: User object.
"""
data: dict[str, Any] = {}
if fullname is not UNCHANGED:
if fullname is not None:
data["fullname"] = fullname
if description is not UNCHANGED:
if description is not None:
data["description"] = description
if email is not None:
data["email"] = email
if admin is not None:
data["admin"] = admin
if groups is not UNCHANGED:
if groups is not None:
data["groups"] = groups
if password_dict is not None:
data["password"] = password_dict
if resource_pool is not UNCHANGED:
data["resource_pool"] = resource_pool
if opt_in is not UNCHANGED:
data["opt_in"] = opt_in
if tour_version is not None:
data["tour_version"] = tour_version

url = self._url_for("user", user_id=user_id)
return self._session.patch(url, json=data).json()
Expand Down
10 changes: 8 additions & 2 deletions virl2_client/virl2_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import os
import re
import time
import warnings
from functools import lru_cache
from pathlib import Path
from threading import RLock
Expand Down Expand Up @@ -164,7 +165,7 @@ class ClientLibrary:
"""Python bindings for the REST API of a CML controller."""

# current client version
VERSION = Version("2.7.0")
VERSION = Version("2.7.1")
# list of Version objects
INCOMPATIBLE_CONTROLLER_VERSIONS = [
Version("2.0.0"),
Expand Down Expand Up @@ -521,7 +522,7 @@ def import_lab(
self,
topology: str,
title: str | None = None,
offline: bool = False,
offline: bool | None = None,
virl_1x: bool = False,
) -> Lab:
"""
Expand All @@ -530,6 +531,7 @@ def import_lab(
:param topology: The topology representation as a string.
:param title: The title of the lab.
:param offline: Whether to import the lab locally.
DEPRECATED: The offline mode will be removed in the next version.
:param virl_1x: Whether the topology format is the old, VIRL 1.x format.
:returns: The imported Lab instance.
:raises ValueError: If no lab ID is returned in the API response.
Expand All @@ -542,6 +544,10 @@ def import_lab(
lab.sync()
return lab
if offline:
warnings.warn(
"The offline mode will be removed in the next version.",
DeprecationWarning,
)
lab_id = "offline_lab"
else:
if virl_1x:
Expand Down

0 comments on commit 2b9e98f

Please sign in to comment.