diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index bae7f18a57176d8261bd2581f12794f0344b28d4..5270caa68061f19f3ade4922f77e6aa5ee380f1d 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -8,7 +8,7 @@ from orchestrator.forms.validators import Choice, UniqueConstrainedList from orchestrator.targets import Target from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr from orchestrator.utils.json import json_dumps -from orchestrator.workflow import StepList, done, init, step, workflow +from orchestrator.workflow import StepList, conditional, done, init, step, workflow from orchestrator.workflows.steps import resync, set_status, store_process_subscription from orchestrator.workflows.utils import wrap_create_initial_input_form from pydantic import validator @@ -16,6 +16,7 @@ from pynetbox.models.dcim import Interfaces from gso.products.product_blocks.iptrunk import ( IptrunkInterfaceBlockInactive, + IptrunkSideBlockProvisioning, IptrunkType, PhyPortCapacity, ) @@ -39,11 +40,7 @@ from gso.utils.helpers import ( def initial_input_form_generator(product_name: str) -> FormGenerator: """Gather input from the user in three steps. General information, and information on both sides of the trunk.""" - # TODO: implement more strict validation: - # * interface names must be validated - routers = {} - for router in subscriptions.get_active_router_subscriptions(includes=["subscription_id", "description"]): routers[str(router["subscription_id"])] = router["description"] @@ -428,19 +425,24 @@ def reserve_interfaces_in_netbox(subscription: IptrunkProvisioning) -> State: } -@step("Allocate interfaces in Netbox") -def allocate_interfaces_in_netbox(subscription: IptrunkProvisioning) -> State: - """Allocate the :term:`LAG` interfaces in NetBox and attach the lag interfaces to the physical interfaces.""" - for trunk_side in subscription.iptrunk.iptrunk_sides: - if get_router_vendor(trunk_side.iptrunk_side_node.owner_subscription_id) == RouterVendor.NOKIA: - for interface in trunk_side.iptrunk_side_ae_members: - NetboxClient().allocate_interface( - device_name=trunk_side.iptrunk_side_node.router_fqdn, - iface_name=interface.interface_name, - ) - return { - "subscription": subscription, - } +def _allocate_interfaces_in_netbox(iptrunk_side: IptrunkSideBlockProvisioning) -> None: + for interface in iptrunk_side.iptrunk_side_ae_members: + NetboxClient().allocate_interface( + device_name=iptrunk_side.iptrunk_side_node.router_fqdn, + iface_name=interface.interface_name, + ) + + +@step("Allocate interfaces in Netbox for side A") +def netbox_allocate_side_a_interfaces(subscription: IptrunkProvisioning) -> None: + """Allocate the :term:`LAG` interfaces for the Nokia router on side A.""" + _allocate_interfaces_in_netbox(subscription.iptrunk.iptrunk_sides[0]) + + +@step("Allocate interfaces in Netbox for side B") +def netbox_allocate_side_b_interfaces(subscription: IptrunkProvisioning) -> None: + """Allocate the :term:`LAG` interfaces for the Nokia router on side B.""" + _allocate_interfaces_in_netbox(subscription.iptrunk.iptrunk_sides[1]) @workflow( @@ -461,6 +463,9 @@ def create_iptrunk() -> StepList: * Allocate the interfaces in Netbox * Set the subscription to active in the database """ + side_a_is_nokia = conditional(lambda state: get_router_vendor(state["side_a_node_id"]) == RouterVendor.NOKIA) + side_b_is_nokia = conditional(lambda state: get_router_vendor(state["side_b_node_id"]) == RouterVendor.NOKIA) + return ( init >> create_subscription @@ -474,7 +479,8 @@ def create_iptrunk() -> StepList: >> pp_interaction(provision_ip_trunk_isis_iface_dry) >> pp_interaction(provision_ip_trunk_isis_iface_real) >> pp_interaction(check_ip_trunk_isis) - >> allocate_interfaces_in_netbox + >> side_a_is_nokia(netbox_allocate_side_a_interfaces) + >> side_b_is_nokia(netbox_allocate_side_b_interfaces) >> set_status(SubscriptionLifecycle.ACTIVE) >> resync >> done