Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

Commit

Permalink
dev-uxmt: Converter: as-path (#766)
Browse files Browse the repository at this point in the history
* Add converter

* Add unit tests

* Fix unit tests

* Fix docstring
  • Loading branch information
jpkrajewski authored Jul 17, 2024
1 parent cbd278b commit 477ab77
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 4 deletions.
9 changes: 9 additions & 0 deletions catalystwan/models/configuration/config_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ class PolicyConvertContext:
zone_based_firewall_residues: Dict[UUID, List[ZoneBasedFWPolicyEntry]] = field(default_factory=dict)
security_policy_residues: Dict[UUID, SecurityPolicyResidues] = field(default_factory=dict)
qos_map_residues: Dict[UUID, List[QoSMapResidues]] = field(default_factory=dict)
as_path_list_num_mapping: Dict[str, int] = field(default_factory=dict)

def get_vpn_id_to_vpn_name_map(self) -> Dict[Union[str, int], List[str]]:
vpn_map: Dict[Union[str, int], List[str]] = {}
Expand All @@ -562,6 +563,14 @@ def get_vpn_id_to_vpn_name_map(self) -> Dict[Union[str, int], List[str]]:
vpn_map[v].append(k)
return vpn_map

def generate_as_path_list_num_from_name(self, name: str) -> int:
"""The UX1 and UX2 intersection in AS Path list name and ID but only for the ISR Edge router (number 1 to 500).
If there is number we can insert the value in as_path_list_num field otherwise we will
generate the value and keep track of it in the context."""
number = len(self.as_path_list_num_mapping) + 1
self.as_path_list_num_mapping[name] = number
return number

@staticmethod
def from_configs(
network_hierarchy: List[NodeInfo],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import unittest

from catalystwan.models.configuration.config_migration import PolicyConvertContext
from catalystwan.models.configuration.feature_profile.sdwan.policy_object.policy.as_path import AsPathParcel
from catalystwan.models.policy.list.as_path import ASPathList, ASPathListEntry
from catalystwan.utils.config_migration.converters.policy.policy_lists import convert


class TestAsPathConverter(unittest.TestCase):
def setUp(self) -> None:
self.context = PolicyConvertContext()

def test_aspath_with_name_conversion(self):
# Arrange
name = "aspath"
description = "aspath description"
entry_1 = "600008"
entry_2 = "600009"
entry_3 = "600010"
aspath = ASPathList(
name=name,
description=description,
)
for entry in [entry_1, entry_2, entry_3]:
aspath._add_entry(ASPathListEntry(as_path=entry))
# Act
parcel = convert(aspath, self.context).output
# Assert
assert isinstance(parcel, AsPathParcel)
assert parcel.parcel_name == name
assert parcel.parcel_description == description
assert len(parcel.entries) == 3
assert parcel.entries[0].as_path.value == entry_1
assert parcel.entries[1].as_path.value == entry_2
assert parcel.entries[2].as_path.value == entry_3
assert parcel.as_path_list_num.value == self.context.as_path_list_num_mapping[name]

def test_aspath_with_number_conversion(self):
# Arrange
name = "490"
description = "aspath description"
aspath = ASPathList(
name=name,
description=description,
)
# Act
parcel = convert(aspath, self.context).output
# Assert
assert isinstance(parcel, AsPathParcel)
assert parcel.parcel_name == name
assert parcel.parcel_description == description
assert len(parcel.entries) == 0
assert parcel.as_path_list_num.value == 490
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from pydantic import ValidationError

from catalystwan.api.configuration_groups.parcel import as_global
from catalystwan.models.common import int_range_serializer, int_range_str_validator
from catalystwan.models.configuration.config_migration import ConvertResult, PolicyConvertContext
from catalystwan.models.configuration.feature_profile.sdwan.policy_object import (
Expand Down Expand Up @@ -92,11 +93,33 @@ def app_list(in_: AppList, context) -> ConvertResult[ApplicationListParcel]:
return ConvertResult[ApplicationListParcel](output=out, status="complete")


def as_path(in_: ASPathList, context) -> ConvertResult[AsPathParcel]:
out = AsPathParcel(**_get_parcel_name_desc(in_))
def as_path(in_: ASPathList, context: PolicyConvertContext) -> ConvertResult[AsPathParcel]:
"""There is a mismatch between UX1 and UX2 models:
UX1:
- AS Path List Name (Alphanumeric value for vEdge, or number from 1 to 500 for ISR Edge router)
- AS Path list
UX2:
- Parcel name
- Parcel description
- AS Path List ID (Number from 1 to 500)
- AS Path list
The UX1 and UX2 intersection in AS Path list name and ID but only for the ISR Edge router (number 1 to 500).
If there is number we can insert the value in as_path_list_num field otherwise we will
generate the value and keep track of it in the context.
"""
result = ConvertResult[AsPathParcel](output=None)
if in_.name.isdigit():
as_path_list_num = int(in_.name)
else:
as_path_list_num = context.generate_as_path_list_num_from_name(in_.name)
result.update_status("partial", f"Mapped AS Path List Name: '{in_.name}' to ID: '{as_path_list_num}'")
out = AsPathParcel(**_get_parcel_name_desc(in_), as_path_list_num=as_global(as_path_list_num))
for entry in in_.entries:
out.add_as_path(entry.as_path)
return ConvertResult[AsPathParcel](output=out, status="complete")
result.output = out
return result


def class_map(in_: ClassMapList, context) -> ConvertResult[FowardingClassParcel]:
Expand Down Expand Up @@ -388,7 +411,7 @@ def zone(in_: ZoneList, context) -> ConvertResult[SecurityZoneListParcel]:
CONVERTERS: Mapping[Type[Input], Callable[..., Output]] = {
AppProbeClassList: app_probe,
AppList: app_list,
# ASPathList: as_path,
ASPathList: as_path,
ClassMapList: class_map,
ColorList: color,
CommunityList: community,
Expand Down

0 comments on commit 477ab77

Please sign in to comment.