diff --git a/gso/cli/imports.py b/gso/cli/imports.py index 082519752d0f8de9b682e98c0dd2d0def7cc74c6..bb20c4f4a1fbe764ea17bec8c9a12f976ef58f5f 100644 --- a/gso/cli/imports.py +++ b/gso/cli/imports.py @@ -245,8 +245,6 @@ class NRENL3CoreServiceImportModel(BaseModel): """Base BGP Peer model.""" bfd_enabled: bool = False - bfd_interval: int | None = None - bfd_multiplier: int | None = None has_custom_policies: bool = False authentication_key: str | None multipath_enabled: bool = False @@ -257,6 +255,14 @@ class NRENL3CoreServiceImportModel(BaseModel): is_multi_hop: bool rtbh_enabled: bool # whether Remote Triggered Blackhole is enabled + class BFDSettingsModel(BaseModel): + """BFD Settings model.""" + + bfd_enabled: bool = False + bfd_interval_rx: int | None = None + bfd_interval_tx: int | None = None + bfd_multiplier: int | None = None + class ServiceBindingPort(BaseModel): """Service Binding model.""" @@ -273,6 +279,8 @@ class NRENL3CoreServiceImportModel(BaseModel): ipv6_mask: IPV6Netmask is_multi_hop: bool = True bgp_peers: list["NRENL3CoreServiceImportModel.BaseBGPPeer"] + v4_bfd_settings: "NRENL3CoreServiceImportModel.BFDSettingsModel" + v6_bfd_settings: "NRENL3CoreServiceImportModel.BFDSettingsModel" partner: str service_binding_ports: list[ServiceBindingPort] diff --git a/gso/workflows/nren_l3_core_service/create_imported_nren_l3_core_service.py b/gso/workflows/nren_l3_core_service/create_imported_nren_l3_core_service.py index 70315e0480f023c3c5f542c4654492a249144e9f..bee99798947197352291eba15acf23d4c1a02aa3 100644 --- a/gso/workflows/nren_l3_core_service/create_imported_nren_l3_core_service.py +++ b/gso/workflows/nren_l3_core_service/create_imported_nren_l3_core_service.py @@ -12,9 +12,9 @@ from pydantic import BaseModel from pydantic_forms.types import UUIDstr from gso.products import ProductName -from gso.products.product_blocks.bgp_session import BFDSettings, BGPSession, IPFamily +from gso.products.product_blocks.bgp_session import BGPSession, IPFamily, IPTypes from gso.products.product_blocks.nren_l3_core_service import NRENAccessPortInactive -from gso.products.product_blocks.service_binding_port import ServiceBindingPortInactive +from gso.products.product_blocks.service_binding_port import BFDSettings, ServiceBindingPortInactive from gso.products.product_types.edge_port import EdgePort from gso.products.product_types.nren_l3_core_service import ImportedNRENL3CoreServiceInactive, NRENL3CoreServiceType from gso.services.partners import get_partner_by_name @@ -27,13 +27,14 @@ from gso.utils.types.virtual_identifiers import VLAN_ID def initial_input_form_generator() -> FormGenerator: """Take all information passed to this workflow by the :term:`API` endpoint that was called.""" - class BFDSettings(BaseModel): + class BFDSettingsModel(BaseModel): bfd_enabled: bool = False - bfd_interval: int | None = None + bfd_interval_rx: int | None = None + bfd_interval_tx: int | None = None bfd_multiplier: int | None = None class BaseBGPPeer(BaseModel): - bfd_settings: BFDSettings + bfd_enabled: bool = False has_custom_policies: bool = False authentication_key: str | None multipath_enabled: bool = False @@ -59,6 +60,8 @@ def initial_input_form_generator() -> FormGenerator: rtbh_enabled: bool = True is_multi_hop: bool = True bgp_peers: list[BaseBGPPeer] + v4_bfd_settings: BFDSettingsModel + v6_bfd_settings: BFDSettingsModel class ImportNRENL3CoreServiceForm(FormPage): partner: str @@ -88,15 +91,22 @@ def initialize_subscription(subscription: ImportedNRENL3CoreServiceInactive, ser for service_binding_port in service_binding_ports: edge_port_subscription = EdgePort.from_subscription(service_binding_port.pop("edge_port")) bgp_peers = service_binding_port.pop("bgp_peers") - sbp_bgp_session_list = [] - for session in bgp_peers: - bfd_settings = BFDSettings.new(subscription_id=uuid4(), **session.pop("bfd_settings")) - sbp_bgp_session_list.append(BGPSession.new(subscription_id=uuid4(), bfd_settings=bfd_settings, **session)) - + sbp_bgp_session_list = [ + BGPSession.new( + subscription_id=uuid4(), + ip_type=IPTypes.IPV4 + if session["families"] in {IPFamily.V4UNICAST, IPFamily.V4MULTICAST} + else IPTypes.IPV6, + **session, + ) + for session in bgp_peers + ] service_binding_port_subscription = ServiceBindingPortInactive.new( subscription_id=uuid4(), edge_port=edge_port_subscription.edge_port, sbp_bgp_session_list=sbp_bgp_session_list, + v4_bfd_settings=BFDSettings.new(subscription_id=uuid4(), **(service_binding_port.pop("v4_bfd_settings"))), + v6_bfd_settings=BFDSettings.new(subscription_id=uuid4(), **(service_binding_port.pop("v6_bfd_settings"))), **service_binding_port, ) subscription.nren_l3_core_service.nren_ap_list.append( diff --git a/gso/workflows/nren_l3_core_service/create_nren_l3_core_service.py b/gso/workflows/nren_l3_core_service/create_nren_l3_core_service.py index 80034d05dfba4efa9e5d5c6152cd480c59a23988..16380b6c1f882518eb5c9558e47949c8f61ce80f 100644 --- a/gso/workflows/nren_l3_core_service/create_nren_l3_core_service.py +++ b/gso/workflows/nren_l3_core_service/create_nren_l3_core_service.py @@ -13,7 +13,7 @@ from orchestrator.workflows.utils import wrap_create_initial_input_form from pydantic import BaseModel, ConfigDict, Field, computed_field from pydantic_forms.validators import Divider -from gso.products.product_blocks.bgp_session import BGPSession, IPFamily +from gso.products.product_blocks.bgp_session import BGPSession, IPFamily, IPTypes from gso.products.product_blocks.nren_l3_core_service import NRENAccessPortInactive from gso.products.product_blocks.service_binding_port import BFDSettings, ServiceBindingPortInactive from gso.products.product_types.edge_port import EdgePort @@ -72,6 +72,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: class IPv4BGPPeer(BaseBGPPeer): peer_address: IPv4AddressType add_v4_multicast: bool = Field(default=False, exclude=True) + ip_type: IPTypes = IPTypes.IPV4 @computed_field # type: ignore[misc] @property @@ -81,6 +82,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: class IPv6BGPPeer(BaseBGPPeer): peer_address: IPv6AddressType add_v6_multicast: bool = Field(default=False, exclude=True) + ip_type: IPTypes = IPTypes.IPV6 @computed_field # type: ignore[misc] @property diff --git a/test/cli/test_imports.py b/test/cli/test_imports.py index ea9b13b5e5551fe263bff5a9a58ae60aad79d550..0048df8e36f2d6861e159f9b0ca3536146101434 100644 --- a/test/cli/test_imports.py +++ b/test/cli/test_imports.py @@ -313,21 +313,19 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc "ipv6_mask": faker.ipv6_netmask(), "v4_bfd_settings": { "bfd_enabled": True, - "bfd_interval": faker.pyint(), + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), "bfd_multiplier": faker.pyint(), }, "v6_bfd_settings": { "bfd_enabled": True, - "bfd_interval": faker.pyint(), + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), "bfd_multiplier": faker.pyint(), }, "bgp_peers": [ { - "bfd_settings": { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), - }, + "bfd_enabled": True, "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": False, @@ -339,11 +337,7 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc "rtbh_enabled": True, }, { - "bfd_settings": { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), - }, + "bfd_enabled": True, "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": False, @@ -368,8 +362,6 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc "bgp_peers": [ { "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": False, @@ -382,8 +374,6 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc }, { "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": False, @@ -395,6 +385,18 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc "rtbh_enabled": True, }, ], + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { + "bfd_enabled": True, + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, }, ], } @@ -721,6 +723,18 @@ def test_import_nren_l3_core_service_with_invalid_edge_port( "rtbh_enabled": True, }, ], + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { + "bfd_enabled": True, + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, }, { "edge_port": edge_port_subscription_factory(), @@ -749,6 +763,18 @@ def test_import_nren_l3_core_service_with_invalid_edge_port( "rtbh_enabled": True, }, ], + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { + "bfd_enabled": True, + "bfd_interval_rx": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, }, ] ) diff --git a/test/workflows/nren_l3_core_service/test_create_imported_nren_l3_core_service.py b/test/workflows/nren_l3_core_service/test_create_imported_nren_l3_core_service.py index 21add00b31a52894b403c2f589659522d5476e0d..f27ca3a9179c8ca40054cc43e7a85ae520c395bc 100644 --- a/test/workflows/nren_l3_core_service/test_create_imported_nren_l3_core_service.py +++ b/test/workflows/nren_l3_core_service/test_create_imported_nren_l3_core_service.py @@ -29,21 +29,19 @@ def test_create_imported_nren_l3_core_service_success( "custom_firewall_filters": faker.boolean(), "v4_bfd_settings": { "bfd_enabled": True, - "bfd_interval": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_interval_rx": faker.pyint(), "bfd_multiplier": faker.pyint(), }, "v6_bfd_settings": { "bfd_enabled": True, - "bfd_interval": faker.pyint(), + "bfd_interval_tx": faker.pyint(), + "bfd_interval_rx": faker.pyint(), "bfd_multiplier": faker.pyint(), }, "bgp_peers": [ { - "bfd_settings": { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), - }, + "bfd_enabled": faker.boolean(), "has_custom_policies": faker.boolean(), "authentication_key": faker.password(), "multipath_enabled": faker.boolean(), @@ -55,11 +53,7 @@ def test_create_imported_nren_l3_core_service_success( "rtbh_enabled": faker.boolean(), }, { - "bfd_settings": { - "bfd_enabled": faker.boolean(), - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), - }, + "bfd_enabled": faker.boolean(), "has_custom_policies": faker.boolean(), "authentication_key": faker.password(), "multipath_enabled": faker.boolean(), diff --git a/test/workflows/nren_l3_core_service/test_create_nren_l3_core_service.py b/test/workflows/nren_l3_core_service/test_create_nren_l3_core_service.py index 01d7f8f002e97ea79c6446c9a184c5ba4a874b0e..ae62f2f542debf9d544be4e5645857dd1217b4a5 100644 --- a/test/workflows/nren_l3_core_service/test_create_nren_l3_core_service.py +++ b/test/workflows/nren_l3_core_service/test_create_nren_l3_core_service.py @@ -4,7 +4,6 @@ import pytest from orchestrator.types import SubscriptionLifecycle from gso.products import ProductName -from gso.products.product_blocks.bgp_session import IPTypes from gso.products.product_types.nren_l3_core_service import NRENL3CoreService from gso.services.subscriptions import get_product_id_by_name from gso.utils.shared_enums import APType @@ -22,7 +21,6 @@ def base_bgp_peer_input(faker): "multipath_enabled": faker.boolean(), "send_default_route": faker.boolean(), "is_passive": faker.boolean(), - "ip_type": faker.random_element(elements=[IPTypes.IPV4, IPTypes.IPV6]), } return _base_bgp_peer_input diff --git a/test/workflows/nren_l3_core_service/test_modify_nren_l3_core_service.py b/test/workflows/nren_l3_core_service/test_modify_nren_l3_core_service.py index e12c4fcac35eaaf7a3dbfe6e9f89d6bd2aa2b442..32238512f55142da1e4e75962218c7434b89f3f4 100644 --- a/test/workflows/nren_l3_core_service/test_modify_nren_l3_core_service.py +++ b/test/workflows/nren_l3_core_service/test_modify_nren_l3_core_service.py @@ -267,8 +267,8 @@ def test_modify_nren_l3_core_service_modify_edge_port_success( == new_sbp_data[i]["v4_bfd_settings"]["bfd_interval_rx"] ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.v4_bfd_settings.bfd_interval_tx - == new_sbp_data[i]["v4_bfd_settings"]["bfd_interval_tx"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v4_bfd_settings.bfd_interval_tx + == new_sbp_data[i]["v4_bfd_settings"]["bfd_interval_tx"] ) assert ( subscription.nren_l3_core_service.nren_ap_list[i].sbp.v4_bfd_settings.bfd_multiplier @@ -283,8 +283,8 @@ def test_modify_nren_l3_core_service_modify_edge_port_success( == new_sbp_data[i]["v6_bfd_settings"]["bfd_interval_rx"] ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.v6_bfd_settings.bfd_interval_tx - == new_sbp_data[i]["v6_bfd_settings"]["bfd_interval_tx"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v6_bfd_settings.bfd_interval_tx + == new_sbp_data[i]["v6_bfd_settings"]["bfd_interval_tx"] ) assert ( subscription.nren_l3_core_service.nren_ap_list[i].sbp.v6_bfd_settings.bfd_multiplier