Skip to content
Snippets Groups Projects
Commit a071236e authored by Erik Reid's avatar Erik Reid
Browse files

use locally defined pydantic models

parent 7b40e942
No related branches found
No related tags found
1 merge request!9Feature/nat 146 device endpoint skeleton
...@@ -7,8 +7,8 @@ from pydantic import BaseModel ...@@ -7,8 +7,8 @@ from pydantic import BaseModel
class PlaybookLaunchResponse(BaseModel): class PlaybookLaunchResponse(BaseModel):
status: str # always 'OK' or 'ERROR' status: str # always 'OK' or 'ERROR'
job_id: Optional[str] = None # only if 'OK' job_id: str = ''
info: Optional[str] = None # only if 'ERROR' info: str = ''
def playbook_launch_success(job_id: str) -> PlaybookLaunchResponse: def playbook_launch_success(job_id: str) -> PlaybookLaunchResponse:
......
""" """
Routes for handling device/base_config-related requests Routes for handling device/base_config-related requests
""" """
import ipaddress
from typing import Optional
from fastapi import APIRouter from fastapi import APIRouter
import pydantic import pydantic
from lso.routes import common from lso.routes import common
from gso.products.product_types.device import DeviceBlockProvisioning
router = APIRouter() 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): class NodeProvisioningParams(pydantic.BaseModel):
# TODO: define and document callback spec # TODO: define and document callback spec
callback: pydantic.HttpUrl callback: pydantic.HttpUrl
data: DeviceBlockProvisioning device: DeviceParams
@router.post('/') @router.post('/')
...@@ -26,20 +48,19 @@ async def provision_node(params: NodeProvisioningParams) \ ...@@ -26,20 +48,19 @@ async def provision_node(params: NodeProvisioningParams) \
:param device: NodeProvisioningParams :param device: NodeProvisioningParams
:return: PlaybookLaunchResponse :return: PlaybookLaunchResponse
""" """
device = params.data.device
extra_vars = { extra_vars = {
'lo_ipv4_address': str(device.lo_ipv4_address), 'lo_ipv4_address': str(params.device.lo_address.v4),
'lo_ipv6_address': str(device.lo_ipv6_address), 'lo_ipv6_address': str(params.device.lo_address.v6),
'lo_iso_address': device.lo_iso_address, 'lo_iso_address': params.device.lo_iso_address,
'snmp_location': device.snmp_location, 'snmp_location': params.device.snmp_location,
'si_ipv4_network': str(device.si_ipv4_network), 'si_ipv4_network': str(params.device.si_ipv4_network),
'lt_ipv4_network': str(device.ias_lt_ipv4_network), 'lt_ipv4_network': str(params.device.ias_lt_network.v4),
'lt_ipv6_network': str(device.ias_lt_ipv6_network), 'lt_ipv6_network': str(params.device.ias_lt_network.v6),
'site_country_code': device.site_country_code, 'site_country_code': params.device.site_country_code,
'verb': 'deploy'} 'verb': 'deploy'}
return common.run_playbook( return common.run_playbook(
playbook='base_config.yaml', playbook='base_config.yaml',
inventory=device.fqdn, inventory=params.device.fqdn,
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback) callback=params.callback)
...@@ -4,7 +4,6 @@ jsonschema ...@@ -4,7 +4,6 @@ jsonschema
fastapi fastapi
pydantic pydantic
ansible-runner ansible-runner
geant-service-orchestrator==0.1.dev253
uvicorn[standard] uvicorn[standard]
httpx httpx
......
...@@ -12,7 +12,6 @@ setup( ...@@ -12,7 +12,6 @@ setup(
'jsonschema', 'jsonschema',
'fastapi', 'fastapi',
'pydantic', 'pydantic',
'ansible-runner', 'ansible-runner'
'geant-service-orchestrator==0.1.dev253'
] ]
) )
import jsonschema import jsonschema
import time
from unittest.mock import patch
from lso.routes.device import NodeProvisioningParams from lso.routes.device import NodeProvisioningParams
from lso.routes.common import PlaybookLaunchResponse from lso.routes.common import PlaybookLaunchResponse
...@@ -6,25 +8,26 @@ from lso.routes.common import PlaybookLaunchResponse ...@@ -6,25 +8,26 @@ from lso.routes.common import PlaybookLaunchResponse
def test_nominal_node_provisioning(client): def test_nominal_node_provisioning(client):
params = { params = {
'callback': 'http://fqdn:12345', 'callback': 'http://fqdn.xyz.abc:12345',
'data': { 'device': {
'device': { 'fqdn': 'bogus.fqdn.org',
'fqdn': 'test.example.com', 'lo_address': {'v4': '1.2.3.4', 'v6': '2001:db8::1'},
'lo_ipv4_address': '1.2.3.4', 'lo_iso_address': '1.2.3.4.5.6',
'lo_ipv6_address': '2001:db8::1', 'snmp_location': 'city,country[1.2,3.4]',
'lo_iso_address': '1.2.3.4.5.6', 'si_ipv4_network': '1.2.3.0/24',
'snmp_location': 'city,country[1.2,3.4]', 'ias_lt_network': {'v4': '1.2.3.0/24', 'v6': '2001:db8::/64'},
'si_ipv4_network': '1.2.3.0/24', 'site_country_code': 'abcdefg'
'ias_lt_ipv4_network': '1.2.3.0/24',
'ias_lt_ipv6_network': '2001:db8::/64',
'site_country_code': 'FR'
}
} }
} }
rv = client.post(f'/api/device', json=params) with patch('lso.routes.common.ansible_runner.run') as _run:
assert rv.status_code == 200 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()) jsonschema.validate(response, PlaybookLaunchResponse.schema())
assert response['status'] == 'OK' 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