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

Commit

Permalink
Fix integration test for 20.13. Add delete_parcel for service api.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpkrajewski committed Apr 23, 2024
1 parent 39b6331 commit 3155a5e
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 54 deletions.
6 changes: 6 additions & 0 deletions catalystwan/api/feature_profile_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ def create_parcel(
)
return self.endpoint.create_service_parcel(profile_uuid, payload._get_parcel_type(), payload)

def delete_parcel(self, profile_uuid: UUID, parcel_type: Type[AnyServiceParcel], parcel_uuid: UUID) -> None:
"""
Delete Service Parcel for selected profile_uuid based on payload type
"""
return self.endpoint.delete_service_parcel(profile_uuid, parcel_type._get_parcel_type(), parcel_uuid)


class SystemFeatureProfileAPI:
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ def create_service_parcel(
) -> ParcelCreationResponse:
...

@versions(supported_versions=(">=20.9"), raises=False)
@delete("/v1/feature-profile/sdwan/service/{profile_uuid}/{parcel_type}/{parcel_uuid}")
def delete_service_parcel(self, profile_uuid: UUID, parcel_type: str, parcel_uuid: UUID) -> None:
...

@versions(supported_versions=(">=20.9"), raises=False)
@post("/v1/feature-profile/sdwan/service/{profile_uuid}/lan/vpn/{vpn_uuid}/{parcel_type}")
def create_lan_vpn_sub_parcel(
Expand Down
69 changes: 40 additions & 29 deletions catalystwan/integration_tests/feature_profile/sdwan/test_service.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from ipaddress import IPv4Address
from secrets import token_hex
from uuid import UUID

from catalystwan.api.configuration_groups.parcel import Global, as_global, as_variable
Expand All @@ -17,12 +16,12 @@
SummaryAddress,
)
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.ethernet import InterfaceEthernetParcel
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.gre import BasicGre, InterfaceGreParcel
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.ipsec import (
InterfaceIpsecParcel,
IpsecAddress,
IpsecTunnelMode,
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.gre import (
BasicGre,
GreAddress,
InterfaceGreParcel,
)
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.ipsec import InterfaceIpsecParcel, IpsecAddress
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.svi import InterfaceSviParcel
from catalystwan.models.configuration.feature_profile.sdwan.service.lan.vpn import LanVpnParcel
from catalystwan.models.configuration.feature_profile.sdwan.service.multicast import (
Expand Down Expand Up @@ -212,21 +211,14 @@ def test_when_default_values_acl_ipv4_expect_successful_post(self):
# Assert
assert parcel_id

def test_when_default_values_switchport_expect_successful_post(self):
def test_when_correct_values_switchport_parcel_expect_successful_post(self):
# Arrange
switchport_parcel = SwitchportParcel(
parcel_name="TestSwitchportParcel",
switchport_default_values_parcel = SwitchportParcel(
parcel_name="TestSwitchportParcelDefaultValues",
parcel_description="Test Switchport Parcel",
)
# Act
parcel_id = self.api.create_parcel(self.profile_uuid, switchport_parcel).id
# Assert
assert parcel_id

def test_when_fully_specified_values_switchport_expect_successful_post(self):
# Arrange
switchport_parcel = SwitchportParcel(
parcel_name="TestSwitchportParcel",
switchport_fully_specified_parcel = SwitchportParcel(
parcel_name="TestSwitchportParcelFullySpecified",
parcel_description="Test Switchport Parcel",
age_time=Global[int](value=100),
static_mac_address=[
Expand Down Expand Up @@ -257,10 +249,15 @@ def test_when_fully_specified_values_switchport_expect_successful_post(self):
)
],
)
switchport_parcels = [switchport_default_values_parcel, switchport_fully_specified_parcel]
# Act
parcel_id = self.api.create_parcel(self.profile_uuid, switchport_parcel).id
# Assert
assert parcel_id
for switchport_parcel in switchport_parcels:
with self.subTest(switchport_parcel=switchport_parcel.parcel_name):
parcel_id = self.api.create_parcel(self.profile_uuid, switchport_parcel).id
# Assert
assert parcel_id
# Cleanup
self.api.delete_parcel(self.profile_uuid, SwitchportParcel, parcel_id)

def test_when_default_values_multicast_expect_successful_post(self):
# Arrange
Expand Down Expand Up @@ -376,7 +373,7 @@ def test_when_fully_specified_values_wireless_lan_expect_successful_post(self):
enable_5G=as_global(True),
country=as_global("US", CountryCode),
username=as_global("admin"),
password=as_global(token_hex(16) + "TEST!@#"),
password=as_variable("{{wireless_lan_password}}"),
ssid=[
SSID(
name=as_global("TestSSID"),
Expand Down Expand Up @@ -413,7 +410,7 @@ def tearDownClass(cls) -> None:
super().tearDownClass()


class TestServiceFeatureProfileVPNInterfaceModels(TestFeatureProfileModels):
class TestServiceFeatureProfileVPNSubparcelModels(TestFeatureProfileModels):
vpn_parcel_uuid: UUID

@classmethod
Expand All @@ -433,7 +430,14 @@ def test_when_default_values_gre_parcel_expect_successful_post(self):
gre_parcel = InterfaceGreParcel(
parcel_name="TestGreParcel",
parcel_description="Test Gre Parcel",
basic=BasicGre(if_name=as_global("gre1"), tunnel_destination=as_global(IPv4Address("4.4.4.4"))),
basic=BasicGre(
if_name=as_global("gre1"),
address=GreAddress(
address=as_global("1.1.1.1"),
mask=as_global("255.255.255.0"),
),
tunnel_destination=as_global(IPv4Address("4.4.4.4")),
),
)
# Act
parcel_id = self.api.create_parcel(self.profile_uuid, gre_parcel, self.vpn_parcel_uuid).id
Expand Down Expand Up @@ -477,20 +481,27 @@ def test_when_default_values_ipsec_parcel_expect_successful_post(self):
ike_local_id=as_global("123"),
ike_remote_id=as_global("123"),
application=as_variable("{{ipsec_application}}"),
tunnel_mode=Global[IpsecTunnelMode](value="ipv6"),
tunnel_destination_v6=as_variable("{{ipsec_tunnelDestinationV6}}"),
tunnel_source_v6=Global[str](value="::"),
tunnel_source_interface=as_variable("{{ipsec_ipsecSourceInterface}}"),
ipv6_address=as_variable("{{test}}"),
address=IpsecAddress(address=as_global("10.0.0.1"), mask=as_global("255.255.255.0")),
tunnel_destination=IpsecAddress(address=as_global("10.0.0.5"), mask=as_global("255.255.255.0")),
mtu_v6=as_variable("{{test}}"),
)
# Act
parcel_id = self.api.create_parcel(self.profile_uuid, ipsec_parcel, self.vpn_parcel_uuid).id
# Assert
assert parcel_id

def test_when_routing_parcel_and_vpn_uuid_present_expect_create_then_assign_to_vpn(self):
# Arrange
multicast_parcel = MulticastParcel(
parcel_name="TestMulticastParcel",
parcel_description="Test Multicast Parcel",
basic=MulticastBasicAttributes(),
)
# Act
parcel_id = self.api.create_parcel(self.profile_uuid, multicast_parcel, self.vpn_parcel_uuid).id
# Assert
assert parcel_id

@classmethod
def tearDownClass(cls) -> None:
cls.api.delete_profile(cls.profile_uuid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ class BasicGre(BaseModel):
)
shutdown: Optional[Union[Global[bool], Variable, Default[bool]]] = Default[bool](value=False)
tunnel_protection: Optional[Union[Global[bool], Variable, Default[bool]]] = Field(
serialization_alias="tunnelProtection", validation_alias="tunnelProtection", default=Default[bool](value=False)
serialization_alias="tunnelProtection", validation_alias="tunnelProtection", default=None
)
tunnel_mode: Union[Global[GreTunnelMode], Default[GreTunnelMode]] = Field(
default=Default[GreTunnelMode](value="ipv4"),
tunnel_mode: Optional[Union[Global[GreTunnelMode], Default[GreTunnelMode]]] = Field(
default=None,
serialization_alias="tunnelMode",
validation_alias="tunnelMode",
)
Expand All @@ -131,30 +131,30 @@ class BasicGre(BaseModel):
clear_dont_fragment: Optional[Union[Global[bool], Variable, Default[bool]]] = Field(
serialization_alias="clearDontFragment",
validation_alias="clearDontFragment",
default=Default[bool](value=False),
default=None,
)
dpd_interval: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="dpdInterval", validation_alias="dpdInterval", default=Default[int](value=10)
serialization_alias="dpdInterval", validation_alias="dpdInterval", default=None
)
dpd_retries: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="dpdRetries", validation_alias="dpdRetries", default=Default[int](value=3)
serialization_alias="dpdRetries", validation_alias="dpdRetries", default=None
)
ike_version: Optional[Union[Global[int], Default[int]]] = Field(
serialization_alias="ikeVersion", validation_alias="ikeVersion", default=Default[int](value=1)
serialization_alias="ikeVersion", validation_alias="ikeVersion", default=None
)
ike_mode: Optional[Union[Global[IkeMode], Variable, Default[IkeMode]]] = Field(
serialization_alias="ikeMode", validation_alias="ikeMode", default=Default[IkeMode](value="main")
serialization_alias="ikeMode", validation_alias="ikeMode", default=None
)
ike_rekey_interval: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="ikeRekeyInterval", validation_alias="ikeRekeyInterval", default=Default[int](value=14400)
serialization_alias="ikeRekeyInterval", validation_alias="ikeRekeyInterval", default=None
)
ike_ciphersuite: Optional[Union[Global[IkeCiphersuite], Variable, Default[IkeCiphersuite]]] = Field(
serialization_alias="ikeCiphersuite",
validation_alias="ikeCiphersuite",
default=Default[IkeCiphersuite](value="aes256-cbc-sha1"),
default=None,
)
ike_group: Optional[Union[Global[IkeGroup], Variable, Default[IkeGroup]]] = Field(
serialization_alias="ikeGroup", validation_alias="ikeGroup", default=Default[IkeGroup](value="16")
serialization_alias="ikeGroup", validation_alias="ikeGroup", default=None
)
pre_shared_secret: Optional[Union[Global[str], Variable, Default[None]]] = Field(
serialization_alias="preSharedSecret", validation_alias="preSharedSecret", default=None
Expand All @@ -168,20 +168,20 @@ class BasicGre(BaseModel):
ipsec_rekey_interval: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="ipsecRekeyInterval",
validation_alias="ipsecRekeyInterval",
default=Default[int](value=3600),
default=None,
)
ipsec_replay_window: Optional[Union[Global[int], Variable, Default[int]]] = Field(
serialization_alias="ipsecReplayWindow", validation_alias="ipsecReplayWindow", default=Default[int](value=512)
serialization_alias="ipsecReplayWindow", validation_alias="ipsecReplayWindow", default=None
)
ipsec_ciphersuite: Optional[Union[Global[IpsecCiphersuite], Variable, Default[IpsecCiphersuite]]] = Field(
serialization_alias="ipsecCiphersuite",
validation_alias="ipsecCiphersuite",
default=Default[IpsecCiphersuite](value="aes256-gcm"),
default=None,
)
perfect_forward_secrecy: Optional[Union[Global[PfsGroup], Variable, Default[PfsGroup]]] = Field(
serialization_alias="perfectForwardSecrecy",
validation_alias="perfectForwardSecrecy",
default=Default[PfsGroup](value="group-16"),
default=None,
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,16 @@ class OspfParcel(_ParcelBase):
type_: Literal["routing/ospf"] = Field(default="routing/ospf", exclude=True)
model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True, extra="forbid")

router_id: Optional[Union[Global[str], Global[IPv4Address], Variable, Default[None]]] = Field(
router_id: Union[Global[str], Global[IPv4Address], Variable, Default[None]] = Field(
validation_alias=AliasPath("data", "routerId"), default=Default[None](value=None)
)
reference_bandwidth: Optional[Union[Global[int], Variable, Default[int]]] = Field(
reference_bandwidth: Union[Global[int], Variable, Default[int]] = Field(
validation_alias=AliasPath("data", "referenceBandwidth"), default=as_default(100)
)
rfc1583: Optional[Union[Global[bool], Variable, Default[bool]]] = Field(
validation_alias=AliasPath("data", "rfc1583"), default=as_default(False)
rfc1583: Union[Global[bool], Variable, Default[bool]] = Field(
validation_alias=AliasPath("data", "rfc1583"), default=as_default(True)
)
originate: Optional[Union[Global[bool], Default[bool]]] = Field(
originate: Union[Global[bool], Default[bool]] = Field(
validation_alias=AliasPath("data", "originate"), default=as_default(False)
)
always: Optional[Union[Global[bool], Variable, Default[bool]]] = Field(
Expand Down
35 changes: 30 additions & 5 deletions catalystwan/tests/test_feature_profile_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from catalystwan.api.feature_profile_api import ServiceFeatureProfileAPI, SystemFeatureProfileAPI
from catalystwan.endpoints.configuration.feature_profile.sdwan.service import ServiceFeatureProfile
from catalystwan.endpoints.configuration.feature_profile.sdwan.system import SystemFeatureProfile
from catalystwan.models.configuration.feature_profile.common import ParcelAssociationPayload, ParcelCreationResponse
from catalystwan.models.configuration.feature_profile.sdwan.service import (
AppqoeParcel,
InterfaceEthernetParcel,
Expand Down Expand Up @@ -125,15 +126,15 @@ def test_update_method_with_valid_arguments(self, parcel, expected_path):

service_interface_parcels = [
(
"gre",
"interface/gre",
InterfaceGreParcel(
parcel_name="TestGreParcel",
parcel_description="Test Gre Parcel",
basic=BasicGre(if_name=as_global("gre1"), tunnel_destination=as_global(IPv4Address("4.4.4.4"))),
),
),
(
"svi",
"interface/svi",
InterfaceSviParcel(
parcel_name="TestSviParcel",
parcel_description="Test Svi Parcel",
Expand All @@ -142,7 +143,7 @@ def test_update_method_with_valid_arguments(self, parcel, expected_path):
),
),
(
"ethernet",
"interface/ethernet",
InterfaceEthernetParcel(
parcel_name="TestEthernetParcel",
parcel_description="Test Ethernet Parcel",
Expand All @@ -151,7 +152,7 @@ def test_update_method_with_valid_arguments(self, parcel, expected_path):
),
),
(
"ipsec",
"interface/ipsec",
InterfaceIpsecParcel(
parcel_name="TestIpsecParcel",
parcel_description="Test Ipsec Parcel",
Expand All @@ -173,6 +174,16 @@ def test_update_method_with_valid_arguments(self, parcel, expected_path):
),
]

service_vpn_sub_parcels = [
(
"routing/multicast",
MulticastParcel(
parcel_name="TestMulticastParcel",
parcel_description="Test Multicast Parcel",
),
)
]


class TestServiceFeatureProfileAPI(unittest.TestCase):
def setUp(self):
Expand All @@ -198,6 +209,20 @@ def test_post_method_interface_parcel(self, parcel_type, parcel):
self.api.create_parcel(self.profile_uuid, parcel, self.vpn_uuid)

# Assert
self.mock_endpoint.create_lan_vpn_interface_parcel.assert_called_once_with(
self.mock_endpoint.create_lan_vpn_sub_parcel.assert_called_once_with(
self.profile_uuid, self.vpn_uuid, parcel_type, parcel
)

@parameterized.expand(service_vpn_sub_parcels)
def test_post_method_create_then_assigin_subparcel(self, parcel_type, parcel):
# Arrange
self.mock_endpoint.create_service_parcel.return_value = ParcelCreationResponse(id=self.parcel_uuid)

# Act
self.api.create_parcel(self.profile_uuid, parcel, self.vpn_uuid)

# Assert
self.mock_endpoint.create_service_parcel.assert_called_once_with(self.profile_uuid, parcel_type, parcel)
self.mock_endpoint.associate_parcel_with_vpn.assert_called_once_with(
self.profile_uuid, self.vpn_uuid, parcel_type, ParcelAssociationPayload(parcel_id=self.parcel_uuid)
)

0 comments on commit 3155a5e

Please sign in to comment.