From 7e7fad974ae5744ee2f37057e330108ab3a473c1 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Tue, 23 Jan 2024 17:53:03 -0800 Subject: [PATCH 1/5] version check and model update for user --- vmngclient/endpoints/administration_user_and_group.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vmngclient/endpoints/administration_user_and_group.py b/vmngclient/endpoints/administration_user_and_group.py index 8d67e580..3ab6b5b0 100644 --- a/vmngclient/endpoints/administration_user_and_group.py +++ b/vmngclient/endpoints/administration_user_and_group.py @@ -4,7 +4,7 @@ from pydantic.v1 import BaseModel, Field -from vmngclient.endpoints import APIEndpoints, delete, get, post, put +from vmngclient.endpoints import APIEndpoints, delete, get, post, put, versions from vmngclient.typed_list import DataSequence @@ -15,6 +15,7 @@ class User(BaseModel): locale: Optional[str] description: Optional[str] resource_group: Optional[str] = Field(alias="resGroupName") + resource_domain: Optional[str] = Field(alias="resourceDomainName") class UserUpdateRequest(BaseModel): @@ -27,7 +28,10 @@ class UserUpdateRequest(BaseModel): group: Optional[List[str]] locale: Optional[str] description: Optional[str] - resource_group: Optional[str] = Field(alias="resGroupName") + if versions("<=20.13"): + resource_group: Optional[str] = Field(alias="resGroupName") + else: + resource_domain: Optional[str] = Field(alias="resourceDomainName") class UserRole(BaseModel): From ec80813ee8ba77742c093f85bd0c7d15069617d1 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Wed, 10 Apr 2024 15:11:47 -0700 Subject: [PATCH 2/5] admin tech - wait for file ready --- catalystwan/api/admin_tech_api.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/catalystwan/api/admin_tech_api.py b/catalystwan/api/admin_tech_api.py index 06e95c9f..17b14d74 100644 --- a/catalystwan/api/admin_tech_api.py +++ b/catalystwan/api/admin_tech_api.py @@ -10,8 +10,8 @@ from pathlib import Path from typing import TYPE_CHECKING, List, Optional -from requests import Response -from requests.exceptions import HTTPError +from requests import Response # type: ignore +from requests.exceptions import HTTPError # type: ignore from catalystwan.dataclasses import AdminTech, DeviceAdminTech from catalystwan.exceptions import CatalystwanException @@ -120,7 +120,8 @@ def generate( except HTTPError as http_error: response = http_error.response # type: ignore if response.status_code == 200: - return response.json()["fileName"] + filename = response.json()["fileName"] + return self._wait_for_file_ready(filename) if response.status_code == 400 and create_admin_tech_error_msgs in response.json().get("error", {}).get( "details", "" ): @@ -131,6 +132,17 @@ def generate( polling_timer -= polling_interval raise GenerateAdminTechLogError(f"It is not possible to generate admintech log for {device_id}") + def _wait_for_file_ready(self, filename: str, timeout: int = 3600, interval: int = 30) -> str: + # Wait for the file to be ready and obtain the token_id + end_time = time.time() + timeout + while time.time() < end_time: + admin_techs = self.get_all() + for admin_tech in admin_techs: + if filename == admin_tech.filename and admin_tech.state == "done": + return admin_tech.token_id + time.sleep(interval) + raise GenerateAdminTechLogError(f"Timeout waiting for admin tech log to be ready for {filename}") + def _get_token_id(self, filename: str) -> str: admin_techs = self.get_all() for admin_tech in admin_techs: From ea16f46bc9b77e46c0b64506e9d7e7069569f88c Mon Sep 17 00:00:00 2001 From: Nikhil Date: Wed, 10 Apr 2024 20:39:51 -0700 Subject: [PATCH 3/5] get token --- catalystwan/api/admin_tech_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalystwan/api/admin_tech_api.py b/catalystwan/api/admin_tech_api.py index 17b14d74..13464083 100644 --- a/catalystwan/api/admin_tech_api.py +++ b/catalystwan/api/admin_tech_api.py @@ -146,7 +146,7 @@ def _wait_for_file_ready(self, filename: str, timeout: int = 3600, interval: int def _get_token_id(self, filename: str) -> str: admin_techs = self.get_all() for admin_tech in admin_techs: - if filename == admin_tech.filename: + if filename == admin_tech.filename and admin_tech.state == "done": return admin_tech.token_id raise RequestTokenIdNotFound( f"requestTokenId of admin tech generation request not found for file name: {filename}" From ab23db06d6b139ccbb01391b0eb77cdd0e331227 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Wed, 10 Apr 2024 20:57:48 -0700 Subject: [PATCH 4/5] correct logic --- catalystwan/api/admin_tech_api.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/catalystwan/api/admin_tech_api.py b/catalystwan/api/admin_tech_api.py index 13464083..088251f2 100644 --- a/catalystwan/api/admin_tech_api.py +++ b/catalystwan/api/admin_tech_api.py @@ -120,8 +120,7 @@ def generate( except HTTPError as http_error: response = http_error.response # type: ignore if response.status_code == 200: - filename = response.json()["fileName"] - return self._wait_for_file_ready(filename) + return response.json()["fileName"] if response.status_code == 400 and create_admin_tech_error_msgs in response.json().get("error", {}).get( "details", "" ): @@ -132,7 +131,7 @@ def generate( polling_timer -= polling_interval raise GenerateAdminTechLogError(f"It is not possible to generate admintech log for {device_id}") - def _wait_for_file_ready(self, filename: str, timeout: int = 3600, interval: int = 30) -> str: + def _get_token_id(self, filename: str, timeout: int = 3600, interval: int = 30) -> str: # Wait for the file to be ready and obtain the token_id end_time = time.time() + timeout while time.time() < end_time: @@ -141,13 +140,6 @@ def _wait_for_file_ready(self, filename: str, timeout: int = 3600, interval: int if filename == admin_tech.filename and admin_tech.state == "done": return admin_tech.token_id time.sleep(interval) - raise GenerateAdminTechLogError(f"Timeout waiting for admin tech log to be ready for {filename}") - - def _get_token_id(self, filename: str) -> str: - admin_techs = self.get_all() - for admin_tech in admin_techs: - if filename == admin_tech.filename and admin_tech.state == "done": - return admin_tech.token_id raise RequestTokenIdNotFound( f"requestTokenId of admin tech generation request not found for file name: {filename}" ) From 436d5775f6c496b8a8cf66e6b1102247a4a68269 Mon Sep 17 00:00:00 2001 From: PrzeG <86780353+PrzeG@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:06:56 +0200 Subject: [PATCH 5/5] Add default None values to the Tier model (#16) --- .../templates/payloads/tenant/tenant_model.py | 4 ++-- .../endpoints/monitoring_device_details.py | 20 ++++++++++++------- pyproject.toml | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/catalystwan/api/templates/payloads/tenant/tenant_model.py b/catalystwan/api/templates/payloads/tenant/tenant_model.py index 690031d3..77454178 100644 --- a/catalystwan/api/templates/payloads/tenant/tenant_model.py +++ b/catalystwan/api/templates/payloads/tenant/tenant_model.py @@ -20,8 +20,8 @@ class Tenant(BaseModel): organization_name: str tier_name: str - tenant_info: Optional[TenantInfo] - tier_info: Optional[TierInfo] + tenant_info: Optional[TenantInfo] = None + tier_info: Optional[TierInfo] = None class TenantModel(FeatureTemplate): diff --git a/catalystwan/endpoints/monitoring_device_details.py b/catalystwan/endpoints/monitoring_device_details.py index ec5319ee..98afa70e 100644 --- a/catalystwan/endpoints/monitoring_device_details.py +++ b/catalystwan/endpoints/monitoring_device_details.py @@ -25,22 +25,28 @@ class Tier(BaseModel): vpn: int rid: int = Field(serialization_alias="@rid", validation_alias="@rid") ipv4_route_limit_type: Optional[str] = Field( - serialization_alias="ipv4RouteLimitType", validation_alias="ipv4RouteLimitType" + default=None, serialization_alias="ipv4RouteLimitType", validation_alias="ipv4RouteLimitType" ) ipv4_route_limit_threshold: Optional[int] = Field( - serialization_alias="ipv4RouteLimitThreshold", validation_alias="ipv4RouteLimitThreshold" + default=None, serialization_alias="ipv4RouteLimitThreshold", validation_alias="ipv4RouteLimitThreshold" + ) + ipv4_route_limit: Optional[int] = Field( + default=None, serialization_alias="ipv4RouteLimit", validation_alias="ipv4RouteLimit" ) - ipv4_route_limit: Optional[int] = Field(serialization_alias="ipv4RouteLimit", validation_alias="ipv4RouteLimit") ipv6_route_limit_type: Optional[str] = Field( - serialization_alias="ipv6RouteLimitType", validation_alias="ipv6RouteLimitType" + default=None, serialization_alias="ipv6RouteLimitType", validation_alias="ipv6RouteLimitType" ) ipv6_route_limit_threshold: Optional[int] = Field( - serialization_alias="ipv6RouteLimitThreshold", validation_alias="ipv6RouteLimitThreshold" + default=None, serialization_alias="ipv6RouteLimitThreshold", validation_alias="ipv6RouteLimitThreshold" + ) + ipv6_route_limit: Optional[int] = Field( + default=None, serialization_alias="ipv6RouteLimit", validation_alias="ipv6RouteLimit" ) - ipv6_route_limit: Optional[int] = Field(serialization_alias="ipv6RouteLimit", validation_alias="ipv6RouteLimit") tlocs: List[TLOC] = Field(default=[]) # New in 20.12 version - nat_session_limit: Optional[int] = Field(serialization_alias="natSessionLimit", validation_alias="natSessionLimit") + nat_session_limit: Optional[int] = Field( + default=None, serialization_alias="natSessionLimit", validation_alias="natSessionLimit" + ) class DeviceData(BaseModel): diff --git a/pyproject.toml b/pyproject.toml index 59fab1dc..cddb93ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "catalystwan" -version = "0.33.1" +version = "0.33.2" description = "Cisco Catalyst WAN SDK for Python" authors = ["kagorski "] readme = "README.md"