Skip to content
Snippets Groups Projects
Verified Commit e8b37d37 authored by Karel van Klink's avatar Karel van Klink :smiley_cat:
Browse files

Add a router to Kentik when creating with a PE role

parent 75384f00
No related branches found
Tags 2.13
1 merge request!309Add a router to Kentik when creating with a PE role
Pipeline #90508 failed
......@@ -6,6 +6,7 @@ from typing import Any
from orchestrator import inputstep, step
from orchestrator.config.assignee import Assignee
from orchestrator.types import State, UUIDstr
from orchestrator.utils.errors import ProcessFailureError
from orchestrator.utils.json import json_dumps
from orchestrator.workflow import StepList, conditional
from pydantic import ConfigDict
......@@ -15,6 +16,7 @@ from pydantic_forms.validators import Label
from gso.products.product_blocks.router import RouterRole
from gso.products.product_types.iptrunk import Iptrunk
from gso.services.kentik_client import KentikClient, NewKentikDevice
from gso.services.lso_client import LSOState, indifferent_lso_interaction
from gso.settings import load_oss_params
from gso.utils.helpers import generate_inventory_for_active_routers
......@@ -423,3 +425,28 @@ def stop_moodi() -> StepList:
}
return _is_moodi_enabled(indifferent_lso_interaction(_stop_moodi))
@step("Create Kentik device")
def create_kentik_device(state: State) -> State:
"""Create a new device in Kentik."""
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"])
new_device = NewKentikDevice(
device_name=state["subscription"]["router"]["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)
return {"kentik_device": kentik_device}
......@@ -28,6 +28,7 @@ from gso.utils.shared_enums import Vendor
from gso.utils.types.ip_address import PortNumber
from gso.utils.types.tt_number import TTNumber
from gso.utils.workflow_steps import (
create_kentik_device,
deploy_base_config_dry,
deploy_base_config_real,
prompt_sharepoint_checklist_url,
......@@ -254,6 +255,7 @@ def create_router() -> StepList:
* Create a new device in Netbox
"""
router_is_nokia = conditional(lambda state: state["vendor"] == Vendor.NOKIA)
router_is_pe = conditional(lambda state: state["router_role"] == RouterRole.PE)
return (
begin
......@@ -261,6 +263,7 @@ def create_router() -> StepList:
>> store_process_subscription(Target.CREATE)
>> initialize_subscription
>> ipam_allocate_loopback
>> router_is_pe(create_kentik_device)
>> lso_interaction(deploy_base_config_dry)
>> lso_interaction(deploy_base_config_real)
>> verify_ipam_loopback
......
......@@ -8,7 +8,6 @@ from orchestrator.forms import FormPage
from orchestrator.forms.validators import Label
from orchestrator.targets import Target
from orchestrator.types import FormGenerator, State, UUIDstr
from orchestrator.utils.errors import ProcessFailureError
from orchestrator.utils.json import json_dumps
from orchestrator.workflow import StepList, begin, done, inputstep, step, workflow
from orchestrator.workflows.steps import resync, store_process_subscription, unsync
......@@ -17,7 +16,6 @@ from pydantic import ConfigDict, model_validator
from gso.products.product_blocks.router import RouterRole
from gso.products.product_types.router import Router
from gso.services.kentik_client import KentikClient, NewKentikDevice
from gso.services.lso_client import LSOState, lso_interaction
from gso.services.subscriptions import get_all_active_sites
from gso.utils.helpers import generate_inventory_for_active_routers
......@@ -34,6 +32,7 @@ from gso.utils.workflow_steps import (
add_pe_to_pe_mesh_real,
check_l3_services,
check_pe_ibgp,
create_kentik_device,
update_sdp_mesh_dry,
update_sdp_mesh_real,
)
......@@ -130,40 +129,6 @@ def prompt_insert_in_earl(subscription: dict[str, Any]) -> FormGenerator:
return {}
@step("Create Kentik device")
def create_kentik_device(subscription: Router) -> State:
"""Create a new device in Kentik."""
if not (
subscription.router.router_site
and subscription.router.router_site.site_name
and subscription.router.router_site.site_tier
and subscription.router.router_fqdn
):
msg = "Router object is missing required properties."
raise ProcessFailureError(msg)
kentik_client = KentikClient()
kentik_site = kentik_client.get_site_by_name(subscription.router.router_site.site_name)
if not kentik_site:
msg = "Site could not be found in Kentik."
raise ProcessFailureError(msg, details=subscription.router.router_site.site_name)
new_device = NewKentikDevice(
device_name=subscription.router.router_fqdn,
device_description=str(subscription.subscription_id),
sending_ips=[str(subscription.router.router_lo_ipv4_address)],
site_id=kentik_site["id"],
device_snmp_ip=str(subscription.router.router_lo_ipv4_address),
device_bgp_flowspec=False,
device_bgp_neighbor_ip=str(subscription.router.router_lo_ipv4_address),
device_bgp_neighbor_ip6=str(subscription.router.router_lo_ipv6_address),
)
kentik_device = kentik_client.create_device(new_device)
return {"kentik_device": kentik_device}
@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."""
......
......@@ -10,7 +10,7 @@ from gso.products.product_types.site import Site
from gso.services.subscriptions import get_product_id_by_name
from gso.utils.shared_enums import Vendor
from test import USER_CONFIRM_EMPTY_FORM
from test.services.conftest import MockedSharePointClient
from test.services.conftest import MockedKentikClient, MockedSharePointClient
from test.workflows import (
assert_complete,
assert_lso_interaction_failure,
......@@ -31,19 +31,21 @@ def router_creation_input_form_data(site_subscription_factory, faker):
"router_site": router_site,
"hostname": faker.pystr(),
"ts_port": faker.pyint(),
"router_role": faker.random_choices(elements=(RouterRole.P, RouterRole.PE, RouterRole.AMT), length=1)[0],
"vendor": Vendor.NOKIA,
}
@pytest.mark.workflow()
@pytest.mark.parametrize("router_role", [RouterRole.P, RouterRole.PE])
@patch("gso.services.lso_client._send_request")
@patch("gso.workflows.router.create_router.NetboxClient.create_device")
@patch("gso.workflows.router.create_router.infoblox.hostname_available")
@patch("gso.workflows.router.create_router.infoblox.find_host_by_fqdn")
@patch("gso.workflows.router.create_router.infoblox.allocate_host")
@patch("gso.workflows.router.create_router.SharePointClient")
@patch("gso.utils.workflow_steps.KentikClient")
def test_create_nokia_router_success(
mock_kentik_client,
mock_sharepoint_client,
mock_allocate_host,
mock_find_host_by_fqdn,
......@@ -51,10 +53,11 @@ def test_create_nokia_router_success(
mock_netbox_create_device,
mock_provision_router,
router_creation_input_form_data,
router_role,
faker,
data_config_filename,
):
# Set up mock return values
mock_kentik_client.return_value = MockedKentikClient
product_id = get_product_id_by_name(ProductName.ROUTER)
mock_site = Site.from_subscription(router_creation_input_form_data["router_site"]).site
mock_v4 = faker.ipv4()
......@@ -68,7 +71,7 @@ def test_create_nokia_router_success(
mock_sharepoint_client.return_value = MockedSharePointClient
# Run workflow
initial_router_data = [{"product": product_id}, router_creation_input_form_data, {}]
initial_router_data = [{"product": product_id}, router_creation_input_form_data | {"router_role": router_role}, {}]
result, process_stat, step_log = run_workflow("create_router", initial_router_data)
state = extract_state(result)
......@@ -118,6 +121,7 @@ def test_create_nokia_router_success(
@pytest.mark.workflow()
@pytest.mark.parametrize("router_role", [RouterRole.P, RouterRole.PE])
@patch("gso.services.lso_client._send_request")
@patch("gso.workflows.router.create_router.NetboxClient.create_device")
@patch("gso.workflows.router.create_router.infoblox.hostname_available")
......@@ -126,7 +130,9 @@ def test_create_nokia_router_success(
@patch("gso.workflows.router.create_router.infoblox.allocate_v6_network")
@patch("gso.workflows.router.create_router.infoblox.allocate_v4_network")
@patch("gso.workflows.router.create_router.infoblox.allocate_host")
@patch("gso.utils.workflow_steps.KentikClient")
def test_create_nokia_router_lso_failure(
mock_kentik_client,
mock_allocate_host,
mock_allocate_v4_network,
mock_allocate_v6_network,
......@@ -136,9 +142,11 @@ def test_create_nokia_router_lso_failure(
mock_netbox_create_device,
mock_provision_router,
router_creation_input_form_data,
router_role,
faker,
):
# Set up mock return values
mock_kentik_client.return_value = MockedKentikClient
mock_site = Site.from_subscription(router_creation_input_form_data["router_site"]).site
mock_v4 = faker.ipv4()
mock_v4_net = faker.ipv4(network=True)
......@@ -176,7 +184,7 @@ def test_create_nokia_router_lso_failure(
# Run workflow
product_id = get_product_id_by_name(ProductName.ROUTER)
initial_router_data = [{"product": product_id}, router_creation_input_form_data, {}]
initial_router_data = [{"product": product_id}, router_creation_input_form_data | {"router_role": router_role}, {}]
result, process_stat, step_log = run_workflow("create_router", initial_router_data)
result, step_log = assert_lso_interaction_success(result, process_stat, step_log)
......
......@@ -19,7 +19,7 @@ from test.workflows import (
@pytest.mark.workflow()
@patch("gso.services.lso_client._send_request")
@patch("gso.workflows.router.promote_p_to_pe.KentikClient")
@patch("gso.utils.workflow_steps.KentikClient")
def test_promote_p_to_pe_success(
mock_kentik_client,
mock_execute_playbook,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment