catalystwan 0.41.2.dev4__py3-none-any.whl → 0.41.2.dev6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- catalystwan/exceptions.py +7 -0
- catalystwan/integration_tests/feature_profile/test_parcel.py +54 -0
- catalystwan/models/configuration/feature_profile/parcel.py +12 -6
- catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py +1 -1
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py +1 -1
- {catalystwan-0.41.2.dev4.dist-info → catalystwan-0.41.2.dev6.dist-info}/METADATA +1 -1
- {catalystwan-0.41.2.dev4.dist-info → catalystwan-0.41.2.dev6.dist-info}/RECORD +9 -8
- {catalystwan-0.41.2.dev4.dist-info → catalystwan-0.41.2.dev6.dist-info}/LICENSE +0 -0
- {catalystwan-0.41.2.dev4.dist-info → catalystwan-0.41.2.dev6.dist-info}/WHEEL +0 -0
catalystwan/exceptions.py
CHANGED
|
@@ -216,3 +216,10 @@ class CatalystwanDeprecationWarning(DeprecationWarning):
|
|
|
216
216
|
f" The public API SHOULD NOT be considered stable."
|
|
217
217
|
)
|
|
218
218
|
return message
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class ParcelModelNotFound(CatalystwanException):
|
|
222
|
+
"""Raised when there is no model matching parcelType field"""
|
|
223
|
+
|
|
224
|
+
def __init__(self, type_):
|
|
225
|
+
self.message = f"Cannot determine model class for parcel type: {type_}"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright 2025 Cisco Systems, Inc. and its affiliates
|
|
2
|
+
from typing import Literal, Union
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from typing_extensions import Annotated
|
|
7
|
+
|
|
8
|
+
from catalystwan.api.configuration_groups.parcel import _ParcelBase
|
|
9
|
+
from catalystwan.exceptions import ParcelModelNotFound
|
|
10
|
+
from catalystwan.models.configuration.feature_profile.parcel import find_type, list_types
|
|
11
|
+
from catalystwan.models.configuration.feature_profile.sdwan.topology import (
|
|
12
|
+
AnyTopologyParcel,
|
|
13
|
+
CustomControlParcel,
|
|
14
|
+
HubSpokeParcel,
|
|
15
|
+
MeshParcel,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_list_types():
|
|
20
|
+
observed_types = list_types(AnyTopologyParcel)
|
|
21
|
+
assert set(observed_types) == {MeshParcel, HubSpokeParcel, CustomControlParcel}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_find_type():
|
|
25
|
+
observed_type = find_type("mesh", AnyTopologyParcel)
|
|
26
|
+
assert observed_type == MeshParcel
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_find_type_raises_when_no_match():
|
|
30
|
+
with pytest.raises(ParcelModelNotFound):
|
|
31
|
+
find_type("unknown", AnyTopologyParcel)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_find_type_raises_for_bogus_param():
|
|
35
|
+
with pytest.raises(ParcelModelNotFound):
|
|
36
|
+
find_type("unknown", None)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_find_type_custom():
|
|
40
|
+
# Arrange
|
|
41
|
+
class CustomParcel(_ParcelBase):
|
|
42
|
+
type_: Literal["custom"] = Field(default="custom", exclude=True)
|
|
43
|
+
|
|
44
|
+
CustomUnion = Annotated[
|
|
45
|
+
Union[
|
|
46
|
+
MeshParcel,
|
|
47
|
+
CustomParcel,
|
|
48
|
+
],
|
|
49
|
+
Field(discriminator="type_"),
|
|
50
|
+
]
|
|
51
|
+
# Act
|
|
52
|
+
observed_type = find_type("custom", CustomUnion)
|
|
53
|
+
# Assert
|
|
54
|
+
assert observed_type == CustomParcel
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Copyright 2024 Cisco Systems, Inc. and its affiliates
|
|
2
2
|
from functools import lru_cache
|
|
3
|
-
from typing import Generic, List, Literal, Optional, Sequence, TypeVar, Union, cast
|
|
3
|
+
from typing import Generic, List, Literal, Optional, Sequence, Type, TypeVar, Union, cast
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
6
|
from pydantic import AliasChoices, BaseModel, ConfigDict, Field, model_validator
|
|
7
7
|
from typing_extensions import Annotated
|
|
8
8
|
|
|
9
|
+
from catalystwan.api.configuration_groups.parcel import _ParcelBase
|
|
10
|
+
from catalystwan.exceptions import ParcelModelNotFound
|
|
9
11
|
from catalystwan.models.configuration.feature_profile.sdwan.application_priority import AnyApplicationPriorityParcel
|
|
10
12
|
from catalystwan.models.configuration.feature_profile.sdwan.cli import AnyCliParcel
|
|
11
13
|
from catalystwan.models.configuration.feature_profile.sdwan.dns_security import AnyDnsSecurityParcel
|
|
@@ -160,6 +162,7 @@ AnyParcel = Annotated[
|
|
|
160
162
|
]
|
|
161
163
|
|
|
162
164
|
T = TypeVar("T", bound=AnyParcel)
|
|
165
|
+
UT = TypeVar("UT", bound=_ParcelBase)
|
|
163
166
|
|
|
164
167
|
|
|
165
168
|
class Parcel(BaseModel, Generic[T]):
|
|
@@ -227,12 +230,15 @@ class ParcelId(BaseModel):
|
|
|
227
230
|
|
|
228
231
|
|
|
229
232
|
@lru_cache
|
|
230
|
-
def list_types(any_union:
|
|
231
|
-
return cast(Sequence[
|
|
233
|
+
def list_types(any_union: Type[UT]) -> Sequence[UT]:
|
|
234
|
+
return cast(Sequence[UT], resolve_nested_base_model_unions(any_union))
|
|
232
235
|
|
|
233
236
|
|
|
234
237
|
@lru_cache
|
|
235
|
-
def find_type(name: str, any_union:
|
|
238
|
+
def find_type(name: str, any_union: Type[UT]) -> UT:
|
|
236
239
|
parcel_types = list_types(any_union)
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
try:
|
|
241
|
+
parcel_type = next(t for t in parcel_types if t._get_parcel_type() == name)
|
|
242
|
+
except StopIteration:
|
|
243
|
+
raise ParcelModelNotFound(name)
|
|
244
|
+
return cast(UT, parcel_type)
|
|
@@ -259,7 +259,7 @@ class AppqoeParcel(_ParcelBase):
|
|
|
259
259
|
virtual_application: Optional[List[VirtualApplication]] = Field(
|
|
260
260
|
default=None, validation_alias=AliasPath("data", "virtualApplication")
|
|
261
261
|
)
|
|
262
|
-
appqoe_device_role: Global[
|
|
262
|
+
appqoe_device_role: Global[AppqoeDeviceRole] = Field(
|
|
263
263
|
default=as_global("forwarder"), validation_alias=AliasPath("data", "appqoeDeviceRole")
|
|
264
264
|
)
|
|
265
265
|
|
|
@@ -168,7 +168,7 @@ class IPv4RouteGatewayNextHop(BaseModel):
|
|
|
168
168
|
class IPv4RouteGatewayNextHopWithTracker(BaseModel):
|
|
169
169
|
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
|
|
170
170
|
|
|
171
|
-
address: Union[Variable, Global[str]]
|
|
171
|
+
address: Union[Variable, Global[str], Global[IPv4Address]]
|
|
172
172
|
distance: Union[Variable, Global[int], Default[int]] = Default[int](value=1)
|
|
173
173
|
tracker: Union[Global[UUID], Default[None]] = as_default(None)
|
|
174
174
|
|
|
@@ -212,7 +212,7 @@ catalystwan/endpoints/tenant_management.py,sha256=c-kIRoS60aVklVPPrmbnW5kaiNgU23
|
|
|
212
212
|
catalystwan/endpoints/tenant_migration.py,sha256=e6eIzRvlrnzUWqamKbWsYjX8drtB-GQKvhrJtX2VDKY,3649
|
|
213
213
|
catalystwan/endpoints/troubleshooting_tools/device_connectivity.py,sha256=JkTZfebTwcambJsgjcJ8qxxBDE5XbUFyYpNqr9681DQ,3661
|
|
214
214
|
catalystwan/endpoints/url_monitoring.py,sha256=ZySOjuCpIAZ4SIsah56yJ-uybYw0W9s6OjQp2FujN0g,802
|
|
215
|
-
catalystwan/exceptions.py,sha256=
|
|
215
|
+
catalystwan/exceptions.py,sha256=MAtoZ9xrXmUgG-zMbdtChF7B2sHAgVlzv-euHOY1kKo,6620
|
|
216
216
|
catalystwan/integration_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
217
217
|
catalystwan/integration_tests/base.py,sha256=0BcKgDZcGjdPH2316C-1Se4FUeAtdrNXdkUVp_aXEZc,2367
|
|
218
218
|
catalystwan/integration_tests/feature_profile/sdwan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -231,6 +231,7 @@ catalystwan/integration_tests/feature_profile/sdwan/test_system.py,sha256=ab6fG7
|
|
|
231
231
|
catalystwan/integration_tests/feature_profile/sdwan/test_tracker.py,sha256=GnIEHmUoIZObtBK-YvjYYtDsFnGSDpAVwi4rk9-r7XE,5117
|
|
232
232
|
catalystwan/integration_tests/feature_profile/sdwan/test_transport.py,sha256=xRS880JCUD06xL_EaHKNylvaXB9wRHqUYsORhU2MYus,78923
|
|
233
233
|
catalystwan/integration_tests/feature_profile/sdwan/topology/test_topology.py,sha256=2vsAd0pk3wcfo8wFTRttnw4gjSPJi1KFfFCu5lGAiJQ,4340
|
|
234
|
+
catalystwan/integration_tests/feature_profile/test_parcel.py,sha256=4dqt5IP39lJ6vTsx3X7OdAHpYdbsIlDdpASFAM6d87Y,1517
|
|
234
235
|
catalystwan/integration_tests/profile_builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
235
236
|
catalystwan/integration_tests/profile_builder/test_pb_service.py,sha256=WO6VVA7kNXesyGtk67e0lMDZBd4Z8wB7espBh0TzUTA,9420
|
|
236
237
|
catalystwan/integration_tests/profile_builder/test_pb_transport.py,sha256=QQ5f1q6OV9dIyRQy1lb3Wp9beIKaWDaDLnNoGm4XY6A,10376
|
|
@@ -245,7 +246,7 @@ catalystwan/models/configuration/common.py,sha256=2X9gj5awWPKtLPFgWfxhkRrMoX22t1
|
|
|
245
246
|
catalystwan/models/configuration/feature_profile/README.md,sha256=IQMhbnEAbLtotT80aL2emekH-ou8CqR0WSYXhZXilJw,10050
|
|
246
247
|
catalystwan/models/configuration/feature_profile/builder.py,sha256=GDqK7ZxnWHTKWHRw13xvD1aDl60xe6gFsP_B9z5T8a8,663
|
|
247
248
|
catalystwan/models/configuration/feature_profile/common.py,sha256=a5xohaoXzAewtqYYdk2GJy7B-rxxlxYatlP2WZ1eZqY,30423
|
|
248
|
-
catalystwan/models/configuration/feature_profile/parcel.py,sha256=
|
|
249
|
+
catalystwan/models/configuration/feature_profile/parcel.py,sha256=k3IyNVzjtDrTjUEBYvzQeQWeqNhRNk2tXDYqbQXWX2o,7583
|
|
249
250
|
catalystwan/models/configuration/feature_profile/sdwan/acl/__init__.py,sha256=-AXvVMLyaAYWUnwzTT_mvar37ZpO2vNRy_ZsUIA5dGo,324
|
|
250
251
|
catalystwan/models/configuration/feature_profile/sdwan/acl/ipv4acl.py,sha256=HpiY0DCZWE9EHCbMbyIJ-iRharSRO3IGcSV3kWbMXjY,12167
|
|
251
252
|
catalystwan/models/configuration/feature_profile/sdwan/acl/ipv6acl.py,sha256=MRtDNb2v1TNNf3yijLFlzL3H1KxHOquPmww1V9ZCacI,12969
|
|
@@ -314,7 +315,7 @@ catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py,sha256=4vX
|
|
|
314
315
|
catalystwan/models/configuration/feature_profile/sdwan/routing/ospf.py,sha256=hfsfL9Fy4q7eUybhSzPDGTFgdlK1VO3zPUy1aNOOCIc,7647
|
|
315
316
|
catalystwan/models/configuration/feature_profile/sdwan/routing/ospfv3.py,sha256=KW0UgMPt08OxLbX4JoShNby83HCMhlHICRLLW8pYinQ,13268
|
|
316
317
|
catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py,sha256=AzPWWFozmwg5nzwEj-bYhg2HTeJJ8FFPQHmvyxDvSnQ,2378
|
|
317
|
-
catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py,sha256=
|
|
318
|
+
catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py,sha256=6_diZuOtJnq0x6QFuwHQ3IgSmV5a6S-Yql7uN-JlF8c,10223
|
|
318
319
|
catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py,sha256=XCYUektYRLZaIzJAiAuSeuKg2DdAYio38t0niN8CkhA,5289
|
|
319
320
|
catalystwan/models/configuration/feature_profile/sdwan/service/dual_router_ha.py,sha256=MMwnBKBth3E91EYCPLtGJqwQYilZPWelGF6KLJmtOPw,1134
|
|
320
321
|
catalystwan/models/configuration/feature_profile/sdwan/service/eigrp.py,sha256=d02hMwUFq5ycoknQci0SAgRlxuiYh0kSKDBxOzn-ves,4075
|
|
@@ -324,7 +325,7 @@ catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py,sha256
|
|
|
324
325
|
catalystwan/models/configuration/feature_profile/sdwan/service/lan/ipsec.py,sha256=jFwQK-xLl_l9aahCX326wRIcEobElfdFxeZY0ofXD5w,7043
|
|
325
326
|
catalystwan/models/configuration/feature_profile/sdwan/service/lan/multilink.py,sha256=EKUIQDq40P01irYFWZ1fACFK6R8AusT6s96bH4qHWUg,5403
|
|
326
327
|
catalystwan/models/configuration/feature_profile/sdwan/service/lan/svi.py,sha256=B9LmnmTNHUQUVYI7071Z2j4s5pJN9SUfWQEuNb1czV8,9114
|
|
327
|
-
catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py,sha256=
|
|
328
|
+
catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py,sha256=3CfGxWQ9R9YHRJpLHzdtpjGVoNqz2VwrioCXdzi5A7k,24231
|
|
328
329
|
catalystwan/models/configuration/feature_profile/sdwan/service/multicast.py,sha256=DXvUUsPVNCmkN-YLqQArP9NKjL444UPfoZavC87i2fw,10821
|
|
329
330
|
catalystwan/models/configuration/feature_profile/sdwan/service/object_tracker.py,sha256=WeKWXT54cyf5r9S-PZLe_M8b2iXgRNwujJVLxxeNnsw,3291
|
|
330
331
|
catalystwan/models/configuration/feature_profile/sdwan/service/route_policy.py,sha256=JSThUK1D3PsCrJCwDL4vEkiPn01cAkBc9XX6IwzJuAY,15765
|
|
@@ -630,7 +631,7 @@ catalystwan/version.py,sha256=X5yIMPIrWPbdoF9eJfwxfjcvWr7JMfWQF98hQhlGB5I,3032
|
|
|
630
631
|
catalystwan/vmanage_auth.py,sha256=UZ57lTihsLsXw4AdU7Vn8XuY1jo3732Vc9WuFoHSiiQ,10780
|
|
631
632
|
catalystwan/workflows/backup_restore_device_templates.py,sha256=BoR2KlRbpCI6RxIWG7j7tucaLpw5w3ESN20dLhsrZFY,19796
|
|
632
633
|
catalystwan/workflows/tenant_migration.py,sha256=4KLbqUwH4gEegE92PCGfRd226eZd_crCUpaYUWoGXDI,9790
|
|
633
|
-
catalystwan-0.41.2.
|
|
634
|
-
catalystwan-0.41.2.
|
|
635
|
-
catalystwan-0.41.2.
|
|
636
|
-
catalystwan-0.41.2.
|
|
634
|
+
catalystwan-0.41.2.dev6.dist-info/LICENSE,sha256=97ROi91Vxrj_Jio2v8FI9E8-y6x2uYdQRaFlrEbVjkc,11375
|
|
635
|
+
catalystwan-0.41.2.dev6.dist-info/METADATA,sha256=_U2izirHEsCyVz8rO2eGD5-YkcT7hmWw8DCCif5qRqQ,21275
|
|
636
|
+
catalystwan-0.41.2.dev6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
637
|
+
catalystwan-0.41.2.dev6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|