Skip to content

Shared

Shared workflow steps for Router workflows.

deploy_base_config_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of provisioning base config on a router.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Deploy base config")
def deploy_base_config_dry(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a dry run of provisioning base config on a router."""
    return _deploy_base_config(subscription, tt_number, process_id, workflow_name, dry_run=True)

deploy_base_config_real(subscription, tt_number, process_id, workflow_name)

Deploy base config on a router using the provisioning proxy.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Deploy base config")
def deploy_base_config_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Deploy base config on a router using the provisioning proxy."""
    return _deploy_base_config(subscription, tt_number, process_id, workflow_name, dry_run=False)

add_pe_to_all_p_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of adding the PE router to all P routers.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Add the PE to all P routers")
def add_pe_to_all_p_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str) -> State:
    """Perform a dry run of adding the PE router to all P routers."""
    return _add_pe_to_all_p(subscription, tt_number, process_id, workflow_name, dry_run=True)

add_pe_to_all_p_real(subscription, tt_number, process_id, workflow_name)

Perform a real run of adding the PE router to all P routers.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Add the PE to all P routers")
def add_pe_to_all_p_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a real run of adding the PE router to all P routers."""
    return _add_pe_to_all_p(subscription, tt_number, process_id, workflow_name, dry_run=False)

add_all_p_to_pe_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of adding all P routers to the PE router.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Add all P routers to the PE")
def add_all_p_to_pe_dry(subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str) -> State:
    """Perform a dry run of adding all P routers to the PE router."""
    return _add_all_p_to_pe(subscription, tt_number, process_id, workflow_name, dry_run=True)

add_all_p_to_pe_real(subscription, tt_number, process_id, workflow_name)

Perform a real run of adding all P routers to the PE router.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Add all P routers to the PE")
def add_all_p_to_pe_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a real run of adding all P routers to the PE router."""
    return _add_all_p_to_pe(subscription, tt_number, process_id, workflow_name, dry_run=False)

add_pe_to_pe_mesh_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of adding the PE router to all PE routers in iGEANT/iGEANT6.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Add the PE to PE mesh")
def add_pe_to_pe_mesh_dry(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a dry run of adding the PE router to all PE routers in iGEANT/iGEANT6."""
    return _add_pe_to_pe_mesh(subscription, tt_number, process_id, workflow_name, dry_run=True)

add_pe_to_pe_mesh_real(subscription, tt_number, process_id, workflow_name)

Perform a real run of adding the PE router to all PE routers in iGEANT/iGEANT6.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Add the PE to PE mesh")
def add_pe_to_pe_mesh_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a real run of adding the PE router to all PE routers in iGEANT/iGEANT6."""
    return _add_pe_to_pe_mesh(subscription, tt_number, process_id, workflow_name, dry_run=False)

add_pe_mesh_to_pe_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of adding list of PE routers into iGEANT/iGEANT6 of the router.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Add PE mesh to the PE")
def add_pe_mesh_to_pe_dry(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a dry run of adding list of PE routers into iGEANT/iGEANT6 of the router."""
    return _add_pe_mesh_to_pe(subscription, tt_number, process_id, workflow_name, dry_run=True)

add_pe_mesh_to_pe_real(subscription, tt_number, process_id, workflow_name)

Perform a real run of adding list of PE routers into iGEANT/iGEANT6 of the router.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Add PE mesh to the PE")
def add_pe_mesh_to_pe_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a real run of adding list of PE routers into iGEANT/iGEANT6 of the router."""
    return _add_pe_mesh_to_pe(subscription, tt_number, process_id, workflow_name, dry_run=False)

add_pe_to_sdp_mesh_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of including new PE router in SDP mesh on other NOKIA PE routers.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Include the PE into SDP mesh on other Nokia PEs")
def add_pe_to_sdp_mesh_dry(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a dry run of including new PE router in SDP mesh on other NOKIA PE routers."""
    return _update_sdp_mesh(subscription, tt_number, process_id, "add_pe_to_sdp_mesh", workflow_name, dry_run=True)

add_pe_to_sdp_mesh_real(subscription, tt_number, process_id, workflow_name)

Perform a real run of including new PE router in SDP mesh on other NOKIA PE routers.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Include the PE into SDP mesh on other Nokia PEs")
def add_pe_to_sdp_mesh_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a real run of including new PE router in SDP mesh on other NOKIA PE routers."""
    return _update_sdp_mesh(subscription, tt_number, process_id, "add_pe_to_sdp_mesh", workflow_name, dry_run=False)

remove_pe_from_sdp_mesh_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of including new PE router in SDP mesh on other NOKIA PE routers.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Include the PE into SDP mesh on other Nokia PEs")
def remove_pe_from_sdp_mesh_dry(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a dry run of including new PE router in SDP mesh on other NOKIA PE routers."""
    return _update_sdp_mesh(subscription, tt_number, process_id, "remove_pe_from_sdp_mesh", workflow_name, dry_run=True)

remove_pe_from_sdp_mesh_real(subscription, tt_number, process_id, workflow_name)

Perform a real run of including new PE router in SDP mesh on other NOKIA PE routers.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Include the PE into SDP mesh on other Nokia PEs")
def remove_pe_from_sdp_mesh_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a real run of including new PE router in SDP mesh on other NOKIA PE routers."""
    return _update_sdp_mesh(
        subscription, tt_number, process_id, "remove_pe_from_sdp_mesh", workflow_name, dry_run=False
    )

update_sdp_single_pe_dry(subscription, tt_number, process_id, workflow_name)

Perform a dry run of configuring SDP on a new PE router to all other NOKIA PE routers.

Source code in gso/workflows/router/shared.py
@step("[DRY RUN] Configure SDP on the PE to all other PEs")
def update_sdp_single_pe_dry(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Perform a dry run of configuring SDP on a new PE router to all other NOKIA PE routers."""
    return _update_sdp_single_pe(subscription, tt_number, process_id, workflow_name, dry_run=True)

update_sdp_single_pe_real(subscription, tt_number, process_id, workflow_name)

Configure SDP on a new PE router to all other NOKIA PE routers.

Source code in gso/workflows/router/shared.py
@step("[FOR REAL] Configure SDP on the PE to all other PEs")
def update_sdp_single_pe_real(
    subscription: dict[str, Any], tt_number: str, process_id: UUIDstr, workflow_name: str
) -> State:
    """Configure SDP on a new PE router to all other NOKIA PE routers."""
    return _update_sdp_single_pe(subscription, tt_number, process_id, workflow_name, dry_run=False)

check_pe_ibgp(subscription)

Check the iBGP session.

Source code in gso/workflows/router/shared.py
@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": "gap_ansible/playbooks/check_ibgp.yaml",
        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
        "extra_vars": extra_vars,
    }

check_l3_services(subscription)

Check L3 services.

Source code in gso/workflows/router/shared.py
@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": "gap_ansible/playbooks/check_l3_services.yaml",
        "inventory": {"all": {"hosts": {subscription["router"]["router_fqdn"]: None}}},
        "extra_vars": extra_vars,
    }

create_kentik_device(state, process_id)

Create a new device in Kentik.

Source code in gso/workflows/router/shared.py
@step("Create Kentik device")
def create_kentik_device(state: State, process_id: UUIDstr) -> State:
    """Create a new device in Kentik."""
    oss_params = load_oss_params()
    if not oss_params.KENTIK:
        msg = "Kentik integration is not enabled in OSS parameters, cannot continue."
        raise ProcessFailureError(msg)
    kentik_client = KentikClient()
    kentik_site = kentik_client.get_site_by_name(state["subscription"]["router"]["router_site"]["site_name"])

    if not kentik_site:
        msg = "Site could not be found in Kentik."
        raise ProcessFailureError(msg, details=state["subscription"]["router"]["router_site"]["site_name"])

    router_fqdn = state["subscription"]["router"]["router_fqdn"]
    new_device = NewKentikDevice(
        device_name=router_fqdn,
        device_description=str(state["subscription"]["subscription_id"]),
        sending_ips=[str(state["subscription"]["router"]["router_lo_ipv4_address"])],
        site_id=kentik_site["id"],
        device_snmp_ip=str(state["subscription"]["router"]["router_lo_ipv4_address"]),
        device_bgp_flowspec=False,
        device_bgp_neighbor_ip=str(state["subscription"]["router"]["router_lo_ipv4_address"]),
        device_bgp_neighbor_ip6=str(state["subscription"]["router"]["router_lo_ipv6_address"]),
    )
    kentik_device = kentik_client.create_device(new_device)

    email_body = f"A new router has been added to Kentik: {router_fqdn}\n"
    active_kentik_plan = kentik_client.get_plan_by_name(oss_params.KENTIK.active_router_license_key)
    active_kentik_device_count = len(active_kentik_plan["devices"])
    available_licenses = active_kentik_plan["maxDevices"]
    kentik_license_warning_threshold = 0.9
    #  Alert if we go across 90% utilization of available licenses.
    if (active_kentik_device_count / available_licenses) > kentik_license_warning_threshold:
        email_body += (
            f"Warning: {active_kentik_device_count} out of {available_licenses} license keys are currently in use.\n"
        )

    email_body += (
        f"\nFor reference, the workflow run can be found at: {oss_params.GENERAL.public_hostname}/workflows/"
        f"{process_id}\n\nRegards, the GÉANT Automation Platform."
    )

    send_mail(
        "[GAP] A new Router has been added to Kentik",
        email_body,
        destination=oss_params.EMAIL.kentik_email_destinations,
    )

    return {"kentik_device": kentik_device}