diff --git a/lso/routes/common.py b/lso/routes/common.py index 0f53189a678d803a19b23d6a207a9b14e5f96a8a..7d72605807d11e839fff22301d4eef2d0759bc53 100644 --- a/lso/routes/common.py +++ b/lso/routes/common.py @@ -7,8 +7,8 @@ from pydantic import BaseModel class PlaybookLaunchResponse(BaseModel): status: str # always 'OK' or 'ERROR' - job_id: Optional[str] = None # only if 'OK' - info: Optional[str] = None # only if 'ERROR' + job_id: str = '' + info: str = '' def playbook_launch_success(job_id: str) -> PlaybookLaunchResponse: diff --git a/lso/routes/device.py b/lso/routes/device.py index fd7e42ae293dcf99f4785915da29f51ecea69a70..dfa18936a38bcb08b7d1feab74315f331c38f67a 100644 --- a/lso/routes/device.py +++ b/lso/routes/device.py @@ -1,19 +1,41 @@ """ Routes for handling device/base_config-related requests """ +import ipaddress +from typing import Optional + from fastapi import APIRouter import pydantic from lso.routes import common -from gso.products.product_types.device import DeviceBlockProvisioning router = APIRouter() +class InterfaceAddress(pydantic.BaseModel): + v4: Optional[ipaddress.IPv4Address] = None + v6: Optional[ipaddress.IPv6Address] = None + + +class InterfaceNetwork(pydantic.BaseModel): + v4: Optional[ipaddress.IPv4Network] = None + v6: Optional[ipaddress.IPv6Network] = None + + +class DeviceParams(pydantic.BaseModel): + fqdn: str # TODO: add some validation + lo_address: Optional[InterfaceAddress] = None + lo_iso_address: Optional[str] = None + si_ipv4_network: Optional[ipaddress.IPv4Network] = None + ias_lt_network: Optional[InterfaceNetwork] = None + site_country_code: Optional[str] = None + snmp_location: Optional[str] = None + + class NodeProvisioningParams(pydantic.BaseModel): # TODO: define and document callback spec callback: pydantic.HttpUrl - data: DeviceBlockProvisioning + device: DeviceParams @router.post('/') @@ -26,20 +48,19 @@ async def provision_node(params: NodeProvisioningParams) \ :param device: NodeProvisioningParams :return: PlaybookLaunchResponse """ - device = params.data.device extra_vars = { - 'lo_ipv4_address': str(device.lo_ipv4_address), - 'lo_ipv6_address': str(device.lo_ipv6_address), - 'lo_iso_address': device.lo_iso_address, - 'snmp_location': device.snmp_location, - 'si_ipv4_network': str(device.si_ipv4_network), - 'lt_ipv4_network': str(device.ias_lt_ipv4_network), - 'lt_ipv6_network': str(device.ias_lt_ipv6_network), - 'site_country_code': device.site_country_code, + 'lo_ipv4_address': str(params.device.lo_address.v4), + 'lo_ipv6_address': str(params.device.lo_address.v6), + 'lo_iso_address': params.device.lo_iso_address, + 'snmp_location': params.device.snmp_location, + 'si_ipv4_network': str(params.device.si_ipv4_network), + 'lt_ipv4_network': str(params.device.ias_lt_network.v4), + 'lt_ipv6_network': str(params.device.ias_lt_network.v6), + 'site_country_code': params.device.site_country_code, 'verb': 'deploy'} return common.run_playbook( playbook='base_config.yaml', - inventory=device.fqdn, + inventory=params.device.fqdn, extra_vars=extra_vars, callback=params.callback) diff --git a/requirements.txt b/requirements.txt index 7f357c7ad3f336c42b9e91974b4fa5673af51a9a..cb38f2f05f28e58e2346276912ac2ef73cd4305b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,6 @@ jsonschema fastapi pydantic ansible-runner -geant-service-orchestrator==0.1.dev253 uvicorn[standard] httpx diff --git a/setup.py b/setup.py index dccbe8ba4ac1f4ebe0b66498ef6863109d13fefd..df2c1a68601281abbd7f76d10cfb03a700dd49ac 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,6 @@ setup( 'jsonschema', 'fastapi', 'pydantic', - 'ansible-runner', - 'geant-service-orchestrator==0.1.dev253' + 'ansible-runner' ] ) diff --git a/test/test_device_routes.py b/test/test_device_routes.py index f8d2e7a248e0ea823a19386cae96993f6a2d4aeb..301827b84114f0f08a0ae27d356bd152cd54596b 100644 --- a/test/test_device_routes.py +++ b/test/test_device_routes.py @@ -1,4 +1,6 @@ import jsonschema +import time +from unittest.mock import patch from lso.routes.device import NodeProvisioningParams from lso.routes.common import PlaybookLaunchResponse @@ -6,25 +8,26 @@ from lso.routes.common import PlaybookLaunchResponse def test_nominal_node_provisioning(client): params = { - 'callback': 'http://fqdn:12345', - 'data': { - 'device': { - 'fqdn': 'test.example.com', - 'lo_ipv4_address': '1.2.3.4', - 'lo_ipv6_address': '2001:db8::1', - 'lo_iso_address': '1.2.3.4.5.6', - 'snmp_location': 'city,country[1.2,3.4]', - 'si_ipv4_network': '1.2.3.0/24', - 'ias_lt_ipv4_network': '1.2.3.0/24', - 'ias_lt_ipv6_network': '2001:db8::/64', - 'site_country_code': 'FR' - } + 'callback': 'http://fqdn.xyz.abc:12345', + 'device': { + 'fqdn': 'bogus.fqdn.org', + 'lo_address': {'v4': '1.2.3.4', 'v6': '2001:db8::1'}, + 'lo_iso_address': '1.2.3.4.5.6', + 'snmp_location': 'city,country[1.2,3.4]', + 'si_ipv4_network': '1.2.3.0/24', + 'ias_lt_network': {'v4': '1.2.3.0/24', 'v6': '2001:db8::/64'}, + 'site_country_code': 'abcdefg' } } - rv = client.post(f'/api/device', json=params) - assert rv.status_code == 200 + with patch('lso.routes.common.ansible_runner.run') as _run: + rv = client.post(f'/api/device', json=params) + # rv = client.post(f'/api/device', json=payload.json()) + assert rv.status_code == 200 + response = rv.json() + # give a second for the run thread to finish + time.sleep(1) + _run.assert_called() - response = rv.json() jsonschema.validate(response, PlaybookLaunchResponse.schema()) assert response['status'] == 'OK'