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

add migration endpoint for IP trunk, with test

parent 6fe30c22
No related branches found
No related tags found
1 merge request!44Feature/ip trunk migration
Pipeline #83914 passed
......@@ -42,6 +42,18 @@ class IPTrunkModifyParams(IPTrunkParams):
old_subscription: dict
class IPTrunkMigrationParams(IPTrunkParams):
"""Additional parameters for migrating an IPTrunk."""
#: Whether this playbook execution should be a dry run, or run for real. Defaults to ``True`` for obvious reasons,
#: also making it an optional parameter.
dry_run: Optional[bool] = True
#: The new Router that this IP Trunk is migrating to.
new_side: dict
#: An Ansible playbook verb that is passed along for indicating the phase of the migration that is performed.
verb: str
class IPTrunkCheckParams(IPTrunkParams):
"""Additional parameters for checking an IPtrunk."""
......@@ -173,7 +185,38 @@ def check_ip_trunk(params: IPTrunkCheckParams) -> PlaybookLaunchResponse:
return run_playbook(
playbook_path=path.join(config_params.ansible_playbooks_root_dir, "iptrunks_checks.yaml"),
inventory=params.subscription["iptrunk"]["iptrunk_sideA_node"]["router_fqdn"],
inventory=params.subscription["iptrunk"]["iptrunk_sides"][0]["iptrunk_side_node"]["router_fqdn"],
extra_vars=extra_vars,
callback=params.callback,
)
@router.post("/migrate")
def migrate_ip_trunk(params: IPTrunkMigrationParams) -> PlaybookLaunchResponse:
"""Launch a playbook to provision a new IP trunk service.
The response will contain either a job ID, or error information.
:param params: The parameters that define the new subscription object that is to be migrated.
:type params: :class:`IPTrunkMigrationParams`
:return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse`
"""
extra_vars = {
"wfo_trunk_json": params.subscription,
"new_side": params.new_side,
"dry_run": str(params.dry_run),
"verb": params.verb,
}
return run_playbook(
playbook_path=path.join(config_params.ansible_playbooks_root_dir, "iptrunks.yaml"),
inventory=str(
params.subscription["iptrunk"]["iptrunk_sides"][0]["iptrunk_side_node"]["router_fqdn"]
+ "\n"
+ params.subscription["iptrunk"]["iptrunk_sides"][1]["iptrunk_side_node"]["router_fqdn"]
+ "\n"
),
extra_vars=extra_vars,
callback=params.callback,
)
......@@ -16,80 +16,137 @@ _SUBSCRIPTION_OBJECT = {
"iptrunk_description": "A description for this trunk",
"iptrunk_isis_metric": 9000,
"iptrunk_minimum_links": 1,
"iptrunk_sideA_ae_geant_a_sid": "GA-00000",
"iptrunk_sideA_ae_iface": "ae0",
"iptrunk_sideA_ae_members": ["ge-0/0/0"],
"iptrunk_sideA_ae_members_description": ["this is the first interface on side A"],
"iptrunk_sideA_node": {
"router_fqdn": "rtx.city.country.geant.net",
"router_ias_lt_ipv4_network": "1.0.0.0/31",
"router_ias_lt_ipv6_network": "dead:beef::3/126",
"router_lo_ipv4_address": "1.0.0.0",
"router_lo_ipv6_address": "dead:beef::",
"router_lo_iso_address": "00.0000.0000.0000.0000.0000.00",
"router_role": "p",
"router_si_ipv4_network": "0.0.1.0/31",
"router_site": {
"name": "SiteBlock",
"iptrunk_sides": [
{
"name": "IptrunkSideBlock",
"label": None,
"site_city": "City",
"site_name": "city",
"site_tier": "1",
"site_country": "Country",
"site_latitude": 0.0,
"site_longitude": 0.0,
"site_internal_id": 0,
"site_country_code": "XX",
"owner_subscription_id": "0",
"site_bgp_community_id": 0,
"subscription_instance_id": "0",
"site_ts_address": "127.0.0.2",
"iptrunk_side_node": {
"name": "RouterBlock",
"label": None,
"router_fqdn": "rt1.city.country.geant.net",
"router_role": "p",
"router_site": {
"name": "SiteBlock",
"label": None,
"site_city": "City",
"site_name": "city",
"site_tier": "1",
"site_country": "Country",
"site_latitude": 1,
"site_longitude": 1,
"site_ts_address": "0.0.0.0",
"site_internal_id": 1,
"site_country_code": "xxx",
"owner_subscription_id": "b5146e62-da79-4791-b703-d03b0ebeebf8",
"site_bgp_community_id": 1,
"subscription_instance_id": "039e03e5-5c09-4236-8d28-cd569e04315e",
},
"router_vendor": "juniper",
"router_ts_port": 22222,
"router_access_via_ts": True,
"owner_subscription_id": "4a0001f1-459d-46f5-9a85-b8177e1bbc1b",
"router_lo_iso_address": "49.51e5.0001.0620.4009.6014.00",
"router_lo_ipv4_address": "0.0.0.0",
"router_lo_ipv6_address": "::",
"router_si_ipv4_network": "0.0.0.0/31",
"router_is_ias_connected": True,
"subscription_instance_id": "2242883e-a581-4ce1-919c-9c986ded57f6",
"router_ias_lt_ipv4_network": "0.0.0.0/31",
"router_ias_lt_ipv6_network": "::/126",
},
"iptrunk_side_ae_iface": "ae1",
"owner_subscription_id": "c9ddbe14-e107-4749-82ac-e22091cdb132",
"iptrunk_side_ae_members": ["ge-0/0/0", "ge-0/0/1"],
"subscription_instance_id": "6276fac5-9d31-4c9a-9247-48f02a19f151",
"iptrunk_side_ae_geant_a_sid": "SID-11112",
"iptrunk_side_ae_members_description": ["first one", "second one"],
},
"router_ts_port": 22,
"router_vendor": "vendor",
"owner_subscription_id": "0",
"subscription_instance_id": "0",
},
"iptrunk_sideB_ae_geant_a_sid": "GA-00002",
"iptrunk_sideB_ae_iface": "ae0",
"iptrunk_sideB_ae_members": ["ge-0/0/0"],
"iptrunk_sideB_ae_members_description": ["this is the first interface side B"],
"iptrunk_sideB_node": {
"router_fqdn": "rtx.town.country.geant.net",
"router_ias_lt_ipv4_network": "0.0.0.0/31",
"router_ias_lt_ipv6_network": "deaf:beef::1/126",
"router_lo_ipv4_address": "0.0.0.0",
"router_lo_ipv6_address": "dead:beef::2",
"router_lo_iso_address": "00.0000.0000.0000.0000.0000.00",
"router_role": "p",
"router_si_ipv4_network": "0.1.0.0/31",
"router_site": {
"name": "SiteBlock",
{
"name": "IptrunkSideBlock",
"label": None,
"site_city": "Town",
"site_name": "town",
"site_tier": "1",
"site_country": "Country",
"site_latitude": 0.0,
"site_longitude": 0.0,
"site_internal_id": 1,
"site_country_code": "xx",
"owner_subscription_id": "0",
"site_bgp_community_id": 2,
"subscription_instance_id": "0",
"site_ts_address": "127.0.0.2",
"iptrunk_side_node": {
"name": "RouterBlock",
"label": None,
"router_fqdn": "rt2.city.country.geant.net",
"router_role": "p",
"router_site": {
"name": "SiteBlock",
"label": None,
"site_city": "City",
"site_name": "city",
"site_tier": "1",
"site_country": "Country",
"site_latitude": 1,
"site_longitude": 1,
"site_ts_address": "0.0.0.0",
"site_internal_id": 2,
"site_country_code": "country",
"owner_subscription_id": "93cba8dc-7424-44c0-8872-13159df93042",
"site_bgp_community_id": 2,
"subscription_instance_id": "6bf4f274-6496-438d-9dba-9c3984d0ec07",
},
"router_vendor": "juniper",
"router_ts_port": 11111,
"router_access_via_ts": True,
"owner_subscription_id": "9cb1fc7d-9608-42ce-aacc-2a97f9620a91",
"router_lo_iso_address": "49.51e5.0001.0620.4009.6066.00",
"router_lo_ipv4_address": "0.0.0.0",
"router_lo_ipv6_address": "::",
"router_si_ipv4_network": "0.0.0.0/31",
"router_is_ias_connected": True,
"subscription_instance_id": "6d09394e-658b-4e55-8b1f-8b812d59f5a1",
"router_ias_lt_ipv4_network": "0.0.0.0/31",
"router_ias_lt_ipv6_network": "::/126",
},
"iptrunk_side_ae_iface": "ae1",
"owner_subscription_id": "c9ddbe14-e107-4749-82ac-e22091cdb132",
"iptrunk_side_ae_members": ["ge-0/0/0", "ge-0/0/1"],
},
"router_ts_port": 22,
"router_vendor": "vendor",
"owner_subscription_id": "0",
"subscription_instance_id": "0",
},
"iptrunk_speed": "1",
"iptrunk_type": "Dark_fiber",
],
},
"status": "provisioning",
}
_MIGRATION_OBJECT = {
"new_node": {
"name": "RouterBlock",
"label": None,
"router_fqdn": "rt2.city.country.geant.net",
"router_role": "p",
"router_site": {
"name": "SiteBlock",
"label": None,
"site_city": "City",
"site_name": "city",
"site_tier": "1",
"site_country": "Country",
"site_latitude": 1,
"site_longitude": 1,
"site_ts_address": "0.0.0.0",
"site_internal_id": 2,
"site_country_code": "country",
"owner_subscription_id": "93cba8dc-7424-44c0-8872-13159df93042",
"site_bgp_community_id": 2,
"subscription_instance_id": "6bf4f274-6496-438d-9dba-9c3984d0ec07",
},
"router_vendor": "juniper",
"router_ts_port": 11111,
"router_access_via_ts": True,
"owner_subscription_id": "9cb1fc7d-9608-42ce-aacc-2a97f9620a91",
"router_lo_iso_address": "49.51e5.0001.0620.4009.6066.00",
"router_lo_ipv4_address": "0.0.0.0",
"router_lo_ipv6_address": "::",
"router_si_ipv4_network": "0.0.0.0/31",
"router_is_ias_connected": True,
"subscription_instance_id": "6d09394e-658b-4e55-8b1f-8b812d59f5a1",
"router_ias_lt_ipv4_network": "0.0.0.0/31",
"router_ias_lt_ipv6_network": "::/126",
},
"new_lag_interface": "ae1",
"new_lag_member_interfaces": ["ge-0/0/0", "ge-0/0/1"],
"replace_index": 0,
}
@responses.activate
def test_ip_trunk_provisioning(client: TestClient) -> None:
......@@ -158,3 +215,28 @@ def test_ip_trunk_deletion(client: TestClient) -> None:
responses.assert_call_count(TEST_CALLBACK_URL, 1)
assert response["status"] == "ok"
@responses.activate
def test_ip_trunk_migration(client: TestClient) -> None:
responses.put(url=TEST_CALLBACK_URL, status=204)
params = {
"callback": TEST_CALLBACK_URL,
"dry_run": True,
"verb": "migrate",
"subscription": _SUBSCRIPTION_OBJECT,
"new_side": _MIGRATION_OBJECT,
}
with patch("lso.playbook.ansible_runner.run", new=test_ansible_runner_run) as _:
rv = client.request(url="/api/ip_trunk/migrate", method=responses.POST, json=params)
assert rv.status_code == 200
response = rv.json()
# Wait a second for the run to finish
time.sleep(1)
jsonschema.validate(response, PlaybookLaunchResponse.model_json_schema())
responses.assert_call_count(TEST_CALLBACK_URL, 1)
assert response["status"] == "ok"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment