diff --git a/gso/workflows/iptrunk/terminate_iptrunk.py b/gso/workflows/iptrunk/terminate_iptrunk.py index 855c6cabe4b857785a9c5107ee72081b40e277b1..c0c47a8f5268ff1a9a7841afef9294704637b12b 100644 --- a/gso/workflows/iptrunk/terminate_iptrunk.py +++ b/gso/workflows/iptrunk/terminate_iptrunk.py @@ -17,6 +17,7 @@ from orchestrator.workflows.steps import ( ) from orchestrator.workflows.utils import wrap_modify_initial_input_form +from gso.products.product_blocks.iptrunk import IptrunkSideBlock from gso.products.product_blocks.router import RouterVendor from gso.products.product_types.iptrunk import Iptrunk from gso.services import infoblox @@ -32,11 +33,12 @@ def initial_input_form_generator() -> FormGenerator: class TerminateForm(FormPage): termination_label: Label = ( "Please confirm whether configuration should get removed from the A and B sides of the trunk, and whether " - "IPAM resources should be released." # type: ignore[assignment] + "IPAM and Netbox resources should be released." # type: ignore[assignment] ) tt_number: str remove_configuration: bool = True clean_up_ipam: bool = True + clean_up_netbox: bool = True user_input = yield TerminateForm return user_input.dict() @@ -88,26 +90,28 @@ def deprovision_ip_trunk_real(subscription: Iptrunk, process_id: UUIDstr, callba return {"subscription": subscription} -@step("Remove IP Trunk from Netbox") -def free_interfaces_in_netbox(subscription: Iptrunk) -> State: - """Mark used interfaces as free in Netbox. +def _remove_interface_from_netbox(side_block: IptrunkSideBlock) -> None: + nbclient = NetboxClient() - TODO: decide on the conditionality of this step - """ - for side in [0, 1]: - router = subscription.iptrunk.iptrunk_sides[side].iptrunk_side_node - router_vendor = get_router_vendor(router.owner_subscription_id) - router_fqdn = router.router_fqdn - if router_vendor == RouterVendor.NOKIA: - nbclient = NetboxClient() - # Remove physical interfaces from LAGs - for member in subscription.iptrunk.iptrunk_sides[side].iptrunk_side_ae_members: - nbclient.free_interface(router_fqdn, member.interface_name) - # Delete LAGs - nbclient.delete_interface( - router_fqdn, - subscription.iptrunk.iptrunk_sides[side].iptrunk_side_ae_iface, - ) + for member in side_block.iptrunk_side_ae_members: + nbclient.free_interface(side_block.iptrunk_side_node.router_fqdn, member.interface_name) + + if side_block.iptrunk_side_ae_iface: + nbclient.delete_interface(side_block.iptrunk_side_node.router_fqdn, side_block.iptrunk_side_ae_iface) + + +@step("Netbox: Remove interfaces on side A") +def netbox_remove_side_a_interfaces(subscription: Iptrunk) -> State: + """Mark used interfaces on side A as free in Netbox.""" + _remove_interface_from_netbox(subscription.iptrunk.iptrunk_sides[0]) + + return {"subscription": subscription} + + +@step("Netbox: Remove interfaces on side B") +def netbox_remove_side_b_interfaces(subscription: Iptrunk) -> State: + """Mark used interfaces on side B as free in Netbox.""" + _remove_interface_from_netbox(subscription.iptrunk.iptrunk_sides[1]) return {"subscription": subscription} @@ -139,12 +143,26 @@ def terminate_iptrunk() -> StepList: * Let the operator decide whether to remove configuration from the routers, if so: * Set the :term:`ISIS` metric of the IP trunk to an arbitrarily high value * Disable and remove configuration from the routers, first as a dry run - * Mark the IP trunk interfaces as free in Netbox + * Mark the IP trunk interfaces as free in Netbox, if selected by the operator * Clear :term:`IPAM` resources, if selected by the operator * Terminate the subscription in the service database """ run_config_steps = conditional(lambda state: state["remove_configuration"]) run_ipam_steps = conditional(lambda state: state["clean_up_ipam"]) + side_a_is_nokia = conditional( + lambda state: state["clean_up_netbox"] + and get_router_vendor( + state["subscription"]["iptrunk"]["iptrunk_sides"][0]["iptrunk_side_node"]["owner_subscription_id"] + ) + == RouterVendor.NOKIA + ) + side_b_is_nokia = conditional( + lambda state: state["clean_up_netbox"] + and get_router_vendor( + state["subscription"]["iptrunk"]["iptrunk_sides"][1]["iptrunk_side_node"]["owner_subscription_id"] + ) + == RouterVendor.NOKIA + ) config_steps = ( init @@ -159,7 +177,8 @@ def terminate_iptrunk() -> StepList: >> store_process_subscription(Target.TERMINATE) >> unsync >> run_config_steps(config_steps) - >> free_interfaces_in_netbox + >> side_a_is_nokia(netbox_remove_side_a_interfaces) + >> side_b_is_nokia(netbox_remove_side_b_interfaces) >> run_ipam_steps(ipam_steps) >> set_status(SubscriptionLifecycle.TERMINATED) >> resync