From b1edd55bfa55549a6538df6105a94ecf5c920f89 Mon Sep 17 00:00:00 2001 From: Karel van Klink <karel.vanklink@geant.org> Date: Mon, 9 Sep 2024 14:53:34 +0200 Subject: [PATCH] Add product blocks for SBP and BGP session. Small edit to edge port product model. --- gso/api/v1/network.py | 2 - gso/products/product_blocks/bgp_session.py | 71 +++++++++++++++++++ gso/products/product_blocks/edge_port.py | 47 ++---------- .../product_blocks/service_binding_port.py | 66 +++++++++++++++++ gso/services/infoblox.py | 2 +- gso/utils/helpers.py | 4 +- gso/workflows/edge_port/create_edge_port.py | 17 ++--- gso/workflows/edge_port/modify_edge_port.py | 25 +++---- .../edge_port/terminate_edge_port.py | 2 +- .../iptrunk/create_imported_iptrunk.py | 1 - gso/workflows/iptrunk/create_iptrunk.py | 3 - gso/workflows/iptrunk/migrate_iptrunk.py | 2 - .../iptrunk/modify_trunk_interface.py | 2 - gso/workflows/iptrunk/terminate_iptrunk.py | 1 - .../create_lan_switch_interconnect.py | 9 --- gso/workflows/router/create_router.py | 1 - gso/workflows/router/promote_p_to_pe.py | 1 - gso/workflows/router/terminate_router.py | 1 - gso/workflows/router/update_ibgp_mesh.py | 2 - test/cli/test_imports.py | 1 - test/fixtures.py | 1 - test/utils/test_helpers.py | 1 - test/workflows/iptrunk/test_create_iptrunk.py | 1 - .../iptrunk/test_modify_trunk_interface.py | 1 - 24 files changed, 162 insertions(+), 102 deletions(-) create mode 100644 gso/products/product_blocks/bgp_session.py create mode 100644 gso/products/product_blocks/service_binding_port.py diff --git a/gso/api/v1/network.py b/gso/api/v1/network.py index e1a15799..e4a19de9 100644 --- a/gso/api/v1/network.py +++ b/gso/api/v1/network.py @@ -10,8 +10,6 @@ from orchestrator.security import authorize from orchestrator.services.subscriptions import build_extended_domain_model from starlette import status -from gso.annotations.coordinates import LatitudeCoordinate, LongitudeCoordinate -from gso.annotations.interfaces import PhysicalPortCapacity from gso.products.product_blocks.iptrunk import IptrunkType from gso.products.product_blocks.router import RouterRole from gso.services.subscriptions import get_active_iptrunk_subscriptions diff --git a/gso/products/product_blocks/bgp_session.py b/gso/products/product_blocks/bgp_session.py new file mode 100644 index 00000000..ebf82d32 --- /dev/null +++ b/gso/products/product_blocks/bgp_session.py @@ -0,0 +1,71 @@ +""":term:`BGP` session product block.""" + +from ipaddress import IPv4Address, IPv6Address + +from orchestrator.domain.base import ProductBlockModel +from orchestrator.types import SubscriptionLifecycle +from pydantic_forms.types import strEnum + + +class IPFamily(strEnum): + """Possible :term:`IP` families of a :term:`BGP` peering.""" + + V4UNICAST = "v4unicast" + V6UNICAST = "v6unicast" + V4MULTICAST = "v4multicast" + V6MULTICAST = "v6multicast" + + +class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="BGPSession"): + """A :term:`BGP` session that is currently inactive. See :class:`BGPSession`.""" + + peer_address: IPv4Address | IPv6Address | None = None + bfd_enabled: bool | None = None + bfd_interval: int | None = None + bfd_multiplier: int | None = None + families: list[IPFamily] | None = None + has_custom_policies: bool | None = None + authentication_key: str | None = None + multipath_enabled: bool | None = None + send_default_route: bool | None = None + is_multi_hop: bool = False + + +class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): + """A :term:`BGP` session that is currently being provisioned. See :class:`BGPSession`.""" + + peer_address: IPv4Address | IPv6Address + bfd_enabled: bool + bfd_interval: int | None = None + bfd_multiplier: int | None = None + families: list[IPFamily] + has_custom_policies: bool + authentication_key: str + multipath_enabled: bool + send_default_route: bool + is_multi_hop: bool + + +class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): + """A :term:`BGP` session that is currently deployed in the network.""" + + #: The peering address of the session. + peer_address: IPv4Address | IPv6Address + #: 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 :term:`IP` families enabled for this session. + families: list[IPFamily] + #: Whether any custom policies exist for this session. + has_custom_policies: bool + #: The authentication key of the :term:`BGP` session. + authentication_key: str + #: Whether multipath is enabled. + multipath_enabled: bool + #: Whether we send a last resort route. + send_default_route: bool + #: Whether this session is multi-hop or not. Defaults to no. + is_multi_hop: bool diff --git a/gso/products/product_blocks/edge_port.py b/gso/products/product_blocks/edge_port.py index 2d72ff69..ffa5ea90 100644 --- a/gso/products/product_blocks/edge_port.py +++ b/gso/products/product_blocks/edge_port.py @@ -4,48 +4,11 @@ Edge port sets the boundary between Geant network and an external entity that co domain still managed by GEANT. In other words, an Edge port determines where the network ends. """ -from typing import Annotated - -from annotated_types import Len -from orchestrator.domain.base import ProductBlockModel, T +from orchestrator.domain.base import ProductBlockModel from orchestrator.types import SubscriptionLifecycle, strEnum -from pydantic import AfterValidator -from pydantic_forms.validators import validate_unique_list -from typing_extensions import Doc -from gso.products.product_blocks.iptrunk import PhysicalPortCapacity from gso.products.product_blocks.router import RouterBlock, RouterBlockInactive, RouterBlockProvisioning - -LAGMemberList = Annotated[ - list[T], AfterValidator(validate_unique_list), Len(min_length=0), Doc("A list of :term:`LAG` member interfaces.") -] - - -class EdgePortInterfaceBlockInactive( - ProductBlockModel, - lifecycle=[SubscriptionLifecycle.INITIAL], - product_block_name="EdgePortInterfaceBlock", -): - """An inactive edge port interface that's currently inactive.""" - - interface_name: str | None = None - interface_description: str | None = None - - -class EdgePortInterfaceBlockProvisioning( - EdgePortInterfaceBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING] -): - """An IP trunk interface that is being provisioned.""" - - interface_name: str - interface_description: str | None = None - - -class EdgePortInterfaceBlock(EdgePortInterfaceBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): - """An active edge port interface.""" - - interface_name: str - interface_description: str | None = None +from gso.utils.types.interfaces import LAGMember, LAGMemberList, PhysicalPortCapacity class EncapsulationType(strEnum): @@ -87,7 +50,7 @@ class EdgePortBlockInactive( edge_port_type: EdgePortType | None = None edge_port_ignore_if_down: bool = False edge_port_geant_ga_id: str | None = None - edge_port_ae_members: LAGMemberList[EdgePortInterfaceBlockInactive] + edge_port_ae_members: LAGMemberList[LAGMember] class EdgePortBlockProvisioning(EdgePortBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): @@ -104,7 +67,7 @@ class EdgePortBlockProvisioning(EdgePortBlockInactive, lifecycle=[SubscriptionLi edge_port_type: EdgePortType edge_port_ignore_if_down: bool = False edge_port_geant_ga_id: str | None = None - edge_port_ae_members: LAGMemberList[EdgePortInterfaceBlockProvisioning] # type: ignore[assignment] + edge_port_ae_members: LAGMemberList[LAGMember] class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): @@ -133,4 +96,4 @@ class EdgePortBlock(EdgePortBlockProvisioning, lifecycle=[SubscriptionLifecycle. #: The GEANT GA ID associated with this edge port, if any. edge_port_geant_ga_id: str | None = None #: A list of LAG members associated with this edge port. - edge_port_ae_members: LAGMemberList[EdgePortInterfaceBlock] # type: ignore[assignment] + edge_port_ae_members: LAGMemberList[LAGMember] diff --git a/gso/products/product_blocks/service_binding_port.py b/gso/products/product_blocks/service_binding_port.py new file mode 100644 index 00000000..a38a5c6e --- /dev/null +++ b/gso/products/product_blocks/service_binding_port.py @@ -0,0 +1,66 @@ +"""Service Binding Port. + +A service binding port is used to logically attach an edge port to a customer service using a :term:`VLAN`. +""" + +from ipaddress import IPv4Address, IPv6Address +from typing import Annotated + +from orchestrator.domain.base import ProductModel +from orchestrator.types import SubscriptionLifecycle +from pydantic import Field +from pydantic_forms.types import strEnum + +VLANID = Annotated[int, Field(gt=0, lt=4096)] + + +class SBPType(strEnum): + """Enumerator for the two allowed types of service binding port: layer 2 or layer 3.""" + + L2 = "l2" + L3 = "l3" + + +class ServiceBindingPortInactive( + ProductModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="ServiceBindingPort" +): + """A Service Binding Port that's currently inactive. See :class:`ServiceBindingPort`.""" + + is_tagged: bool | None = None + vlan_id: VLANID | None = None + sbp_type: SBPType | None = None + ipv4_address: IPv4Address | None = None + ipv6_address: IPv6Address | None = None + custom_firewall_filters: bool | None = None + geant_sid: str | None = None + + +class ServiceBindingPortProvisioning(ServiceBindingPortInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]): + """A Service Binding Port that's currently being provisioned. See :class:`ServiceBindingPort`.""" + + is_tagged: bool + vlan_id: VLANID | None = None + sbp_type: SBPType + ipv4_address: IPv4Address | None = None + ipv6_address: IPv6Address | None = None + custom_firewall_filters: bool + geant_sid: str + + +class ServiceBindingPort(ServiceBindingPortProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]): + """A service binding port that is actively used in the network.""" + + #: Whether this :term:`VLAN` is tagged or not. + is_tagged: bool + #: The :term:`VLAN` ID. + vlan_id: VLANID | None = None + #: Is this service binding port layer 2 or 3? + sbp_type: SBPType + #: If layer 3, IPv4 resources. + ipv4_address: IPv4Address | None = None + #: If layer 3, IPv6 resources. + ipv6_address: IPv6Address | None = None + #: Any custom firewall filters that the partner may require. + custom_firewall_filters: bool + #: The GÉANT service ID of this binding port. + geant_sid: str diff --git a/gso/services/infoblox.py b/gso/services/infoblox.py index c47da5ba..fc33f3b0 100644 --- a/gso/services/infoblox.py +++ b/gso/services/infoblox.py @@ -37,7 +37,7 @@ def _setup_connection() -> tuple[connector.Connector, IPAMParams]: return connector.Connector(options), oss -def _allocate_network( +def _allocate_network( # noqa: PLR0917 conn: connector.Connector, dns_view: str, network_view: str, diff --git a/gso/utils/helpers.py b/gso/utils/helpers.py index 00e420c0..4e4c7646 100644 --- a/gso/utils/helpers.py +++ b/gso/utils/helpers.py @@ -11,10 +11,10 @@ from gso.products.product_blocks.router import RouterRole from gso.products.product_types.router import Router from gso.services import subscriptions from gso.services.netbox_client import NetboxClient -from gso.utils.types.interfaces import PhysicalPortCapacity -from gso.utils.types.ip_address import IPv4AddressType from gso.services.partners import get_all_partners from gso.utils.shared_enums import Vendor +from gso.utils.types.interfaces import PhysicalPortCapacity +from gso.utils.types.ip_address import IPv4AddressType if TYPE_CHECKING: from gso.products.product_blocks.iptrunk import IptrunkInterfaceBlock diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py index ddca7d48..c961cd7f 100644 --- a/gso/workflows/edge_port/create_edge_port.py +++ b/gso/workflows/edge_port/create_edge_port.py @@ -1,7 +1,6 @@ """A creation workflow for adding a new edge port to the network.""" from typing import Annotated, Any, Self -from uuid import uuid4 from annotated_types import Len from orchestrator import step, workflow @@ -9,6 +8,7 @@ from orchestrator.forms import FormPage from orchestrator.forms.validators import Choice from orchestrator.targets import Target from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr +from orchestrator.utils.errors import ProcessFailureError from orchestrator.workflow import StepList, begin, done from orchestrator.workflows.steps import resync, set_status, store_process_subscription from orchestrator.workflows.utils import wrap_create_initial_input_form @@ -16,8 +16,7 @@ from pydantic import AfterValidator, ConfigDict, model_validator from pydantic_forms.validators import validate_unique_list from pynetbox.models.dcim import Interfaces -from gso.products.product_blocks.edge_port import EdgePortInterfaceBlockInactive, EdgePortType, EncapsulationType -from gso.products.product_blocks.iptrunk import PhysicalPortCapacity +from gso.products.product_blocks.edge_port import EdgePortType, EncapsulationType from gso.products.product_blocks.router import RouterRole from gso.products.product_types.edge_port import EdgePortInactive, EdgePortProvisioning from gso.products.product_types.router import Router @@ -25,13 +24,13 @@ from gso.services import lso_client, subscriptions from gso.services.lso_client import lso_interaction from gso.services.netbox_client import NetboxClient from gso.utils.helpers import ( - LAGMember, available_interfaces_choices, available_service_lags_choices, partner_choice, validate_edge_port_number_of_members_based_on_lacp, ) -from gso.utils.types import TTNumber +from gso.utils.types.interfaces import LAGMember, PhysicalPortCapacity +from gso.utils.types.tt_number import TTNumber def initial_input_form_generator(product_name: str) -> FormGenerator: @@ -134,9 +133,7 @@ def initialize_subscription( subscription.description = f"Edge Port {name} on {router.router_fqdn}, {partner}, {geant_ga_id or ""}" subscription.edge_port.edge_port_description = description for member in ae_members: - subscription.edge_port.edge_port_ae_members.append( - EdgePortInterfaceBlockInactive.new(subscription_id=uuid4(), **member), - ) + subscription.edge_port.edge_port_ae_members.append(LAGMember(**member)) subscription = EdgePortProvisioning.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) return {"subscription": subscription} @@ -181,8 +178,8 @@ def allocate_interfaces_in_netbox(subscription: EdgePortProvisioning) -> None: fqdn = subscription.edge_port.edge_port_node.router_fqdn iface_name = interface.interface_name if not fqdn or not iface_name: - msg = f"FQDN and/or interface name missing in subscription {interface.owner_subscription_id}" - raise ValueError(msg) + msg = "FQDN and/or interface name missing in subscription" + raise ProcessFailureError(msg, details=subscription.subscription_id) NetboxClient().allocate_interface(device_name=fqdn, iface_name=iface_name) diff --git a/gso/workflows/edge_port/modify_edge_port.py b/gso/workflows/edge_port/modify_edge_port.py index cb7bcc9b..7e280198 100644 --- a/gso/workflows/edge_port/modify_edge_port.py +++ b/gso/workflows/edge_port/modify_edge_port.py @@ -1,7 +1,6 @@ """Modify an existing edge port subscription.""" from typing import Annotated, Any, Self -from uuid import uuid4 from annotated_types import Len from orchestrator import workflow @@ -14,22 +13,18 @@ from pydantic import AfterValidator, ConfigDict, model_validator from pydantic_forms.types import FormGenerator, UUIDstr from pydantic_forms.validators import ReadOnlyField, validate_unique_list -from gso.products.product_blocks.edge_port import ( - EdgePortInterfaceBlock, - EncapsulationType, -) -from gso.products.product_blocks.iptrunk import PhysicalPortCapacity +from gso.products.product_blocks.edge_port import EncapsulationType from gso.products.product_types.edge_port import EdgePort from gso.services.lso_client import execute_playbook, lso_interaction from gso.services.netbox_client import NetboxClient from gso.services.partners import get_partner_by_id from gso.utils.helpers import ( - LAGMember, available_interfaces_choices, available_interfaces_choices_including_current_members, validate_edge_port_number_of_members_based_on_lacp, ) -from gso.utils.types import TTNumber +from gso.utils.types.interfaces import LAGMember, PhysicalPortCapacity +from gso.utils.types.tt_number import TTNumber def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator: @@ -151,9 +146,7 @@ def modify_edge_port_subscription( ) subscription.edge_port.edge_port_ae_members.clear() for member in ae_members: - subscription.edge_port.edge_port_ae_members.append( - EdgePortInterfaceBlock.new(subscription_id=uuid4(), **member), - ) + subscription.edge_port.edge_port_ae_members.append(LAGMember(**member)) subscription.save() return { @@ -166,19 +159,19 @@ def modify_edge_port_subscription( @step("Update interfaces in NetBox") def update_interfaces_in_netbox( subscription: EdgePort, - removed_ae_members: list[dict], - previous_ae_members: list[dict], + removed_ae_members: list[LAGMember], + previous_ae_members: list[LAGMember], ) -> dict[str, Any]: """Update the interfaces in NetBox.""" nbclient = NetboxClient() # Free removed interfaces for member in removed_ae_members: - nbclient.free_interface(subscription.edge_port.edge_port_node.router_fqdn, member["interface_name"]) + nbclient.free_interface(subscription.edge_port.edge_port_node.router_fqdn, member.interface_name) # Attach physical interfaces to :term:`LAG` # Update interface description to subscription ID # Reserve interfaces - for member in subscription.edge_port.edge_port_ae_members: # type: ignore[assignment] - if any(prev_member["interface_name"] == member.interface_name for prev_member in previous_ae_members): + for member in subscription.edge_port.edge_port_ae_members: + if any(prev_member.interface_name == member.interface_name for prev_member in previous_ae_members): continue nbclient.attach_interface_to_lag( device_name=subscription.edge_port.edge_port_node.router_fqdn, diff --git a/gso/workflows/edge_port/terminate_edge_port.py b/gso/workflows/edge_port/terminate_edge_port.py index 53569c1e..e191d330 100644 --- a/gso/workflows/edge_port/terminate_edge_port.py +++ b/gso/workflows/edge_port/terminate_edge_port.py @@ -14,7 +14,7 @@ from pydantic_forms.types import FormGenerator, UUIDstr from gso.products.product_types.edge_port import EdgePort from gso.services.lso_client import execute_playbook, lso_interaction from gso.services.netbox_client import NetboxClient -from gso.utils.types import TTNumber +from gso.utils.types.tt_number import TTNumber def initial_input_form_generator() -> FormGenerator: diff --git a/gso/workflows/iptrunk/create_imported_iptrunk.py b/gso/workflows/iptrunk/create_imported_iptrunk.py index a03ce8df..4d754375 100644 --- a/gso/workflows/iptrunk/create_imported_iptrunk.py +++ b/gso/workflows/iptrunk/create_imported_iptrunk.py @@ -13,7 +13,6 @@ from orchestrator.workflows.steps import resync, set_status, store_process_subsc from pydantic import AfterValidator, ConfigDict from pydantic_forms.validators import validate_unique_list -from gso.annotations.interfaces import LAGMember, LAGMemberList, PhysicalPortCapacity from gso.products import ProductName from gso.products.product_blocks.iptrunk import IptrunkInterfaceBlockInactive, IptrunkType from gso.products.product_types.iptrunk import ImportedIptrunkInactive diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index 8dda8479..e1040118 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -20,9 +20,6 @@ from pydantic import ConfigDict from pydantic_forms.validators import ReadOnlyField from pynetbox.models.dcim import Interfaces -from gso.annotations.interfaces import JuniperLAGMember, LAGMember, LAGMemberList, PhysicalPortCapacity -from gso.annotations.netbox_router import NetboxEnabledRouter -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.iptrunk import ( IptrunkInterfaceBlockInactive, IptrunkSideBlockInactive, diff --git a/gso/workflows/iptrunk/migrate_iptrunk.py b/gso/workflows/iptrunk/migrate_iptrunk.py index 5afc1e43..5a7cafb0 100644 --- a/gso/workflows/iptrunk/migrate_iptrunk.py +++ b/gso/workflows/iptrunk/migrate_iptrunk.py @@ -24,8 +24,6 @@ from pydantic import ConfigDict from pydantic_forms.validators import ReadOnlyField from pynetbox.models.dcim import Interfaces -from gso.annotations.interfaces import JuniperAEInterface, JuniperLAGMember, LAGMember, LAGMemberList -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.iptrunk import IptrunkInterfaceBlock, IptrunkType from gso.products.product_types.iptrunk import Iptrunk from gso.products.product_types.router import Router diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py index a43e3634..16de2462 100644 --- a/gso/workflows/iptrunk/modify_trunk_interface.py +++ b/gso/workflows/iptrunk/modify_trunk_interface.py @@ -15,8 +15,6 @@ from orchestrator.workflows.utils import wrap_modify_initial_input_form from pydantic import ConfigDict from pydantic_forms.validators import Label, ReadOnlyField -from gso.annotations.interfaces import JuniperLAGMember, LAGMember, LAGMemberList, PhysicalPortCapacity -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.iptrunk import ( IptrunkInterfaceBlock, IptrunkSideBlock, diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py index e86a61eb..9b5cf71a 100644 --- a/gso/workflows/iptrunk/terminate_iptrunk.py +++ b/gso/workflows/iptrunk/terminate_iptrunk.py @@ -17,7 +17,6 @@ from orchestrator.workflows.steps import ( ) from orchestrator.workflows.utils import wrap_modify_initial_input_form -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.iptrunk import IptrunkSideBlock from gso.products.product_types.iptrunk import Iptrunk from gso.services import infoblox diff --git a/gso/workflows/lan_switch_interconnect/create_lan_switch_interconnect.py b/gso/workflows/lan_switch_interconnect/create_lan_switch_interconnect.py index de28e1ce..973cf1d8 100644 --- a/gso/workflows/lan_switch_interconnect/create_lan_switch_interconnect.py +++ b/gso/workflows/lan_switch_interconnect/create_lan_switch_interconnect.py @@ -13,15 +13,6 @@ from orchestrator.workflows.utils import wrap_create_initial_input_form from pydantic import AfterValidator, ConfigDict from pydantic_forms.validators import Divider, ReadOnlyField -from gso.annotations.interfaces import ( - JuniperAEInterface, - JuniperLAGMember, - JuniperPhyInterface, - LAGMember, - PhysicalPortCapacity, - validate_interface_names_are_unique, -) -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.lan_switch_interconnect import ( LanSwitchInterconnectAddressSpace, LanSwitchInterconnectInterfaceBlockInactive, diff --git a/gso/workflows/router/create_router.py b/gso/workflows/router/create_router.py index 8a0fc9b7..04d38b75 100644 --- a/gso/workflows/router/create_router.py +++ b/gso/workflows/router/create_router.py @@ -14,7 +14,6 @@ from orchestrator.workflows.utils import wrap_create_initial_input_form from pydantic import ConfigDict, model_validator from pydantic_forms.validators import ReadOnlyField -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.router import RouterRole from gso.products.product_types.router import RouterInactive, RouterProvisioning from gso.products.product_types.site import Site diff --git a/gso/workflows/router/promote_p_to_pe.py b/gso/workflows/router/promote_p_to_pe.py index 0b7ddf3b..a82b4823 100644 --- a/gso/workflows/router/promote_p_to_pe.py +++ b/gso/workflows/router/promote_p_to_pe.py @@ -15,7 +15,6 @@ from orchestrator.workflows.steps import resync, store_process_subscription, uns from orchestrator.workflows.utils import wrap_modify_initial_input_form from pydantic import ConfigDict, model_validator -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.router import RouterRole from gso.products.product_types.router import Router from gso.services.kentik_client import KentikClient, NewKentikDevice diff --git a/gso/workflows/router/terminate_router.py b/gso/workflows/router/terminate_router.py index dfe846ab..9bc48f8c 100644 --- a/gso/workflows/router/terminate_router.py +++ b/gso/workflows/router/terminate_router.py @@ -20,7 +20,6 @@ from orchestrator.workflows.steps import ( from orchestrator.workflows.utils import wrap_modify_initial_input_form from requests import HTTPError -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.router import RouterRole from gso.products.product_types.router import Router from gso.services import infoblox diff --git a/gso/workflows/router/update_ibgp_mesh.py b/gso/workflows/router/update_ibgp_mesh.py index 72a1b593..298c0878 100644 --- a/gso/workflows/router/update_ibgp_mesh.py +++ b/gso/workflows/router/update_ibgp_mesh.py @@ -12,8 +12,6 @@ from orchestrator.workflows.steps import resync, store_process_subscription, uns from orchestrator.workflows.utils import wrap_modify_initial_input_form from pydantic import ConfigDict, model_validator -from gso.annotations.snmp import SNMPVersion -from gso.annotations.tt_number import TTNumber from gso.products.product_blocks.router import RouterRole from gso.products.product_types.router import Router from gso.services import librenms_client diff --git a/test/cli/test_imports.py b/test/cli/test_imports.py index ac3aa664..98332386 100644 --- a/test/cli/test_imports.py +++ b/test/cli/test_imports.py @@ -4,7 +4,6 @@ from unittest.mock import patch import pytest -from gso.annotations.interfaces import PhysicalPortCapacity from gso.cli.imports import ( import_iptrunks, import_office_routers, diff --git a/test/fixtures.py b/test/fixtures.py index 29d5614f..6c392855 100644 --- a/test/fixtures.py +++ b/test/fixtures.py @@ -21,7 +21,6 @@ from pydantic_forms.core import FormPage from pydantic_forms.types import FormGenerator, SubscriptionMapping from pydantic_forms.validators import Choice -from gso.annotations.interfaces import PhysicalPortCapacity from gso.products import ProductName from gso.products.product_blocks.iptrunk import ( IptrunkInterfaceBlock, diff --git a/test/utils/test_helpers.py b/test/utils/test_helpers.py index a39ab9fb..0df4ced9 100644 --- a/test/utils/test_helpers.py +++ b/test/utils/test_helpers.py @@ -3,7 +3,6 @@ from unittest.mock import patch import pytest from orchestrator.types import SubscriptionLifecycle -from gso.annotations.tt_number import validate_tt_number from gso.products import Router from gso.products.product_blocks.iptrunk import IptrunkInterfaceBlock from gso.products.product_blocks.router import RouterRole diff --git a/test/workflows/iptrunk/test_create_iptrunk.py b/test/workflows/iptrunk/test_create_iptrunk.py index b8a90ba9..6be42fae 100644 --- a/test/workflows/iptrunk/test_create_iptrunk.py +++ b/test/workflows/iptrunk/test_create_iptrunk.py @@ -4,7 +4,6 @@ from unittest.mock import patch import pytest from infoblox_client.objects import HostRecord -from gso.annotations.interfaces import PhysicalPortCapacity from gso.products import Iptrunk, ProductName from gso.products.product_blocks.iptrunk import IptrunkType from gso.services.subscriptions import get_product_id_by_name diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index 7c0d2235..359308cd 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -2,7 +2,6 @@ from unittest.mock import patch import pytest -from gso.annotations.interfaces import LAGMemberList, PhysicalPortCapacity from gso.products import Iptrunk from gso.products.product_blocks.iptrunk import IptrunkType from gso.utils.shared_enums import Vendor -- GitLab