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

Commit

Permalink
Merge pull request #528 from CiscoDevNet/fix/bgp
Browse files Browse the repository at this point in the history
Cover more fields in BGP
  • Loading branch information
jpkrajewski authored Mar 18, 2024
2 parents 4d30386 + cdf14b3 commit 6c8e7b2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from catalystwan.api.configuration_groups.parcel import Default, Global, Variable, _ParcelBase, as_variable

FamilyType = Literal["ipv4-unicast", "vpnv4-unicast", "vpnv6-unicast"]
FamilyType1 = Literal["ipv6-unicast", "vpnv6-unicast"]
FamilyTypeIpv6 = Literal["ipv6-unicast", "vpnv6-unicast"]
Mask = Literal[
"255.255.255.255",
"255.255.255.254",
Expand Down Expand Up @@ -157,7 +157,7 @@ class AddressFamilyItem(BaseModel):
serialization_alias="maxPrefixConfig",
validation_alias="maxPrefixConfig",
description="Set maximum number of prefixes accepted from BGP peer"
"and threshold exceeded policy actions(restart or warning)",
"and threshold exceeded policy actions (restart or warning)",
)
in_route_policy: Optional[Union[RefIdItem, Default[None]]] = Field(
default=None,
Expand Down Expand Up @@ -279,7 +279,7 @@ class VariableFamilyItem1(BaseModel):
extra="forbid",
populate_by_name=True,
)
family_type: Global[FamilyType1] = Field(
family_type: Global[FamilyTypeIpv6] = Field(
...,
serialization_alias="familyType",
validation_alias="familyType",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import logging
from copy import deepcopy
from typing import Dict, List, cast

from catalystwan.api.configuration_groups.parcel import as_variable
from catalystwan.api.configuration_groups.parcel import Variable, as_global, as_variable
from catalystwan.models.configuration.feature_profile.sdwan.transport import BGPParcel
from catalystwan.models.configuration.feature_profile.sdwan.transport.bgp import (
FamilyType,
FamilyTypeIpv6,
MaxPrefixConfigWarningDisablePeer,
PolicyTypeWarningDisablePeer,
)

logger = logging.getLogger(__name__)


class BGPTemplateConverter:
Expand All @@ -22,22 +31,54 @@ def create_parcel(name: str, description: str, template_values: dict) -> BGPParc
BannerParcel: A BannerParcel object with the provided template values.
"""
device_specific_ipv4_neighbor_address = "{{{{lbgp_1_neighbor_{index}_address}}}}"
device_specific_ipv6_neighbor_address = "{{{{lbgp_1_ipv6_neighbor_{index}_address}}}}"

parcel_values = {"parcel_name": name, "parcel_description": description, **deepcopy(template_values["bgp"])}

shutdown = parcel_values.get("shutdown")
neighbors = cast(List[Dict], parcel_values.get("neighbor", []))
if neighbors:
for i, neighbor in enumerate(neighbors):
remote_as = neighbor.get("remote_as", as_variable("{{lbgp_1_remote_as}}"))
if isinstance(remote_as, Variable):
logger.info("Remote AS is not set, using device specific variable")
neighbor["remote_as"] = remote_as
if address_family := neighbor.get("address_family", []):
for family_type in address_family:
family_type["family_type"] = as_global(family_type["family_type"].value, FamilyType)
if neighbor.get("address") is None:
logger.info("Neighbor address is not set, using device specific variable")
neighbor["address"] = as_variable(device_specific_ipv4_neighbor_address.format(index=(i + 1)))
if if_name := neighbor.get("update_source", {}).get("if_name"):
neighbor["if_name"] = if_name
neighbor.pop("update_source")
if shutdown is not None:
neighbor["shutdown"] = shutdown

for key in ["address_family", "shutdown"]:
ipv6_neighbors = cast(List[Dict], parcel_values.get("ipv6_neighbor", []))
if ipv6_neighbors:
for neighbor in ipv6_neighbors:
remote_as = neighbor.get("remote_as", as_variable("{{lbgp_1_remote_as}}"))
if isinstance(remote_as, Variable):
logger.info("Remote AS is not set, using device specific variable")
neighbor["remote_as"] = remote_as
if address_family := neighbor.get("address_family", []):
for family in address_family:
family["family_type"] = as_global(family["family_type"].value, FamilyTypeIpv6)
if maximum_prefixes := family.pop("maximum_prefixes", None):
family["max_prefix_config"] = MaxPrefixConfigWarningDisablePeer(
policy_type=as_global("warning-only", PolicyTypeWarningDisablePeer),
prefix_num=maximum_prefixes.get("prefix_num"),
threshold=as_global(75),
)
if neighbor.get("address") is None:
logger.info("Neighbor address is not set, using device specific variable")
neighbor["address"] = as_variable(device_specific_ipv6_neighbor_address.format(index=(i + 1)))
if if_name := neighbor.get("update_source", {}).get("if_name"):
neighbor["if_name"] = if_name
neighbor.pop("update_source")

for key in ["address_family", "shutdown", "target"]:
parcel_values.pop(key, None)

return BGPParcel(**parcel_values) # type: ignore

0 comments on commit 6c8e7b2

Please sign in to comment.