From a69686728ad8f02a357a8005633cd950c304f24c Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Fri, 4 Oct 2024 14:40:44 +0100
Subject: [PATCH] Use of common BGP and SDP functions from `workflow_steps`

---
 gso/workflows/router/promote_p_to_pe.py  | 248 ++---------------------
 gso/workflows/router/update_ibgp_mesh.py |  45 +++-
 2 files changed, 53 insertions(+), 240 deletions(-)

diff --git a/gso/workflows/router/promote_p_to_pe.py b/gso/workflows/router/promote_p_to_pe.py
index 3bc2e80f..101e4c65 100644
--- a/gso/workflows/router/promote_p_to_pe.py
+++ b/gso/workflows/router/promote_p_to_pe.py
@@ -23,6 +23,20 @@ from gso.services.subscriptions import get_all_active_sites
 from gso.utils.helpers import generate_inventory_for_active_routers
 from gso.utils.shared_enums import Vendor
 from gso.utils.types.tt_number import TTNumber
+from gso.utils.workflow_steps import (
+    add_all_p_to_pe_dry,
+    add_all_p_to_pe_real,
+    add_pe_mesh_to_pe_dry,
+    add_pe_mesh_to_pe_real,
+    add_pe_to_all_p_dry,
+    add_pe_to_all_p_real,
+    add_pe_to_pe_mesh_dry,
+    add_pe_to_pe_mesh_real,
+    check_l3_services,
+    check_pe_ibgp,
+    update_sdp_mesh_dry,
+    update_sdp_mesh_real,
+)
 
 
 def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
@@ -150,54 +164,6 @@ def create_kentik_device(subscription: Router) -> State:
     return {"kentik_device": kentik_device}
 
 
-@step("[DRY RUN] Include new PE into SDP mesh on other Nokia PEs")
-def update_sdp_mesh_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a dry run for updating the SDP mesh with the new router."""
-    extra_vars = {
-        "dry_run": True,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Update the SDP mesh for L2circuits(epipes) config on PE NOKIA routers",
-        "verb": "update_sdp_mesh",
-        "pe_router_list": {
-            subscription["router"]["router_fqdn"]: {
-                "lo4": str(subscription["router"]["router_lo_ipv4_address"]),
-                "lo6": str(subscription["router"]["router_lo_ipv6_address"]),
-            }
-        },
-    }
-
-    return {
-        "playbook_name": "update_pe_sdp_mesh.yaml",
-        "inventory": generate_inventory_for_active_routers(router_role=RouterRole.PE, router_vendor=Vendor.NOKIA),
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[FOR REAL] Include new PE into SDP mesh on other Nokia PEs")
-def update_sdp_mesh_real(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Update the SDP mesh for L2 circuits(epipes) config on PE NOKIA routers."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Update the SDP mesh for l2circuits(epipes) config on PE NOKIA routers",
-        "verb": "update_sdp_mesh",
-        "pe_router_list": {
-            subscription["router"]["router_fqdn"]: {
-                "lo4": str(subscription["router"]["router_lo_ipv4_address"]),
-                "lo6": str(subscription["router"]["router_lo_ipv6_address"]),
-            }
-        },
-    }
-
-    return {
-        "playbook_name": "update_pe_sdp_mesh.yaml",
-        "inventory": generate_inventory_for_active_routers(router_role=RouterRole.PE, router_vendor=Vendor.NOKIA),
-        "extra_vars": extra_vars,
-    }
-
-
 @step("[DRY RUN] Remove P from all PEs")
 def remove_p_from_pe_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
     """Perform a dry run of removing the P router from all the PE routers."""
@@ -234,96 +200,6 @@ def remove_p_from_pe_real(subscription: dict[str, Any], tt_number: str, process_
     }
 
 
-@step("[DRY RUN] Add PE mesh to PE")
-def add_pe_mesh_to_pe_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a dry run of adding list of PE routers into iGEANT/iGEANT6 of promoted router."""
-    extra_vars = {
-        "dry_run": True,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Add list of PE routers into iGEANT/iGEANT6 of promoted router",
-        "verb": "add_pe_mesh_to_pe",
-        "pe_router_list": generate_inventory_for_active_routers(RouterRole.PE)["all"]["hosts"],
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[FOR REAL] Add PE mesh to PE")
-def add_pe_mesh_to_pe_real(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a real run of adding list of PE routers into iGEANT/iGEANT6 of promoted router."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Add list of PE routers into iGEANT/iGEANT6 of promoted router",
-        "verb": "add_pe_mesh_to_pe",
-        "pe_router_list": generate_inventory_for_active_routers(RouterRole.PE)["all"]["hosts"],
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[DRY RUN] Add PE to PE mesh")
-def add_pe_to_pe_mesh_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a dry run of adding the promoted router to all PE routers in iGEANT/iGEANT6."""
-    extra_vars = {
-        "dry_run": True,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Add promoted router to all PE routers in iGEANT/iGEANT6.",
-        "verb": "add_pe_to_pe_mesh",
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": generate_inventory_for_active_routers(RouterRole.PE),
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[FOR REAL] Add PE to PE mesh")
-def add_pe_to_pe_mesh_real(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a real run of adding the promoted router to all PE routers in iGEANT/iGEANT6."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Add promoted router to all PE routers in iGEANT/iGEANT6.",
-        "verb": "add_pe_to_pe_mesh",
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": generate_inventory_for_active_routers(RouterRole.PE),
-        "extra_vars": extra_vars,
-    }
-
-
-@step("Check iBGP session")
-def check_pe_ibgp(subscription: dict[str, Any]) -> LSOState:
-    """Check the iBGP session."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "verb": "check_pe_ibgp",
-    }
-
-    return {
-        "playbook_name": "check_ibgp.yaml",
-        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
-        "extra_vars": extra_vars,
-    }
-
-
 @step("[DRY RUN] Deploy routing instances")
 def deploy_routing_instances_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
     """Perform a dry run of deploying routing instances."""
@@ -358,22 +234,6 @@ def deploy_routing_instances_real(subscription: dict[str, Any], tt_number: str,
     }
 
 
-@step("Check L3 services")
-def check_l3_services(subscription: dict[str, Any]) -> LSOState:
-    """Check L3 services."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "verb": "check_base_ris",
-    }
-
-    return {
-        "playbook_name": "check_l3_services.yaml",
-        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
-        "extra_vars": extra_vars,
-    }
-
-
 @step("Remove ISIS overload")
 def remove_isis_overload(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
     """Remove ISIS overload."""
@@ -399,86 +259,6 @@ def update_subscription_model(subscription: Router) -> State:
     return {"subscription": subscription}
 
 
-@step("[DRY RUN] Add all P to this new PE")
-def add_all_p_to_pe_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a dry run of adding all P routers to the PE router."""
-    extra_vars = {
-        "dry_run": True,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Add all P-routers to this new PE",
-        "verb": "add_all_p_to_pe",
-        "p_router_list": generate_inventory_for_active_routers(
-            RouterRole.P, exclude_routers=[subscription["router"]["router_fqdn"]]
-        )["all"]["hosts"],
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[FOR REAL] Add all P to this new PE")
-def add_all_p_to_pe_real(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a real run of adding all P routers to the PE router."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - Add all P-routers to this new PE",
-        "verb": "add_all_p_to_pe",
-        "p_router_list": generate_inventory_for_active_routers(
-            RouterRole.P, exclude_routers=[subscription["router"]["router_fqdn"]]
-        )["all"]["hosts"],
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[DRY RUN] Add this new PE to all P")
-def add_pe_to_all_p_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a dry run of adding promoted router to all PE routers in iGEANT/iGEANT6."""
-    extra_vars = {
-        "dry_run": True,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Add promoted router to all PE routers in iGEANT/iGEANT6",
-        "verb": "add_pe_to_all_p",
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": generate_inventory_for_active_routers(
-            RouterRole.P, exclude_routers=[subscription["router"]["router_fqdn"]]
-        ),
-        "extra_vars": extra_vars,
-    }
-
-
-@step("[FOR REAL] Add this new PE to all P")
-def add_pe_to_all_p_real(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
-    """Perform a real run of adding promoted router to all PE routers in iGEANT/iGEANT6."""
-    extra_vars = {
-        "dry_run": False,
-        "subscription": subscription,
-        "commit_comment": f"GSO_PROCESS_ID: {process_id} - TT_NUMBER: {tt_number} - "
-        f"Add promoted router to all PE routers in iGEANT/iGEANT6",
-        "verb": "add_pe_to_all_p",
-    }
-
-    return {
-        "playbook_name": "update_ibgp_mesh.yaml",
-        "inventory": generate_inventory_for_active_routers(
-            RouterRole.P, exclude_routers=[subscription["router"]["router_fqdn"]]
-        ),
-        "extra_vars": extra_vars,
-    }
-
-
 @step("[DRY RUN] Delete default routes")
 def delete_default_routes_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr) -> LSOState:
     """Perform a dry run of deleting the default routes."""
diff --git a/gso/workflows/router/update_ibgp_mesh.py b/gso/workflows/router/update_ibgp_mesh.py
index 9c88704b..98f17122 100644
--- a/gso/workflows/router/update_ibgp_mesh.py
+++ b/gso/workflows/router/update_ibgp_mesh.py
@@ -7,7 +7,7 @@ from orchestrator.forms import FormPage
 from orchestrator.forms.validators import Label
 from orchestrator.targets import Target
 from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
-from orchestrator.workflow import StepList, begin, done, inputstep, step, workflow
+from orchestrator.workflow import StepList, begin, conditional, done, inputstep, step, workflow
 from orchestrator.workflows.steps import resync, store_process_subscription, unsync
 from orchestrator.workflows.utils import wrap_modify_initial_input_form
 from pydantic import ConfigDict, model_validator
@@ -20,6 +20,22 @@ from gso.services.subscriptions import get_trunks_that_terminate_on_router
 from gso.utils.helpers import generate_inventory_for_active_routers
 from gso.utils.types.snmp import SNMPVersion
 from gso.utils.types.tt_number import TTNumber
+from gso.utils.workflow_steps import (
+    add_all_p_to_pe_dry,
+    add_all_p_to_pe_real,
+    add_pe_mesh_to_pe_dry,
+    add_pe_mesh_to_pe_real,
+    add_pe_to_all_p_dry,
+    add_pe_to_all_p_real,
+    add_pe_to_pe_mesh_dry,
+    add_pe_to_pe_mesh_real,
+    check_l3_services,
+    check_pe_ibgp,
+    update_sdp_mesh_dry,
+    update_sdp_mesh_real,
+    update_sdp_single_pe_dry,
+    update_sdp_single_pe_real,
+)
 
 
 def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
@@ -194,15 +210,32 @@ def update_ibgp_mesh() -> StepList:
     * Add the new P-router to LibreNMS.
     * Update the subscription model.
     """
+    router_is_pe = conditional(lambda state: state["router_role"] == RouterRole.PE)
+    router_is_p = conditional(lambda state: state["router_role"] == RouterRole.P)
+
     return (
         begin
         >> store_process_subscription(Target.MODIFY)
         >> unsync
-        >> lso_interaction(add_p_to_mesh_dry)
-        >> lso_interaction(add_p_to_mesh_real)
-        >> lso_interaction(add_all_pe_to_p_dry)
-        >> lso_interaction(add_all_pe_to_p_real)
-        >> lso_interaction(check_ibgp_session)
+        >> router_is_p(lso_interaction(add_p_to_mesh_dry))
+        >> router_is_p(lso_interaction(add_p_to_mesh_real))
+        >> router_is_p(lso_interaction(add_all_pe_to_p_dry))
+        >> router_is_p(lso_interaction(add_all_pe_to_p_real))
+        >> router_is_p(lso_interaction(check_ibgp_session))
+        >> router_is_pe(lso_interaction(add_pe_mesh_to_pe_dry))
+        >> router_is_pe(lso_interaction(add_pe_mesh_to_pe_real))
+        >> router_is_pe(lso_interaction(add_pe_to_pe_mesh_dry))
+        >> router_is_pe(lso_interaction(add_pe_to_pe_mesh_real))
+        >> router_is_pe(lso_interaction(add_all_p_to_pe_dry))
+        >> router_is_pe(lso_interaction(add_all_p_to_pe_real))
+        >> router_is_pe(lso_interaction(add_pe_to_all_p_dry))
+        >> router_is_pe(lso_interaction(add_pe_to_all_p_real))
+        >> router_is_pe(lso_interaction(update_sdp_single_pe_dry))
+        >> router_is_pe(lso_interaction(update_sdp_single_pe_real))
+        >> router_is_pe(lso_interaction(update_sdp_mesh_dry))
+        >> router_is_pe(lso_interaction(update_sdp_mesh_real))
+        >> router_is_pe(lso_interaction(check_pe_ibgp))
+        >> router_is_pe(lso_interaction(check_l3_services))
         >> add_device_to_librenms
         >> prompt_insert_in_radius
         >> prompt_radius_login
-- 
GitLab