From 54a33604369a61d68fca2c1d8d6d6c8c61a63e4c Mon Sep 17 00:00:00 2001 From: Karel van Klink <karel.vanklink@geant.org> Date: Wed, 6 Nov 2024 17:56:33 +0100 Subject: [PATCH] Split BFD settings off into separate product block and allow for both v4 and v6 settings in a service binding port --- .../2024-10-30_c6b82e23297c_add_bfd_to_sbp.py | 50 ----------- ...9_split_bfd_settings_off_into_separate_.py | 83 +++++++++++++++++++ gso/products/product_blocks/bgp_session.py | 45 +++++++--- .../product_blocks/service_binding_port.py | 29 ++++--- .../create_imported_nren_l3_core_service.py | 12 ++- .../create_nren_l3_core_service.py | 28 +++++-- .../modify_nren_l3_core_service.py | 54 ++++++++---- test/cli/test_imports.py | 26 ++++-- test/conftest.py | 18 +--- test/fixtures/__init__.py | 2 + test/fixtures/iptrunk_fixtures.py | 41 +++++---- .../fixtures/nren_l3_core_service_fixtures.py | 45 ++++++---- ...st_create_imported_nren_l3_core_service.py | 29 +++++-- .../test_create_nren_l3_core_service.py | 21 +++-- .../test_modify_nren_l3_core_service.py | 80 +++++++++++++----- 15 files changed, 364 insertions(+), 199 deletions(-) delete mode 100644 gso/migrations/versions/2024-10-30_c6b82e23297c_add_bfd_to_sbp.py create mode 100644 gso/migrations/versions/2024-11-06_d16b635106c9_split_bfd_settings_off_into_separate_.py diff --git a/gso/migrations/versions/2024-10-30_c6b82e23297c_add_bfd_to_sbp.py b/gso/migrations/versions/2024-10-30_c6b82e23297c_add_bfd_to_sbp.py deleted file mode 100644 index d8fc7e61..00000000 --- a/gso/migrations/versions/2024-10-30_c6b82e23297c_add_bfd_to_sbp.py +++ /dev/null @@ -1,50 +0,0 @@ -"""Add BFD to SBP. - -Revision ID: c6b82e23297c -Revises: 7412c5b7ebe4 -Create Date: 2024-10-30 14:39:30.047934 - -""" -import sqlalchemy as sa -from alembic import op - -# revision identifiers, used by Alembic. -revision = 'c6b82e23297c' -down_revision = '7412c5b7ebe4' -branch_labels = None -depends_on = None - - -def upgrade() -> None: - conn = op.get_bind() - conn.execute(sa.text(""" -INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled'))) - """)) - conn.execute(sa.text(""" -INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval'))) - """)) - conn.execute(sa.text(""" -INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier'))) - """)) - - -def downgrade() -> None: - conn = op.get_bind() - conn.execute(sa.text(""" -DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) - """)) - conn.execute(sa.text(""" -DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) - """)) - conn.execute(sa.text(""" -DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) - """)) - conn.execute(sa.text(""" -DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) - """)) - conn.execute(sa.text(""" -DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) - """)) - conn.execute(sa.text(""" -DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) - """)) diff --git a/gso/migrations/versions/2024-11-06_d16b635106c9_split_bfd_settings_off_into_separate_.py b/gso/migrations/versions/2024-11-06_d16b635106c9_split_bfd_settings_off_into_separate_.py new file mode 100644 index 00000000..b6168a1d --- /dev/null +++ b/gso/migrations/versions/2024-11-06_d16b635106c9_split_bfd_settings_off_into_separate_.py @@ -0,0 +1,83 @@ +"""Split BFD settings off into separate product block. + +Revision ID: d16b635106c9 +Revises: 0e7e7d749617 +Create Date: 2024-11-06 16:53:48.831945 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'd16b635106c9' +down_revision = '0e7e7d749617' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) + """)) + conn.execute(sa.text(""" +INSERT INTO product_blocks (name, description, tag, status) VALUES ('BFDSettings', 'Settings related to BFD', 'BFD', 'active') RETURNING product_blocks.product_block_id + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_relations (in_use_by_id, depends_on_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings'))), ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('ServiceBindingPort')), (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled'))) + """)) + conn.execute(sa.text(""" +INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval'))) + """)) + + +def downgrade() -> None: + conn = op.get_bind() + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_multiplier')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_enabled')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('bfd_interval')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_block_relations WHERE product_block_relations.in_use_by_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession', 'ServiceBindingPort')) AND product_block_relations.depends_on_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')) + """)) + conn.execute(sa.text(""" +DELETE FROM subscription_instances WHERE subscription_instances.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BFDSettings')) + """)) + conn.execute(sa.text(""" +DELETE FROM product_blocks WHERE product_blocks.name IN ('BFDSettings') + """)) diff --git a/gso/products/product_blocks/bgp_session.py b/gso/products/product_blocks/bgp_session.py index c4088462..d6ef9a33 100644 --- a/gso/products/product_blocks/bgp_session.py +++ b/gso/products/product_blocks/bgp_session.py @@ -19,13 +19,39 @@ class IPFamily(strEnum): V6MULTICAST = "v6multicast" +class BFDSettingsInactive( + ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="BFDSettings" +): + """Settings for :term:`BFD`, see :class:`BFDSettings`.""" + + bfd_enabled: bool = False + bfd_interval: int | None = None + bfd_multiplier: int | None = None + + +class BFDSettingsProvisioning(BFDSettingsInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): + """Settings for :term:`BFD`, see :class:`BFDSettings`.""" + + bfd_enabled: bool + bfd_interval: int | None + bfd_multiplier: int | None + + +class BFDSettings(BFDSettingsProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): + """A set of settings for :term:`BFD`.""" + + #: Whether :term:`BFD` is enabled. + bfd_enabled: bool + #: The :term:`BFD` interval, if enabled. + bfd_interval: int | None + #: The :term:`BFD` multiplier, if enabled. + bfd_multiplier: int | None + + class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="BGPSession"): """A :term:`BGP` session that is currently inactive. See :class:`BGPSession`.""" peer_address: IPAddress | None = None - bfd_enabled: bool | None = None - bfd_interval: int | None = None - bfd_multiplier: int | None = None families: list[IPFamily] = Field(default_factory=list) has_custom_policies: bool | None = None authentication_key: str | None = None @@ -34,15 +60,13 @@ class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INI is_multi_hop: bool = False is_passive: bool = False rtbh_enabled: bool = False + bfd_settings: BFDSettingsInactive class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): """A :term:`BGP` session that is currently being provisioned. See :class:`BGPSession`.""" peer_address: IPAddress - bfd_enabled: bool - bfd_interval: int | None = None - bfd_multiplier: int | None = None families: list[IPFamily] has_custom_policies: bool authentication_key: str | None @@ -51,6 +75,7 @@ class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycl is_multi_hop: bool is_passive: bool rtbh_enabled: bool + bfd_settings: BFDSettingsProvisioning class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): @@ -58,12 +83,6 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE #: The peering address of the session. peer_address: IPAddress - #: Whether :term:`BFD` is enabled. - bfd_enabled: bool - #: The :term:`BFD` interval, if enabled. - bfd_interval: int | None = None - #: The :term:`BFD` multiplier, if enabled. - bfd_multiplier: int | None = None #: The list of IP families enabled for this session. families: list[IPFamily] #: Whether any custom policies exist for this session. @@ -80,3 +99,5 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE is_passive: bool #: Whether Remote Triggered Blackhole is enabled rtbh_enabled: bool + #: Settings for :term:`BFD`. + bfd_settings: BFDSettings diff --git a/gso/products/product_blocks/service_binding_port.py b/gso/products/product_blocks/service_binding_port.py index 19452b2e..92fb14e2 100644 --- a/gso/products/product_blocks/service_binding_port.py +++ b/gso/products/product_blocks/service_binding_port.py @@ -7,7 +7,14 @@ from orchestrator.domain.base import ProductBlockModel from orchestrator.types import SubscriptionLifecycle from pydantic import Field -from gso.products.product_blocks.bgp_session import BGPSession, BGPSessionInactive, BGPSessionProvisioning +from gso.products.product_blocks.bgp_session import ( + BFDSettings, + BFDSettingsInactive, + BFDSettingsProvisioning, + BGPSession, + BGPSessionInactive, + BGPSessionProvisioning, +) from gso.products.product_blocks.edge_port import EdgePortBlock, EdgePortBlockInactive, EdgePortBlockProvisioning from gso.utils.shared_enums import SBPType from gso.utils.types.ip_address import IPv4AddressType, IPV4Netmask, IPv6AddressType, IPV6Netmask @@ -30,9 +37,8 @@ class ServiceBindingPortInactive( geant_sid: str | None = None bgp_session_list: list[BGPSessionInactive] = Field(default_factory=list) edge_port: EdgePortBlockInactive | None = None - bfd_enabled: bool = False - bfd_interval: int | None = None - bfd_multiplier: int | None = None + v4_bfd_settings: BFDSettingsInactive + v6_bfd_settings: BFDSettingsInactive class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): @@ -49,9 +55,8 @@ class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[Subs geant_sid: str bgp_session_list: list[BGPSessionProvisioning] # type: ignore[assignment] edge_port: EdgePortBlockProvisioning - bfd_enabled: bool - bfd_interval: int | None - bfd_multiplier: int | None + v4_bfd_settings: BFDSettingsProvisioning + v6_bfd_settings: BFDSettingsProvisioning class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): @@ -79,9 +84,7 @@ class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[Subscription bgp_session_list: list[BGPSession] # type: ignore[assignment] #: The Edge Port on which this :term:`SBP` resides. edge_port: EdgePortBlock - #: Whether :term:`BFD` is enabled. - bfd_enabled: bool - #: The :term:`BFD` interval, if enabled. - bfd_interval: int | None - #: The :term:`BFD` multiplier, if enabled. - bfd_multiplier: int | None + #: :term:`BFD` settings for IPv4 + v4_bfd_settings: BFDSettings + #: :term:`BFD` settings for IPv6 + v6_bfd_settings: BFDSettings 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 ae32599f..70315e04 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,7 +12,7 @@ from pydantic import BaseModel from pydantic_forms.types import UUIDstr from gso.products import ProductName -from gso.products.product_blocks.bgp_session import BGPSession, IPFamily +from gso.products.product_blocks.bgp_session import BFDSettings, BGPSession, IPFamily 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_types.edge_port import EdgePort @@ -27,10 +27,13 @@ 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 BaseBGPPeer(BaseModel): + class BFDSettings(BaseModel): bfd_enabled: bool = False bfd_interval: int | None = None bfd_multiplier: int | None = None + + class BaseBGPPeer(BaseModel): + bfd_settings: BFDSettings has_custom_policies: bool = False authentication_key: str | None multipath_enabled: bool = False @@ -85,7 +88,10 @@ 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 = [BGPSession.new(subscription_id=uuid4(), **session) for session in 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)) service_binding_port_subscription = ServiceBindingPortInactive.new( subscription_id=uuid4(), 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 2b9ade91..72a63eb5 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 AfterValidator, 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 BFDSettings, BGPSession, IPFamily 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_types.edge_port import EdgePort @@ -63,10 +63,13 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: selected_edge_ports = yield EdgePortSelectionForm ep_list = selected_edge_ports.edge_ports - class BaseBGPPeer(BaseModel): + class BFDSettingsForm(BaseModel): bfd_enabled: bool = False bfd_interval: int | None = None bfd_multiplier: int | None = None + + class BaseBGPPeer(BaseModel): + bfd_settings: BFDSettingsForm has_custom_policies: bool = False authentication_key: str | None multipath_enabled: bool = False @@ -105,9 +108,8 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: geant_sid: str is_tagged: bool = False - bfd_enabled: bool = False - bfd_interval: int | None = None - bfd_multiplier: int | None = None + v4_bfd_settings: BFDSettingsForm + v6_bfd_settings: BFDSettingsForm vlan_id: VLAN_ID ipv4_address: IPv4AddressType ipv4_mask: IPV4Netmask @@ -152,13 +154,21 @@ def initialize_subscription( edge_port_fqdn_list = [] for edge_port_input, sbp_input in zip(edge_ports, binding_port_inputs, strict=False): edge_port_subscription = EdgePort.from_subscription(edge_port_input["edge_port"]) - sbp_bgp_session_list = [ - BGPSession.new(subscription_id=uuid4(), **session, rtbh_enabled=True, is_multi_hop=True) - for session in sbp_input["bgp_peers"] - ] + sbp_bgp_session_list = [] + for session in sbp_input["bgp_peers"]: + bfd_settings = BFDSettings.new(subscription_id=uuid4(), **session.pop("bfd_settings")) + sbp_bgp_session_list.append( + BGPSession.new( + subscription_id=uuid4(), **session, bfd_settings=bfd_settings, rtbh_enabled=True, is_multi_hop=True + ) + ) + v4_bfd_settings = BFDSettings.new(subscription_id=uuid4(), **sbp_input.pop("v4_bfd_settings")) + v6_bfd_settings = BFDSettings.new(subscription_id=uuid4(), **sbp_input.pop("v6_bfd_settings")) service_binding_port = ServiceBindingPortInactive.new( subscription_id=uuid4(), **sbp_input, + v4_bfd_settings=v4_bfd_settings, + v6_bfd_settings=v6_bfd_settings, bgp_session_list=sbp_bgp_session_list, sbp_type=SBPType.L3, edge_port=edge_port_subscription.edge_port, diff --git a/gso/workflows/nren_l3_core_service/modify_nren_l3_core_service.py b/gso/workflows/nren_l3_core_service/modify_nren_l3_core_service.py index 0b275587..ea09fbb7 100644 --- a/gso/workflows/nren_l3_core_service/modify_nren_l3_core_service.py +++ b/gso/workflows/nren_l3_core_service/modify_nren_l3_core_service.py @@ -14,7 +14,7 @@ from pydantic import AfterValidator, BaseModel, ConfigDict, Field, computed_fiel from pydantic_forms.types import State from pydantic_forms.validators import Divider, Label -from gso.products.product_blocks.bgp_session import BGPSession, IPFamily +from gso.products.product_blocks.bgp_session import BFDSettings, BGPSession, IPFamily from gso.products.product_blocks.nren_l3_core_service import NRENAccessPort from gso.products.product_blocks.service_binding_port import ServiceBindingPort from gso.products.product_types.edge_port import EdgePort @@ -59,10 +59,13 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: str(ap.sbp.edge_port.owner_subscription_id) for ap in subscription.nren_l3_core_service.nren_ap_list ] - class BaseBGPPeer(BaseModel): + class BFDInputModel(BaseModel): bfd_enabled: bool = False bfd_interval: int | None = None bfd_multiplier: int | None = None + + class BaseBGPPeer(BaseModel): + bfd_settings: BFDInputModel has_custom_policies: bool = False authentication_key: str | None multipath_enabled: bool = False @@ -144,9 +147,16 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: ipv6_address: IPv6AddressType = current_sbp.ipv6_address # type: ignore[assignment] ipv6_mask: IPV6Netmask = current_sbp.ipv6_mask # type: ignore[assignment] custom_firewall_filters: bool = current_sbp.custom_firewall_filters - bfd_enabled: bool = current_sbp.bfd_enabled - bfd_interval: int | None = current_sbp.bfd_interval - bfd_multiplier: int | None = current_sbp.bfd_multiplier + v4_bfd_settings: BFDInputModel = BFDInputModel( + bfd_enabled=current_sbp.v4_bfd_settings.bfd_enabled, + bfd_multiplier=current_sbp.v4_bfd_settings.bfd_multiplier, + bfd_interval=current_sbp.v4_bfd_settings.bfd_interval, + ) + v6_bfd_settings: BFDInputModel = BFDInputModel( + bfd_enabled=current_sbp.v6_bfd_settings.bfd_enabled, + bfd_multiplier=current_sbp.v6_bfd_settings.bfd_multiplier, + bfd_interval=current_sbp.v6_bfd_settings.bfd_interval, + ) divider: Divider = Field(None, exclude=True) v4_bgp_peer: IPv4BGPPeer = IPv4BGPPeer( **v4_peer.model_dump(exclude=set("families")), @@ -191,9 +201,8 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: ipv4_address: IPv4AddressType ipv6_address: IPv6AddressType custom_firewall_filters: bool = False - bfd_enabled: bool = False - bfd_interval: int | None = None - bfd_multiplier: int | None = None + v4_bfd_settings: BFDInputModel + v6_bfd_settings: BFDInputModel divider: Divider = Field(None, exclude=True) v4_bgp_peer: IPv4BGPPeer v6_bgp_peer: IPv6BGPPeer @@ -240,12 +249,22 @@ def modify_existing_sbp_blocks(subscription: NRENL3CoreService, modified_sbp_lis ) v4_peer = next(peer for peer in current_sbp.bgp_session_list if IPFamily.V4UNICAST in peer.families) + v4_peer_bfd_settings = modified_sbp_data["v4_bgp_peer"].pop("bfd_settings") + for attribute in v4_peer_bfd_settings: + setattr(v4_peer.bfd_settings, attribute, v4_peer_bfd_settings[attribute]) for attribute in modified_sbp_data["v4_bgp_peer"]: setattr(v4_peer, attribute, modified_sbp_data["v4_bgp_peer"][attribute]) + for attribute in modified_sbp_data["v4_bfd_settings"]: + setattr(current_sbp.v4_bfd_settings, attribute, modified_sbp_data["v4_bfd_settings"][attribute]) v6_peer = next(peer for peer in current_sbp.bgp_session_list if IPFamily.V6UNICAST in peer.families) + v6_peer_bfd_settings = modified_sbp_data["v6_bgp_peer"].pop("bfd_settings") + for attribute in v6_peer_bfd_settings: + setattr(v6_peer.bfd_settings, attribute, v6_peer_bfd_settings[attribute]) for attribute in modified_sbp_data["v6_bgp_peer"]: setattr(v6_peer, attribute, modified_sbp_data["v6_bgp_peer"][attribute]) + for attribute in modified_sbp_data["v6_bfd_settings"]: + setattr(current_sbp.v6_bfd_settings, attribute, modified_sbp_data["v6_bfd_settings"][attribute]) current_sbp.bgp_session_list = [v4_peer, v6_peer] current_sbp.vlan_id = modified_sbp_data["vlan_id"] @@ -254,9 +273,6 @@ def modify_existing_sbp_blocks(subscription: NRENL3CoreService, modified_sbp_lis current_sbp.ipv4_address = modified_sbp_data["ipv4_address"] current_sbp.ipv6_address = modified_sbp_data["ipv6_address"] current_sbp.custom_firewall_filters = modified_sbp_data["custom_firewall_filters"] - current_sbp.bfd_enabled = modified_sbp_data["bfd_enabled"] - current_sbp.bfd_interval = modified_sbp_data["bfd_interval"] - current_sbp.bfd_multiplier = modified_sbp_data["bfd_multiplier"] access_port.ap_type = modified_sbp_data["new_ap_type"] return {"subscription": subscription} @@ -267,13 +283,21 @@ def create_new_sbp_blocks(subscription: NRENL3CoreService, added_service_binding """Add new two :term:`SBP` to the :term:`NREN` L3 Core Service subscription.""" for sbp_input in added_service_binding_ports: edge_port = EdgePort.from_subscription(sbp_input["edge_port_id"]) - bgp_session_list = [ - BGPSession.new(subscription_id=uuid4(), **session, rtbh_enabled=True, is_multi_hop=True) - for session in sbp_input["bgp_peers"] - ] + bgp_session_list = [] + for session in sbp_input["bgp_peers"]: + bfd_settings = BFDSettings.new(subscription_id=uuid4(), **session.pop("bfd_settings")) + bgp_session_list.append( + BGPSession.new( + subscription_id=uuid4(), **session, bfd_settings=bfd_settings, rtbh_enabled=True, is_multi_hop=True + ) + ) + v4_bfd_settings = BFDSettings.new(subscription_id=uuid4(), **sbp_input.pop("v4_bfd_settings")) + v6_bfd_settings = BFDSettings.new(subscription_id=uuid4(), **sbp_input.pop("v6_bfd_settings")) service_binding_port = ServiceBindingPort.new( subscription_id=uuid4(), **sbp_input, + v4_bfd_settings=v4_bfd_settings, + v6_bfd_settings=v6_bfd_settings, bgp_session_list=bgp_session_list, sbp_type=SBPType.L3, edge_port=edge_port.edge_port, diff --git a/test/cli/test_imports.py b/test/cli/test_imports.py index bc4325dc..ea9b13b5 100644 --- a/test/cli/test_imports.py +++ b/test/cli/test_imports.py @@ -311,11 +311,23 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc "ipv4_mask": faker.ipv4_netmask(), "ipv6_address": faker.ipv6(), "ipv6_mask": faker.ipv6_netmask(), + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "bgp_peers": [ { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": False, @@ -327,9 +339,11 @@ def nren_l3_core_service_data(temp_file, faker, partner_factory, edge_port_subsc "rtbh_enabled": True, }, { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": False, diff --git a/test/conftest.py b/test/conftest.py index 888926fc..ce44b074 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -35,23 +35,7 @@ from urllib3_mock import Responses from gso.main import init_gso_app from gso.services.partners import PartnerSchema, create_partner from gso.utils.types.interfaces import LAGMember, LAGMemberList -from test.fixtures import ( # noqa: F401 - bgp_session_subscription_factory, - edge_port_subscription_factory, - iptrunk_side_subscription_factory, - iptrunk_subscription_factory, - lan_switch_interconnect_subscription_factory, - layer_2_circuit_subscription_factory, - nren_access_port_factory, - nren_l3_core_service_subscription_factory, - office_router_subscription_factory, - opengear_subscription_factory, - router_subscription_factory, - service_binding_port_factory, - site_subscription_factory, - super_pop_switch_subscription_factory, - switch_subscription_factory, -) +from test.fixtures import * # noqa: F403 logging.getLogger("faker.factory").setLevel(logging.WARNING) diff --git a/test/fixtures/__init__.py b/test/fixtures/__init__.py index d2582b5b..71535c89 100644 --- a/test/fixtures/__init__.py +++ b/test/fixtures/__init__.py @@ -3,6 +3,7 @@ from test.fixtures.iptrunk_fixtures import iptrunk_side_subscription_factory, ip from test.fixtures.lan_switch_interconnect_fixtures import lan_switch_interconnect_subscription_factory from test.fixtures.layer_2_circuit_fixtures import layer_2_circuit_subscription_factory from test.fixtures.nren_l3_core_service_fixtures import ( + bfd_settings_factory, bgp_session_subscription_factory, nren_access_port_factory, nren_l3_core_service_subscription_factory, @@ -16,6 +17,7 @@ from test.fixtures.super_pop_switch_fixtures import super_pop_switch_subscriptio from test.fixtures.switch_fixtures import switch_subscription_factory __all__ = [ + "bfd_settings_factory", "bgp_session_subscription_factory", "edge_port_subscription_factory", "iptrunk_side_subscription_factory", diff --git a/test/fixtures/iptrunk_fixtures.py b/test/fixtures/iptrunk_fixtures.py index 70ccdeb5..5044a2e5 100644 --- a/test/fixtures/iptrunk_fixtures.py +++ b/test/fixtures/iptrunk_fixtures.py @@ -25,30 +25,27 @@ def iptrunk_side_subscription_factory(router_subscription_factory, faker): iptrunk_side_ae_members=None, iptrunk_side_ae_members_description=None, ) -> IptrunkSideBlock: - iptrunk_side_node_id = iptrunk_side_node or router_subscription_factory(vendor=Vendor.NOKIA) - iptrunk_side_node = Router.from_subscription(iptrunk_side_node_id).router - iptrunk_side_ae_iface = iptrunk_side_ae_iface or faker.pystr() - iptrunk_side_ae_geant_a_sid = iptrunk_side_ae_geant_a_sid or faker.geant_sid() - iptrunk_side_ae_members = iptrunk_side_ae_members or [ - IptrunkInterfaceBlock.new( - faker.uuid4(), - interface_name=faker.network_interface(), - interface_description=faker.sentence(), - ), - IptrunkInterfaceBlock.new( - faker.uuid4(), - interface_name=faker.network_interface(), - interface_description=faker.sentence(), - ), - ] - return IptrunkSideBlock.new( faker.uuid4(), - iptrunk_side_node=iptrunk_side_node, - iptrunk_side_ae_iface=iptrunk_side_ae_iface, - iptrunk_side_ae_geant_a_sid=iptrunk_side_ae_geant_a_sid, - iptrunk_side_ae_members=iptrunk_side_ae_members, - iptrunk_side_ae_members_description=iptrunk_side_ae_members_description, + iptrunk_side_node=Router.from_subscription( + iptrunk_side_node or router_subscription_factory(vendor=Vendor.NOKIA) + ).router, + iptrunk_side_ae_iface=iptrunk_side_ae_iface or faker.pystr(), + iptrunk_side_ae_geant_a_sid=iptrunk_side_ae_geant_a_sid or faker.geant_sid(), + iptrunk_side_ae_members=iptrunk_side_ae_members + or [ + IptrunkInterfaceBlock.new( + faker.uuid4(), + interface_name=faker.network_interface(), + interface_description=faker.sentence(), + ), + IptrunkInterfaceBlock.new( + faker.uuid4(), + interface_name=faker.network_interface(), + interface_description=faker.sentence(), + ), + ], + iptrunk_side_ae_members_description=iptrunk_side_ae_members_description or faker.sentence(), ) return subscription_create diff --git a/test/fixtures/nren_l3_core_service_fixtures.py b/test/fixtures/nren_l3_core_service_fixtures.py index b3622cfd..58754e59 100644 --- a/test/fixtures/nren_l3_core_service_fixtures.py +++ b/test/fixtures/nren_l3_core_service_fixtures.py @@ -7,7 +7,7 @@ from orchestrator.domain import SubscriptionModel from orchestrator.types import SubscriptionLifecycle, UUIDstr from gso.products import ProductName -from gso.products.product_blocks.bgp_session import BGPSession, IPFamily +from gso.products.product_blocks.bgp_session import BFDSettings, BGPSession, IPFamily from gso.products.product_blocks.nren_l3_core_service import NRENAccessPort from gso.products.product_blocks.service_binding_port import ServiceBindingPort from gso.products.product_types.edge_port import EdgePort @@ -22,17 +22,34 @@ from gso.utils.types.ip_address import IPAddress @pytest.fixture() -def bgp_session_subscription_factory(faker): +def bfd_settings_factory(faker): + def create_bfd_settings( + bfd_multiplier: int | None = None, + bfd_interval: int | None = None, + *, + bfd_enabled: bool | None = None, + ): + bfd_enabled = bfd_enabled or faker.boolean() + return BFDSettings.new( + subscription_id=uuid4(), + bfd_enabled=bfd_enabled, + bfd_multiplier=bfd_multiplier or (faker.pyint() if bfd_enabled else None), + bfd_interval=bfd_interval or (faker.pyint() if bfd_enabled else None), + ) + + return create_bfd_settings + + +@pytest.fixture() +def bgp_session_subscription_factory(faker, bfd_settings_factory): def create_bgp_session( peer_address: IPAddress | None = None, - bfd_interval: int = 2, - bfd_multiplier: int = 2, families: list[IPFamily] | None = None, authentication_key: str | None = None, + bfd_settings: BFDSettings | None = None, *, is_multi_hop: bool = False, has_custom_policies: bool = False, - bfd_enabled: bool = True, multipath_enabled: bool | None = True, send_default_route: bool | None = True, is_passive: bool | None = False, @@ -41,15 +58,13 @@ def bgp_session_subscription_factory(faker): return BGPSession.new( subscription_id=uuid4(), peer_address=peer_address or faker.ipv4(), - bfd_enabled=bfd_enabled, + bfd_settings=bfd_settings or bfd_settings_factory(), families=families or [IPFamily.V4UNICAST], has_custom_policies=has_custom_policies, authentication_key=authentication_key or faker.password(), multipath_enabled=multipath_enabled, send_default_route=send_default_route, is_multi_hop=is_multi_hop, - bfd_interval=bfd_interval, - bfd_multiplier=bfd_multiplier, rtbh_enabled=rtbh_enabled, is_passive=is_passive, ) @@ -58,7 +73,9 @@ def bgp_session_subscription_factory(faker): @pytest.fixture() -def service_binding_port_factory(faker, bgp_session_subscription_factory, edge_port_subscription_factory): +def service_binding_port_factory( + faker, bgp_session_subscription_factory, edge_port_subscription_factory, bfd_settings_factory +): def create_service_binding_port( bgp_session_list: list[BGPSession] | None = None, geant_sid: str | None = None, @@ -69,10 +86,9 @@ def service_binding_port_factory(faker, bgp_session_subscription_factory, edge_p ipv6_mask: int | None = None, vlan_id: int | None = None, edge_port: EdgePort | None = None, - bfd_interval: int = 2, - bfd_multiplier: int = 2, + v4_bfd_settings: BFDSettings | None = None, + v6_bfd_settings: BFDSettings | None = None, *, - bfd_enabled: bool = False, custom_firewall_filters: bool = False, is_tagged: bool = False, ): @@ -93,9 +109,8 @@ def service_binding_port_factory(faker, bgp_session_subscription_factory, edge_p bgp_session_subscription_factory(families=[IPFamily.V6UNICAST], peer_address=faker.ipv6()), ], edge_port=edge_port or EdgePort.from_subscription(edge_port_subscription_factory()).edge_port, - bfd_enabled=bfd_enabled, - bfd_interval=bfd_interval, - bfd_multiplier=bfd_multiplier, + v4_bfd_settings=v4_bfd_settings or bfd_settings_factory(), + v6_bfd_settings=v6_bfd_settings or bfd_settings_factory(), ) return create_service_binding_port 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 bcc0c068..21add00b 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 @@ -27,14 +27,23 @@ def test_create_imported_nren_l3_core_service_success( "ipv6_address": faker.ipv6(), "ipv6_mask": faker.ipv6_netmask(), "custom_firewall_filters": faker.boolean(), - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "bgp_peers": [ { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "has_custom_policies": faker.boolean(), "authentication_key": faker.password(), "multipath_enabled": faker.boolean(), @@ -46,9 +55,11 @@ def test_create_imported_nren_l3_core_service_success( "rtbh_enabled": faker.boolean(), }, { - "bfd_enabled": faker.boolean(), - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "bfd_settings": { + "bfd_enabled": faker.boolean(), + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "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 cd8d123a..b1797f83 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 @@ -15,9 +15,11 @@ def base_bgp_peer_input(faker): def _base_bgp_peer_input(): bfd_enabled = faker.boolean() return { - "bfd_enabled": bfd_enabled, - "bfd_interval": faker.pyint() if bfd_enabled else None, - "bfd_multiplier": faker.pyint() if bfd_enabled else None, + "bfd_settings": { + "bfd_enabled": bfd_enabled, + "bfd_interval": faker.pyint() if bfd_enabled else None, + "bfd_multiplier": faker.pyint() if bfd_enabled else None, + }, "has_custom_policies": faker.boolean(), "authentication_key": faker.password(), "multipath_enabled": faker.boolean(), @@ -57,9 +59,16 @@ def test_create_nren_l3_core_service_success( "ipv6_address": faker.ipv6(), "ipv6_mask": faker.ipv6_netmask(), "custom_firewall_filters": faker.boolean(), - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "v4_bgp_peer": base_bgp_peer_input() | {"add_v4_multicast": faker.boolean(), "peer_address": faker.ipv4()}, "v6_bgp_peer": base_bgp_peer_input() | {"add_v6_multicast": faker.boolean(), "peer_address": faker.ipv6()}, }, 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 d2976494..be5caf91 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 @@ -77,11 +77,15 @@ def test_modify_nren_l3_core_service_add_new_edge_port_success( "v4_bgp_peer": { "authentication_key": faker.password(), "peer_address": faker.ipv4(), + "bfd_settings": {"bfd_enabled": False}, }, "v6_bgp_peer": { "authentication_key": faker.password(), "peer_address": faker.ipv6(), + "bfd_settings": {"bfd_enabled": False}, }, + "v4_bfd_settings": {"bfd_enabled": False}, + "v6_bfd_settings": {"bfd_enabled": False}, }, ] @@ -102,13 +106,22 @@ def sbp_input_form_data(faker): "ipv4_address": faker.ipv4(), "ipv6_address": faker.ipv6(), "custom_firewall_filters": True, - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), - "v4_bgp_peer": { + "v4_bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, + "v6_bfd_settings": { "bfd_enabled": True, "bfd_interval": faker.pyint(), "bfd_multiplier": faker.pyint(), + }, + "v4_bgp_peer": { + "bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": True, @@ -118,9 +131,11 @@ def sbp_input_form_data(faker): "add_v4_multicast": True, }, "v6_bgp_peer": { - "bfd_enabled": True, - "bfd_interval": faker.pyint(), - "bfd_multiplier": faker.pyint(), + "bfd_settings": { + "bfd_enabled": True, + "bfd_interval": faker.pyint(), + "bfd_multiplier": faker.pyint(), + }, "has_custom_policies": True, "authentication_key": faker.password(), "multipath_enabled": True, @@ -179,16 +194,16 @@ def test_modify_nren_l3_core_service_modify_edge_port_success( ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].bfd_enabled - == new_sbp_data[i]["v4_bgp_peer"]["bfd_enabled"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].bfd_settings.bfd_enabled + == new_sbp_data[i]["v4_bgp_peer"]["bfd_settings"]["bfd_enabled"] ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].bfd_interval - == new_sbp_data[i]["v4_bgp_peer"]["bfd_interval"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].bfd_settings.bfd_interval + == new_sbp_data[i]["v4_bgp_peer"]["bfd_settings"]["bfd_interval"] ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].bfd_multiplier - == new_sbp_data[i]["v4_bgp_peer"]["bfd_multiplier"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].bfd_settings.bfd_multiplier + == new_sbp_data[i]["v4_bgp_peer"]["bfd_settings"]["bfd_multiplier"] ) assert ( subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[0].has_custom_policies @@ -223,16 +238,16 @@ def test_modify_nren_l3_core_service_modify_edge_port_success( ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].bfd_enabled - == new_sbp_data[i]["v6_bgp_peer"]["bfd_enabled"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].bfd_settings.bfd_enabled + == new_sbp_data[i]["v6_bgp_peer"]["bfd_settings"]["bfd_enabled"] ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].bfd_interval - == new_sbp_data[i]["v6_bgp_peer"]["bfd_interval"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].bfd_settings.bfd_interval + == new_sbp_data[i]["v6_bgp_peer"]["bfd_settings"]["bfd_interval"] ) assert ( - subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].bfd_multiplier - == new_sbp_data[i]["v6_bgp_peer"]["bfd_multiplier"] + subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].bfd_settings.bfd_multiplier + == new_sbp_data[i]["v6_bgp_peer"]["bfd_settings"]["bfd_multiplier"] ) assert ( subscription.nren_l3_core_service.nren_ap_list[i].sbp.bgp_session_list[1].has_custom_policies @@ -265,6 +280,27 @@ def test_modify_nren_l3_core_service_modify_edge_port_success( ) == new_sbp_data[i]["v6_bgp_peer"]["add_v6_multicast"] ) - assert subscription.nren_l3_core_service.nren_ap_list[i].sbp.bfd_enabled == new_sbp_data[i]["bfd_enabled"] - assert subscription.nren_l3_core_service.nren_ap_list[i].sbp.bfd_interval == new_sbp_data[i]["bfd_interval"] - assert subscription.nren_l3_core_service.nren_ap_list[i].sbp.bfd_multiplier == new_sbp_data[i]["bfd_multiplier"] + assert ( + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v4_bfd_settings.bfd_enabled + == new_sbp_data[i]["v4_bfd_settings"]["bfd_enabled"] + ) + assert ( + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v4_bfd_settings.bfd_interval + == new_sbp_data[i]["v4_bfd_settings"]["bfd_interval"] + ) + assert ( + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v4_bfd_settings.bfd_multiplier + == new_sbp_data[i]["v4_bfd_settings"]["bfd_multiplier"] + ) + assert ( + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v6_bfd_settings.bfd_enabled + == new_sbp_data[i]["v6_bfd_settings"]["bfd_enabled"] + ) + assert ( + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v6_bfd_settings.bfd_interval + == new_sbp_data[i]["v6_bfd_settings"]["bfd_interval"] + ) + assert ( + subscription.nren_l3_core_service.nren_ap_list[i].sbp.v6_bfd_settings.bfd_multiplier + == new_sbp_data[i]["v6_bfd_settings"]["bfd_multiplier"] + ) -- GitLab