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

Fix bad conditional logic that added same parcel twice #12

Merged
merged 4 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions catalystwan/endpoints/configuration_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,27 @@ class FeatureProfile(BaseModel):


class ConfigGroup(BaseModel):
model_config = ConfigDict(populate_by_name=True)
id: UUID
name: str
description: Optional[str]
solution: Solution
profiles: Optional[List[FeatureProfile]]
source: Optional[str] = None
state: Optional[str] = None
devices: List = Field(default=[])
created_by: Optional[str] = Field(alias="createdBy")
last_updated_by: Optional[str] = Field(alias="lastUpdatedBy")
created_on: Optional[datetime] = Field(alias="createdOn")
last_updated_on: Optional[datetime] = Field(alias="lastUpdatedOn")
devices: Optional[List] = Field(default=[])
created_by: Optional[str] = Field(serialization_alias="createdBy", validation_alias="createdBy")
last_updated_by: Optional[str] = Field(serialization_alias="lastUpdatedBy", validation_alias="lastUpdatedBy")
created_on: Optional[datetime] = Field(serialization_alias="createdOn", validation_alias="createdOn")
last_updated_on: Optional[datetime] = Field(serialization_alias="lastUpdatedOn", validation_alias="lastUpdatedOn")
version: int
number_of_devices: int = Field(alias="numberOfDevices")
number_of_devices_up_to_date: int = Field(alias="numberOfDevicesUpToDate")
origin: Optional[str]
number_of_devices: int = Field(serialization_alias="numberOfDevices", validation_alias="numberOfDevices")
number_of_devices_up_to_date: int = Field(
serialization_alias="numberOfDevicesUpToDate", validation_alias="numberOfDevicesUpToDate"
)
origin: Optional[str] = None
topology: Optional[str] = None
full_config_cli: bool = Field(alias="fullConfigCli")
full_config_cli: bool = Field(serialization_alias="fullConfigCli", validation_alias="fullConfigCli")


class ConfigGroupResponsePayload(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import List, Literal, Optional, Union
from uuid import UUID

from pydantic import AliasPath, BaseModel, ConfigDict, Field
from pydantic import AliasPath, BaseModel, ConfigDict, Field, IPvAnyAddress

from catalystwan.api.configuration_groups.parcel import Default, Global, Variable, _ParcelBase, as_default
from catalystwan.models.configuration.feature_profile.common import Prefix
Expand Down Expand Up @@ -124,7 +124,9 @@ class HostMapping(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)

host_name: Union[Variable, Global[str]] = Field(serialization_alias="hostName", validation_alias="hostName")
list_of_ip: Union[Variable, Global[List[str]]] = Field(serialization_alias="listOfIp", validation_alias="listOfIp")
list_of_ip: Union[Variable, Global[List[IPvAnyAddress]]] = Field(
serialization_alias="listOfIp", validation_alias="listOfIp"
)


class RoutePrefix(BaseModel):
Expand Down Expand Up @@ -428,7 +430,7 @@ class NatPortForward(BaseModel):
serialization_alias="sourceIp", validation_alias="sourceIp"
)
translated_source_ip: Union[Variable, Global[str], Global[IPv4Address]] = Field(
serialization_alias="TranslatedSourceIp", validation_alias="TranslatedSourceIp"
serialization_alias="translatedSourceIp", validation_alias="translatedSourceIp"
)
protocol: Union[Variable, Global[NATPortForwardProtocol]]

Expand All @@ -443,7 +445,7 @@ class StaticNat(BaseModel):
serialization_alias="sourceIp", validation_alias="sourceIp"
)
translated_source_ip: Union[Variable, Global[str], Global[IPv4Address]] = Field(
serialization_alias="TranslatedSourceIp", validation_alias="TranslatedSourceIp"
serialization_alias="translatedSourceIp", validation_alias="translatedSourceIp"
)
static_nat_direction: Union[Variable, Global[Direction]] = Field(
serialization_alias="staticNatDirection", validation_alias="staticNatDirection"
Expand All @@ -460,7 +462,7 @@ class StaticNatSubnet(BaseModel):
serialization_alias="sourceIpSubnet", validation_alias="sourceIpSubnet"
)
translated_source_ip_subnet: Union[Variable, Global[str]] = Field(
serialization_alias="TranslatedSourceIpSubnet", validation_alias="TranslatedSourceIpSubnet"
serialization_alias="translatedSourceIpSubnet", validation_alias="translatedSourceIpSubnet"
)
prefix_length: Union[Variable, Global[int]] = Field(
serialization_alias="prefixLength", validation_alias="prefixLength"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import logging
from copy import deepcopy
from ipaddress import IPv4Interface, IPv6Interface
from typing import Literal, Type, Union
from typing import List, Literal, Type, Union

from pydantic import BaseModel
from pydantic import BaseModel, IPvAnyAddress

from catalystwan.api.configuration_groups.parcel import as_default, as_global, as_variable
from catalystwan.api.configuration_groups.parcel import Global, as_default, as_global, as_variable
from catalystwan.models.configuration.feature_profile.common import Prefix
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.vpn import (
DHCP,
Expand Down Expand Up @@ -227,11 +227,16 @@ def configure_hostname_mapping(self, values: dict) -> None:
for entry in host:
host_mapping_item = HostMapping(
host_name=entry["hostname"],
list_of_ip=entry["ip"],
list_of_ip=self._get_list_of_ips(entry),
)
host_mapping_items.append(host_mapping_item)
values["new_host_mapping"] = host_mapping_items

def _get_list_of_ips(self, entry) -> Global[List[IPvAnyAddress]]:
# Feature Template payload has space in ip string, so we need to strip it
list_of_ips = entry.get("ip", Global[List[str]](value=[])).value
return Global[List[IPvAnyAddress]](value=[IPvAnyAddress(ip.strip()) for ip in list_of_ips])

def configure_service(self, values: dict) -> None:
if service := values.get("service", []):
service_items = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ def _resolve_and_add_parcel(self, transformed_parcel: TransformedParcel) -> None
parcel = transformed_parcel.parcel
if isinstance(parcel, LanVpnParcel):
self.builder.add_parcel_vpn(parcel) # type: ignore
if isinstance(parcel, (InterfaceEthernetParcel, InterfaceGreParcel, InterfaceIpsecParcel, InterfaceSviParcel)):
elif isinstance(
parcel, (InterfaceEthernetParcel, InterfaceGreParcel, InterfaceIpsecParcel, InterfaceSviParcel)
):
# TODO: Assiging logic
# Every Service VPN parcel can have interface childs and
# there can be multiple service VPNs in one feature profile
Expand Down