From 7235cee5f36badf7204de85fd50f2cf2e86439e4 Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Mon, 4 Nov 2024 11:19:52 +0100 Subject: [PATCH] Improve L2Circuits creation WF --- .../l2_circuit/create_layer_2_circuit.py | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/gso/workflows/l2_circuit/create_layer_2_circuit.py b/gso/workflows/l2_circuit/create_layer_2_circuit.py index c3fdae2a..73e6d168 100644 --- a/gso/workflows/l2_circuit/create_layer_2_circuit.py +++ b/gso/workflows/l2_circuit/create_layer_2_circuit.py @@ -1,6 +1,6 @@ """Workflow for creating a new Layer 2 Circuit.""" -from typing import Any +from typing import Any, Self from uuid import uuid4 from orchestrator import step, workflow @@ -10,7 +10,7 @@ from orchestrator.types import SubscriptionLifecycle 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 -from pydantic import BaseModel, ConfigDict, Field +from pydantic import BaseModel, ConfigDict, Field, model_validator from pydantic_forms.types import FormGenerator, State, UUIDstr from pydantic_forms.validators import Divider, Label, ReadOnlyField @@ -18,6 +18,7 @@ from gso.products.product_blocks.layer_2_circuit import Layer2CircuitSideBlockIn from gso.products.product_blocks.service_binding_port import ServiceBindingPortInactive from gso.products.product_types.edge_port import EdgePort from gso.products.product_types.layer_2_circuit import Layer2Circuit, Layer2CircuitInactive +from gso.services.partners import get_partner_by_name from gso.utils.helpers import active_edge_port_selector, generate_unique_vc_id, partner_choice from gso.utils.shared_enums import SBPType from gso.utils.types.interfaces import BandwidthString @@ -27,12 +28,13 @@ from gso.utils.types.virtual_identifiers import VLAN_ID def initial_input_generator(product_name: str) -> FormGenerator: """Gather input from the operator about a new Layer 2 Circuit subscription.""" + geant_partner_id = get_partner_by_name("GEANT")["partner_id"] class CreateLayer2CircuitServicePage(FormPage): model_config = ConfigDict(title=f"{product_name}") tt_number: TTNumber - partner: partner_choice() # type: ignore[valid-type] + partner: partner_choice() = geant_partner_id # type: ignore[valid-type] divider: Divider = Field(None, exclude=True) layer_2_circuit_type: Layer2CircuitType @@ -41,35 +43,42 @@ def initial_input_generator(product_name: str) -> FormGenerator: initial_user_input = yield CreateLayer2CircuitServicePage class Layer2CircuitSideSelection(BaseModel): - edge_port: active_edge_port_selector(partner_id=initial_user_input.partner) # type: ignore[valid-type] + edge_port: active_edge_port_selector( + partner_id=initial_user_input.partner if initial_user_input.partner != geant_partner_id else None + ) vlan_id: VLAN_ID + def vlan_range_field(*, is_tagged: bool) -> Any: + """Return the appropriate field type based on whether the circuit is tagged.""" + return VLAN_ID if is_tagged else ReadOnlyField(None, default_type=int) + class Layer2CircuitServiceSidesPage(FormPage): model_config = ConfigDict(title=f"{product_name} - Configure Edge Ports") - if initial_user_input.layer_2_circuit_type == Layer2CircuitType.TAGGED: - vlan_range_label: Label = Field("Please set a VLAN range, bounds including.", exclude=True) - vlan_range_lower_bound: VLAN_ID - vlan_range_upper_bound: VLAN_ID - else: - vlan_range_lower_bound: ReadOnlyField(None, default_type=int) - vlan_range_upper_bound: ReadOnlyField(None, default_type=int) - + vlan_range_label: Label = Field("Please set a VLAN range, bounds including.", exclude=True) + vlan_range_lower_bound: vlan_range_field( + is_tagged=initial_user_input.layer_2_circuit_type == Layer2CircuitType.TAGGED + ) + vlan_range_upper_bound: vlan_range_field( + is_tagged=initial_user_input.layer_2_circuit_type == Layer2CircuitType.TAGGED + ) vlan_divider: Divider = Field(None, exclude=True) - - if initial_user_input.policer_enabled: - policer_bandwidth: BandwidthString - else: - policer_bandwidth: ReadOnlyField(None, default_type=str) - - policer_divider: Divider = Field(None, exclude=True) - + policer_bandwidth: ( + BandwidthString if initial_user_input.policer_enabled else ReadOnlyField(None, default_type=str) + ) geant_sid: str layer_2_circuit_side_a: Layer2CircuitSideSelection side_divider: Divider = Field(None, exclude=True) layer_2_circuit_side_b: Layer2CircuitSideSelection + @model_validator(mode="after") + def check_unique_sides(self) -> Self: + if self.layer_2_circuit_side_a.edge_port == self.layer_2_circuit_side_b.edge_port: + msg = "Both sides of the circuit cannot be connected to the same edge port" + raise ValueError(msg) + return self + layer_2_circuit_input = yield Layer2CircuitServiceSidesPage return {"product_name": product_name} | initial_user_input.model_dump() | layer_2_circuit_input.model_dump() @@ -116,6 +125,7 @@ def initialize_subscription( subscription.layer_2_circuit.vlan_range_upper_bound = vlan_range_upper_bound subscription.layer_2_circuit.policer_enabled = policer_enabled subscription.layer_2_circuit.bandwidth = policer_bandwidth + subscription.description = (f"GÉANT PLUS {subscription.layer_2_circuit.virtual_circuit_id}") subscription = Layer2Circuit.from_other_lifecycle(subscription, SubscriptionLifecycle.PROVISIONING) -- GitLab