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

Commit

Permalink
Add SVI Interface model. Add unit tests and integration test for the …
Browse files Browse the repository at this point in the history
…moedl creation. Remove static UUID in tests, instead create dynamicly. Add IPv6Interface and IPv4Interface cast in normalizer. Change models to use casted Global[Interface] values. Fix Svi model
  • Loading branch information
jpkrajewski committed Mar 22, 2024
1 parent 5b0b70f commit 56a7f73
Show file tree
Hide file tree
Showing 12 changed files with 277 additions and 66 deletions.
9 changes: 4 additions & 5 deletions catalystwan/integration_tests/feature_profile/sdwan/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import unittest
from typing import cast

from catalystwan.session import create_manager_session

Expand All @@ -9,8 +8,8 @@ class TestFeatureProfileModels(unittest.TestCase):
def setUp(self) -> None:
# TODO: Add those params to PyTest
self.session = create_manager_session(
url=cast(str, os.environ.get("TEST_VMANAGE_URL", "localhost")),
port=cast(int, int(os.environ.get("TEST_VMANAGE_PORT", 443))), # type: ignore
username=cast(str, os.environ.get("TEST_VMANAGE_USERNAME", "admin")),
password=cast(str, os.environ.get("TEST_VMANAGE_PASSWORD", "admin")),
url=os.environ.get("TEST_VMANAGE_URL", "localhost"),
port=int(os.environ.get("TEST_VMANAGE_PORT", 443)),
username=os.environ.get("TEST_VMANAGE_USERNAME", "admin"),
password=os.environ.get("TEST_VMANAGE_PASSWORD", "admin"),
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
SubnetMask,
)
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.gre import BasicGre, InterfaceGreParcel
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.svi import InterfaceSviParcel
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.vpn import LanVpnParcel


Expand Down Expand Up @@ -73,6 +74,19 @@ def test_when_default_values_gre_parcel_expect_successful_post(self):
# Assert
assert parcel_id

def test_when_default_values_svi_parcel_expect_successful_post(self):
# Arrange
svi_parcel = InterfaceSviParcel(
parcel_name="TestSviParcel",
parcel_description="Test Svi Parcel",
interface_name=as_global("Vlan1"),
svi_description=as_global("Test Svi Description"),
)
# Act
parcel_id = self.api.create_parcel(self.profile_uuid, svi_parcel, self.vpn_parcel_uuid).id
# Assert
assert parcel_id

def tearDown(self) -> None:
self.api.delete_profile(self.profile_uuid)
self.session.close()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from ipaddress import IPv4Address
from ipaddress import IPv4Address, IPv4Interface
from typing import List, Literal, Optional, Union

from pydantic import AliasPath, BaseModel, ConfigDict, Field
Expand Down Expand Up @@ -35,7 +35,7 @@ class Ip(BaseModel):
extra="forbid",
populate_by_name=True,
)
address: Union[Global[str], Variable] = Field(
address: Union[Global[str], Global[IPv4Interface], Variable] = Field(
default=as_variable("{{ipv4Addr}}"), description="Assign IPv4 address"
)
default_gateway: Union[Global[IPv4Address], Variable, Default[None]] = Field(
Expand Down Expand Up @@ -88,7 +88,9 @@ class InterfaceItem(BaseModel):
validation_alias="ucseInterfaceVpn",
description="UCSE Interface VPN",
)
address: Optional[Union[Global[str], Variable]] = Field(default=None, description="Assign IPv4 address")
address: Optional[Union[Global[str], Global[IPv4Interface], Variable]] = Field(
default=None, description="Assign IPv4 address"
)


class UcseParcel(_ParcelBase):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from .lan.ethernet import InterfaceEthernetData
from .lan.gre import InterfaceGreParcel
from .lan.ipsec import InterfaceIpsecData
from .lan.svi import InterfaceSviData
from .lan.svi import InterfaceSviParcel
from .lan.vpn import LanVpnParcel

AnyTopLevelServiceParcel = Annotated[
Expand All @@ -28,7 +28,7 @@
InterfaceEthernetData,
InterfaceGreParcel,
InterfaceIpsecData,
InterfaceSviData,
InterfaceSviParcel,
],
Field(discriminator="type_"),
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright 2024 Cisco Systems, Inc. and its affiliates

from ipaddress import IPv4Address, IPv6Address, IPv6Interface
from typing import Literal, Optional, Union
from uuid import UUID

Expand Down Expand Up @@ -68,14 +69,14 @@


class Arp(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

ip_address: Union[Variable, Global[str], Default[None]]
ip_address: Union[Variable, Global[str], Global[IPv4Address], Default[None]]
mac_address: Union[Global[str], Variable]


class VrrpTrackingObject(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

tracker_id: Union[Default[None], Global[UUID]] = Field(
serialization_alias="trackerId", validation_alias="trackerId"
Expand All @@ -89,18 +90,18 @@ class VrrpTrackingObject(BaseModel):


class VrrpIPv6Address(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

ipv6_link_local: Union[Global[str], Variable] = Field(
ipv6_link_local: Union[Global[str], Global[IPv6Address], Variable] = Field(
serialization_alias="ipv6LinkLocal", validation_alias="ipv6LinkLocal"
)
prefix: Optional[Union[Global[str], Variable, Default[None]]] = None
prefix: Optional[Union[Global[str], Global[IPv6Interface], Variable, Default[None]]] = None


class StaticIPv4Address(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

ip_address: Union[Variable, Global[str], Default[None]] = Field(
ip_address: Union[Variable, Global[str], Global[IPv4Address], Default[None]] = Field(
serialization_alias="ipAddress", validation_alias="ipAddress"
)
subnet_mask: Union[Variable, Global[str], Default[None]] = Field(
Expand All @@ -109,6 +110,6 @@ class StaticIPv4Address(BaseModel):


class StaticIPv6Address(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

address: Union[Global[str], Variable]
address: Union[Global[str], Global[IPv6Interface], Variable]
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright 2024 Cisco Systems, Inc. and its affiliates

from ipaddress import IPv4Address, IPv6Address
from ipaddress import IPv4Address, IPv6Address, IPv6Interface
from typing import Literal, Optional, Union

from pydantic import AliasPath, BaseModel, ConfigDict, Field
Expand Down Expand Up @@ -97,7 +97,7 @@ class BasicGre(BaseModel):
)
description: Union[Global[str], Variable, Default[None]] = Field(default=Default[None](value=None))
address: Optional[GreAddress] = None
ipv6_address: Optional[Union[Global[str], Global[IPv6Address], Variable, Default[None]]] = Field(
ipv6_address: Optional[Union[Global[str], Global[IPv6Interface], Variable, Default[None]]] = Field(
serialization_alias="ipv6Address", validation_alias="ipv6Address", default=None
)
shutdown: Optional[Union[Global[bool], Variable, Default[bool]]] = Default[bool](value=False)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright 2024 Cisco Systems, Inc. and its affiliates

from ipaddress import IPv4Address, IPv6Interface
from typing import List, Literal, Optional, Union
from uuid import UUID

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

from catalystwan.api.configuration_groups.parcel import Default, Global, Variable, _ParcelBase
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.common import (
Expand All @@ -16,27 +17,29 @@


class VrrpIPv4SecondaryAddress(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

address: Union[Variable, Global[str]]


class VrrpIPv6SecondaryAddress(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

prefix: Union[Global[str], Variable]
prefix: Union[Global[str], Global[IPv6Interface], Variable]


class VrrpIPv4(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

group_id: Union[Variable, Global[int]] = Field(serialization_alias="groupId", validation_alias="groupId")
priority: Union[Variable, Global[int], Default[int]] = Default[int](value=100)
timer: Union[Variable, Global[int], Default[int]] = Default[int](value=1000)
track_omp: Union[Global[bool], Default[bool]] = Field(
serialization_alias="trackOmp", validation_alias="trackOmp", default=Default[bool](value=False)
)
ip_address: Union[Global[str], Variable] = Field(serialization_alias="ipAddress", validation_alias="ipAddress")
ip_address: Union[Global[str], Global[IPv4Address], Variable] = Field(
serialization_alias="ipAddress", validation_alias="ipAddress"
)
ip_address_secondary: Optional[List[VrrpIPv4SecondaryAddress]] = Field(
serialization_alias="ipAddressSecondary", validation_alias="ipAddressSecondary"
)
Expand All @@ -54,7 +57,7 @@ class VrrpIPv4(BaseModel):


class VrrpIPv6(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

group_id: Union[Variable, Global[int]] = Field(serialization_alias="groupId", validation_alias="groupId")
priority: Union[Variable, Global[int], Default[int]] = Default[int](value=100)
Expand All @@ -70,14 +73,14 @@ class VrrpIPv6(BaseModel):


class Dhcpv6Helper(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

address: Union[Global[str], Variable] = Field(serialization_alias="address", validation_alias="address")
vpn: Optional[Union[Global[int], Variable, Default[None]]] = None


class AdvancedSviAttributes(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

tcp_mss: Optional[Union[Global[int], Variable, Default[None]]] = Field(
serialization_alias="tcpMss", validation_alias="tcpMss", default=Default[None](value=None)
Expand All @@ -97,8 +100,8 @@ class AdvancedSviAttributes(BaseModel):
)


class IPv4Address(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
class IPv4AddressConfiguration(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

address: StaticIPv4Address = Field(serialization_alias="addressV4", validation_alias="addressV4")
secondary_address: Optional[List[StaticIPv4Address]] = Field(
Expand All @@ -109,10 +112,10 @@ class IPv4Address(BaseModel):
)


class IPv6Address(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
class IPv6AddressConfiguration(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

address: Union[Global[str], Variable, Default[None]] = Field(
address: Union[Global[str], Global[IPv6Interface], Variable, Default[None]] = Field(
serialization_alias="addressV6", validation_alias="addressV6"
)
secondary_address: Optional[List[StaticIPv6Address]] = Field(
Expand All @@ -124,7 +127,7 @@ class IPv6Address(BaseModel):


class AclQos(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

ipv4_acl_egress: Optional[Global[UUID]] = Field(
serialization_alias="ipv4AclEgress", validation_alias="ipv4AclEgress", default=None
Expand All @@ -140,30 +143,32 @@ class AclQos(BaseModel):
)


class InterfaceSviData(_ParcelBase):
class InterfaceSviParcel(_ParcelBase):
type_: Literal["svi"] = Field(default="svi", exclude=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

shutdown: Union[Global[bool], Variable, Default[bool]] = Default[bool](value=True)
interface_name: Optional[Union[Global[str], Variable]] = Field(
serialization_alias="interfaceName", validation_alias="interfaceName"
shutdown: Union[Global[bool], Variable, Default[bool]] = Field(
default=Default[bool](value=True), validation_alias=AliasPath("data", "shutdown")
)
interface_name: Union[Global[str], Variable] = Field(validation_alias=AliasPath("data", "interfaceName"))
svi_description: Optional[Union[Global[str], Variable, Default[None]]] = Field(
default=Default[bool](value=True), validation_alias=AliasPath("data", "description")
)
description: Optional[Union[Global[str], Variable, Default[None]]] = Default[None](value=None)
interface_mtu: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="ifMtu", validation_alias="ifMtu", default=Default[int](value=1500)
validation_alias=AliasPath("data", "ifMtu"), default=Default[int](value=1500)
)
ip_mtu: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="ipMtu", validation_alias="ipMtu", default=Default[int](value=1500)
)
ipv4: Optional[IPv4Address] = None
ipv6: Optional[IPv6Address] = None
acl_qos: Optional[AclQos] = Field(serialization_alias="aclQos", validation_alias="aclQos", default=None)
arp: Optional[List[Arp]] = None
vrrp: Optional[List[VrrpIPv4]] = None
vrrp_ipv6: Optional[List[VrrpIPv6]] = Field(
serialization_alias="vrrpIpv6", validation_alias="vrrpIpv6", default=None
)
validation_alias=AliasPath("data", "ipMtu"), default=Default[int](value=1500)
)
ipv4: Optional[IPv4AddressConfiguration] = Field(default=None, validation_alias=AliasPath("data", "ipv4"))
ipv6: Optional[IPv6AddressConfiguration] = Field(default=None, validation_alias=AliasPath("data", "ipv6"))
acl_qos: Optional[AclQos] = Field(validation_alias=AliasPath("data", "aclQos"), default=None)
arp: Optional[List[Arp]] = Field(default=None, validation_alias=AliasPath("data", "arp"))
vrrp: Optional[List[VrrpIPv4]] = Field(default=None, validation_alias=AliasPath("data", "vrrp"))
vrrp_ipv6: Optional[List[VrrpIPv6]] = Field(validation_alias=AliasPath("data", "vrrpIpv6"), default=None)
dhcp_client_v6: Optional[Union[Global[bool], Variable, Default[bool]]] = Field(
serialization_alias="dhcpClientV6", validation_alias="dhcpClientV6", default=Default[bool](value=False)
validation_alias=AliasPath("data", "dhcpClientV6"), default=Default[bool](value=False)
)
advanced: AdvancedSviAttributes = Field(
default_factory=AdvancedSviAttributes, validation_alias=AliasPath("data", "advanced")
)
advanced: AdvancedSviAttributes = AdvancedSviAttributes()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright 2024 Cisco Systems, Inc. and its affiliates

from ipaddress import IPv4Address, IPv6Address
from ipaddress import IPv4Address, IPv6Address, IPv6Interface
from typing import List, Literal, Optional, Union
from uuid import UUID

Expand Down Expand Up @@ -149,7 +149,7 @@ class IPv4Prefix(BaseModel):
class IPv6Prefix(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)

prefix: Union[Global[str], Variable]
prefix: Union[Global[str], Global[IPv6Interface], Variable]
aggregate_only: Optional[Union[Global[bool], Default[bool]]] = Field(
serialization_alias="aggregateOnly", validation_alias="aggregateOnly", default=None
)
Expand Down
Loading

0 comments on commit 56a7f73

Please sign in to comment.