diff --git a/gso/products/product_blocks/lan_switch_interconnect.py b/gso/products/product_blocks/lan_switch_interconnect.py
index 08693fef09ff372623ddcdb36cd5759c4e1e088e..55a7b97a3ca788dbe3e61f5ddd9c8a5344e5976f 100644
--- a/gso/products/product_blocks/lan_switch_interconnect.py
+++ b/gso/products/product_blocks/lan_switch_interconnect.py
@@ -117,7 +117,7 @@ class LanSwitchInterconnectBlockInactive(
lan_switch_interconnect_description: str | None = None
address_space: LanSwitchInterconnectAddressSpace | None = None
- number_of_members: int | None = None
+ minimum_links: int | None = None
router_side: LanSwitchInterconnectRouterSideBlockInactive
switch_side: LanSwitchInterconnectSwitchSideBlockInactive
@@ -129,7 +129,7 @@ class LanSwitchInterconnectBlockProvisioning(
lan_switch_interconnect_description: str | None = None
address_space: LanSwitchInterconnectAddressSpace | None = None
- number_of_members: int | None = None
+ minimum_links: int | None = None
router_side: LanSwitchInterconnectRouterSideBlockProvisioning
switch_side: LanSwitchInterconnectSwitchSideBlockProvisioning
@@ -142,7 +142,7 @@ class LanSwitchInterconnectBlock(LanSwitchInterconnectBlockProvisioning, lifecyc
#: The address space of the VLAN Switch Interconnect. It can be private or public.
address_space: LanSwitchInterconnectAddressSpace
#: The minimum amount of links the LAN Switch Interconnect should consist of.
- number_of_members: int
+ minimum_links: int
#: The router side of the LAN Switch Interconnect.
router_side: LanSwitchInterconnectRouterSideBlock
#: The switch side of the LAN Switch Interconnect.
diff --git a/gso/products/product_blocks/pop_vlan.py b/gso/products/product_blocks/pop_vlan.py
index 9840299c80c8dffa9cb270d0f381f7ed47e42ea8..1407a06c99c9cff2560ec2cb96f1491efc935ce9 100644
--- a/gso/products/product_blocks/pop_vlan.py
+++ b/gso/products/product_blocks/pop_vlan.py
@@ -1,18 +1,28 @@
"""Pop VLAN product block that has all parameters of a subscription throughout its lifecycle."""
-
+from ipaddress import IPv4Network, IPv6Network
from typing import TypeVar
from orchestrator.domain.base import ProductBlockModel
from orchestrator.forms.validators import UniqueConstrainedList
from orchestrator.types import SubscriptionLifecycle
+from pydantic_forms.types import strEnum
-from gso.products.product_blocks.iptrunk import LAGMemberList
-from gso.products.product_blocks.router import RouterBlock, RouterBlockInactive, RouterBlockProvisioning
-from gso.products.product_blocks.switch import SwitchBlock, SwitchBlockInactive, SwitchBlockProvisioning
+from gso.products.product_blocks.lan_switch_interconnect import LanSwitchInterconnectBlock
+from gso.products.product_types.lan_switch_interconnect import (
+ LanSwitchInterconnectInactive,
+ LanSwitchInterconnectProvisioning,
+)
T_co = TypeVar("T_co", covariant=True)
+class LayerPreference(strEnum):
+ """Enumerator for the different types of layer preferences."""
+
+ L2 = "L2"
+ L3 = "L3"
+
+
class PortList(UniqueConstrainedList[T_co]): # type: ignore[type-var]
"""A list of ports."""
@@ -22,7 +32,7 @@ class PopVlanPortBlockInactive(
):
"""An inactive Pop VLAN port."""
- port: str | None = None
+ port_name: str | None = None
port_description: str | None = None
tagged: bool | None = None
@@ -30,7 +40,7 @@ class PopVlanPortBlockInactive(
class PopVlanPortBlockProvisioning(PopVlanPortBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A Pop VLAN port that is being provisioned."""
- port: str | None = None
+ port_name: str | None = None
port_description: str | None = None
tagged: bool | None = None
@@ -38,96 +48,11 @@ class PopVlanPortBlockProvisioning(PopVlanPortBlockInactive, lifecycle=[Subscrip
class PopVlanPortBlock(PopVlanPortBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""An active Pop VLAN port."""
- port: str
+ port_name: str
port_description: str
tagged: bool
-class PopVlanInterfaceBlockInactive(
- ProductBlockModel,
- lifecycle=[SubscriptionLifecycle.INITIAL],
- product_block_name="PopVlanInterfaceBlock",
-):
- """An inactive Pop VLAN interface."""
-
- interface_name: str | None = None
- interface_description: str | None = None
-
-
-class PopVlanInterfaceBlockProvisioning(PopVlanInterfaceBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
- """A Pop VLAN interface that is being provisioned."""
-
- interface_name: str
- interface_description: str
-
-
-class PopVlanInterfaceBlock(PopVlanInterfaceBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
- """An active Pop VLAN interface."""
-
- interface_name: str
- interface_description: str
-
-
-class PopVlanRouterSideBlockInactive(
- ProductBlockModel,
- lifecycle=[SubscriptionLifecycle.INITIAL],
- product_block_name="PopVlanRouterSideBlock",
-):
- """An inactive Pop VLAN router side."""
-
- node: RouterBlockInactive
- ae_iface: str | None = None
- ae_members: LAGMemberList[PopVlanInterfaceBlockInactive]
-
-
-class PopVlanRouterSideBlockProvisioning(
- PopVlanRouterSideBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]
-):
- """An Pop VLAN router side that is being provisioned."""
-
- node: RouterBlockProvisioning
- ae_iface: str | None = None
- ae_members: LAGMemberList[PopVlanInterfaceBlockProvisioning]
-
-
-class PopVlanRouterSideBlock(PopVlanRouterSideBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
- """An active Pop VLAN router side."""
-
- node: RouterBlock
- ae_iface: str
- ae_members: LAGMemberList[PopVlanInterfaceBlock]
-
-
-class PopVlanSwitchSideBlockInactive(
- ProductBlockModel,
- lifecycle=[SubscriptionLifecycle.INITIAL],
- product_block_name="PopVlanSwitchSideBlock",
-):
- """An inactive Pop VLAN switch side."""
-
- node: SwitchBlockInactive
- ae_iface: str | None = None
- ae_members: LAGMemberList[PopVlanInterfaceBlockInactive]
-
-
-class PopVlanSwitchSideBlockProvisioning(
- PopVlanSwitchSideBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]
-):
- """An Pop VLAN switch side that is being provisioned."""
-
- node: SwitchBlockProvisioning
- ae_iface: str | None = None
- ae_members: LAGMemberList[PopVlanInterfaceBlockProvisioning]
-
-
-class PopVlanSwitchSideBlock(PopVlanSwitchSideBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
- """An active Pop VLAN switch side."""
-
- node: SwitchBlock
- ae_iface: str
- ae_members: LAGMemberList[PopVlanInterfaceBlock]
-
-
class PopVlanBlockInactive(
ProductBlockModel,
lifecycle=[SubscriptionLifecycle.INITIAL],
@@ -135,33 +60,41 @@ class PopVlanBlockInactive(
):
"""A Pop VLAN that's currently inactive, see :class:`PopVlanBlock`."""
- number_of_ports: int | None = None
- number_of_members: int | None = None
- router_side: PopVlanRouterSideBlockInactive
- switch_side: PopVlanSwitchSideBlockInactive
- ports: PortList[PopVlanPortBlockInactive]
+ vlan_id: int
+ description: str | None
+ lan_switch_interconnect: LanSwitchInterconnectInactive
+ ports: PortList[PopVlanPortBlockProvisioning]
+ layer_preference: LayerPreference
+ ipv4_network: IPv4Network | None = None
+ ipv6_network: IPv6Network | None = None
class PopVlanBlockProvisioning(PopVlanBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
"""A Pop VLAN that's currently being provisioned, see :class:`PopVlanBlock`."""
- number_of_ports: int | None = None
- number_of_members: int | None = None
- router_side: PopVlanRouterSideBlockProvisioning
- switch_side: PopVlanSwitchSideBlockProvisioning
+ vlan_id: int
+ description: str | None
+ lan_switch_interconnect: LanSwitchInterconnectProvisioning
ports: PortList[PopVlanPortBlockProvisioning]
+ layer_preference: LayerPreference
+ ipv4_network: IPv4Network | None = None
+ ipv6_network: IPv6Network | None = None
class PopVlanBlock(PopVlanBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
"""A Pop VLAN that's currently deployed in the network."""
- #: The number of ports in the Pop VLAN.
- number_of_ports: int
- #: The number of members in the Pop VLAN.
- number_of_members: int
- #: The router side of the Pop VLAN.
- router_side: PopVlanRouterSideBlock
- #: The switch side of the Pop VLAN.
- switch_side: PopVlanSwitchSideBlock
- #: The ports of the Pop VLAN.
+ #: The VLAN ID of the Pop VLAN.
+ vlan_id: int
+ #: The description of the Pop VLAN.
+ description: str
+ #: The Lan Switch Interconnect that this Pop VLAN is connected to.
+ lan_switch_interconnect: LanSwitchInterconnectBlock
+ #: The ports of the Pop VLAN.
ports: PortList[PopVlanPortBlock]
+ #: The level of the layer preference for the Pop VLAN (L2 or L3).
+ layer_preference: LayerPreference
+ #: IPv4 network for the Pop VLAN if layer_preference is L3.
+ ipv4_network: IPv4Network | None = None
+ #: IPv6 network for the Pop VLAN if layer_preference is L3.
+ ipv6_network: IPv6Network | None = None
diff --git a/gso/products/product_blocks/switch.py b/gso/products/product_blocks/switch.py
index 42f920a86689ce5cf132aa243b2c86c43e94a5b8..b0fdec46b1fe2e95c3dc9e7908585cc566d2f5c8 100644
--- a/gso/products/product_blocks/switch.py
+++ b/gso/products/product_blocks/switch.py
@@ -2,13 +2,22 @@
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle
+from pydantic_forms.types import strEnum
from gso.products.product_blocks.site import (
SiteBlock,
SiteBlockInactive,
SiteBlockProvisioning,
)
-from gso.utils.shared_enums import PortNumber
+from gso.utils.shared_enums import PortNumber, Vendor
+
+
+class SwitchModel(strEnum):
+ """Enumerator for the different types of switches."""
+
+ EX3400_24 = "EX3400 24"
+ EX3400_32 = "EX3400 32"
+ EX3400_48 = "EX3400 48"
class SwitchBlockInactive(
@@ -21,6 +30,8 @@ class SwitchBlockInactive(
switch_hostname: str | None = None
switch_ts_port: PortNumber | None = None
switch_site: SiteBlockInactive | None
+ switch_vendor: Vendor | None
+ switch_model: SwitchModel | None = None
class SwitchBlockProvisioning(SwitchBlockInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
@@ -29,6 +40,8 @@ class SwitchBlockProvisioning(SwitchBlockInactive, lifecycle=[SubscriptionLifecy
switch_hostname: str
switch_ts_port: PortNumber
switch_site: SiteBlockProvisioning
+ switch_vendor: Vendor
+ switch_model: SwitchModel | None = None
class SwitchBlock(SwitchBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
@@ -40,3 +53,7 @@ class SwitchBlock(SwitchBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTI
switch_ts_port: PortNumber
#: The :class:`Site` that this switch resides in. Both physically and computationally.
switch_site: SiteBlock
+ #: The vendor of the switch.
+ switch_vendor: Vendor
+ #: The model of the switch.
+ switch_model: SwitchModel | None = None