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

add test fixture

parent 8667a603
No related branches found
No related tags found
No related merge requests found
Pipeline #84756 passed
...@@ -12,7 +12,7 @@ import ansible_runner ...@@ -12,7 +12,7 @@ import ansible_runner
import requests import requests
import xmltodict import xmltodict
from dictdiffer import diff from dictdiffer import diff
from fastapi import status from fastapi import Response, status
from pydantic import BaseModel, HttpUrl from pydantic import BaseModel, HttpUrl
from lso import config from lso import config
...@@ -181,6 +181,7 @@ def run_playbook( ...@@ -181,6 +181,7 @@ def run_playbook(
extra_vars: dict[str, Any], extra_vars: dict[str, Any],
inventory: dict[str, Any] | str, inventory: dict[str, Any] | str,
callback: HttpUrl, callback: HttpUrl,
response: Response,
) -> PlaybookLaunchResponse: ) -> PlaybookLaunchResponse:
"""Run an Ansible playbook against a specified inventory. """Run an Ansible playbook against a specified inventory.
...@@ -193,10 +194,12 @@ def run_playbook( ...@@ -193,10 +194,12 @@ def run_playbook(
:rtype: :class:`PlaybookLaunchResponse` :rtype: :class:`PlaybookLaunchResponse`
""" """
if not Path.exists(playbook_path): if not Path.exists(playbook_path):
response.status_code = status.HTTP_404_NOT_FOUND
msg = f"Filename '{playbook_path}' does not exist." msg = f"Filename '{playbook_path}' does not exist."
return playbook_launch_error(msg) return playbook_launch_error(msg)
if not ansible_runner.utils.isinventory(inventory): if not ansible_runner.utils.isinventory(inventory):
response.status_code = status.HTTP_400_BAD_REQUEST
msg = "Invalid inventory provided. Should be a string, or JSON object." msg = "Invalid inventory provided. Should be a string, or JSON object."
return playbook_launch_error(msg) return playbook_launch_error(msg)
......
"""Routes for handling events related to the IP trunk service.""" """Routes for handling events related to the IP trunk service."""
from fastapi import APIRouter from fastapi import APIRouter, Response
from pydantic import BaseModel, HttpUrl from pydantic import BaseModel, HttpUrl
from lso.playbook import PlaybookLaunchResponse, get_playbook_path, run_playbook from lso.playbook import PlaybookLaunchResponse, get_playbook_path, run_playbook
...@@ -72,7 +72,7 @@ class IPTrunkDeleteParams(IPTrunkParams): ...@@ -72,7 +72,7 @@ class IPTrunkDeleteParams(IPTrunkParams):
@router.post("/") @router.post("/")
def provision_ip_trunk(params: IPTrunkProvisioningParams) -> PlaybookLaunchResponse: def provision_ip_trunk(params: IPTrunkProvisioningParams, response: Response) -> PlaybookLaunchResponse:
"""Launch a playbook to provision a new IP trunk service. """Launch a playbook to provision a new IP trunk service.
The response will contain either a job ID, or error information. The response will contain either a job ID, or error information.
...@@ -80,6 +80,7 @@ def provision_ip_trunk(params: IPTrunkProvisioningParams) -> PlaybookLaunchRespo ...@@ -80,6 +80,7 @@ def provision_ip_trunk(params: IPTrunkProvisioningParams) -> PlaybookLaunchRespo
:param params: The parameters that define the new subscription object that :param params: The parameters that define the new subscription object that
is to be deployed. is to be deployed.
:type params: :class:`IPTrunkProvisioningParams` :type params: :class:`IPTrunkProvisioningParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -99,15 +100,17 @@ def provision_ip_trunk(params: IPTrunkProvisioningParams) -> PlaybookLaunchRespo ...@@ -99,15 +100,17 @@ def provision_ip_trunk(params: IPTrunkProvisioningParams) -> PlaybookLaunchRespo
f"{params.subscription['iptrunk']['iptrunk_sides'][1]['iptrunk_side_node']['router_fqdn']}\n", f"{params.subscription['iptrunk']['iptrunk_sides'][1]['iptrunk_side_node']['router_fqdn']}\n",
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback, callback=params.callback,
response=response,
) )
@router.put("/") @router.put("/")
def modify_ip_trunk(params: IPTrunkModifyParams) -> PlaybookLaunchResponse: def modify_ip_trunk(params: IPTrunkModifyParams, response: Response) -> PlaybookLaunchResponse:
"""Launch a playbook that modifies an existing IP trunk service. """Launch a playbook that modifies an existing IP trunk service.
:param params: The parameters that define the change in configuration. :param params: The parameters that define the change in configuration.
:type params: :class:`IPTrunkModifyParams` :type params: :class:`IPTrunkModifyParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -127,16 +130,18 @@ def modify_ip_trunk(params: IPTrunkModifyParams) -> PlaybookLaunchResponse: ...@@ -127,16 +130,18 @@ def modify_ip_trunk(params: IPTrunkModifyParams) -> PlaybookLaunchResponse:
f"{params.subscription['iptrunk']['iptrunk_sides'][1]['iptrunk_side_node']['router_fqdn']}\n", f"{params.subscription['iptrunk']['iptrunk_sides'][1]['iptrunk_side_node']['router_fqdn']}\n",
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback, callback=params.callback,
response=response,
) )
@router.delete("/") @router.delete("/")
def delete_ip_trunk(params: IPTrunkDeleteParams) -> PlaybookLaunchResponse: def delete_ip_trunk(params: IPTrunkDeleteParams, response: Response) -> PlaybookLaunchResponse:
"""Launch a playbook that deletes an existing IP trunk service. """Launch a playbook that deletes an existing IP trunk service.
:param params: Parameters that define the subscription that should get :param params: Parameters that define the subscription that should get
terminated. terminated.
:type params: :class:`IPTrunkDeleteParams` :type params: :class:`IPTrunkDeleteParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -156,16 +161,18 @@ def delete_ip_trunk(params: IPTrunkDeleteParams) -> PlaybookLaunchResponse: ...@@ -156,16 +161,18 @@ def delete_ip_trunk(params: IPTrunkDeleteParams) -> PlaybookLaunchResponse:
f"{params.subscription['iptrunk']['iptrunk_sides'][1]['iptrunk_side_node']['router_fqdn']}\n", f"{params.subscription['iptrunk']['iptrunk_sides'][1]['iptrunk_side_node']['router_fqdn']}\n",
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback, callback=params.callback,
response=response,
) )
@router.post("/perform_check") @router.post("/perform_check")
def check_ip_trunk(params: IPTrunkCheckParams) -> PlaybookLaunchResponse: def check_ip_trunk(params: IPTrunkCheckParams, response: Response) -> PlaybookLaunchResponse:
"""Launch a playbook that performs a check on an IP trunk service instance. """Launch a playbook that performs a check on an IP trunk service instance.
:param params: Parameters that define the check that is going to be :param params: Parameters that define the check that is going to be
executed, including on which relevant subscription. executed, including on which relevant subscription.
:type params: :class:`IPTrunkCheckParams` :type params: :class:`IPTrunkCheckParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -178,17 +185,19 @@ def check_ip_trunk(params: IPTrunkCheckParams) -> PlaybookLaunchResponse: ...@@ -178,17 +185,19 @@ def check_ip_trunk(params: IPTrunkCheckParams) -> PlaybookLaunchResponse:
inventory=params.subscription["iptrunk"]["iptrunk_sides"][0]["iptrunk_side_node"]["router_fqdn"], inventory=params.subscription["iptrunk"]["iptrunk_sides"][0]["iptrunk_side_node"]["router_fqdn"],
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback, callback=params.callback,
response=response,
) )
@router.post("/migrate") @router.post("/migrate")
def migrate_ip_trunk(params: IPTrunkMigrationParams) -> PlaybookLaunchResponse: def migrate_ip_trunk(params: IPTrunkMigrationParams, response: Response) -> PlaybookLaunchResponse:
"""Launch a playbook to provision a new IP trunk service. """Launch a playbook to provision a new IP trunk service.
The response will contain either a job ID, or error information. 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. :param params: The parameters that define the new subscription object that is to be migrated.
:type params: :class:`IPTrunkMigrationParams` :type params: :class:`IPTrunkMigrationParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -212,4 +221,5 @@ def migrate_ip_trunk(params: IPTrunkMigrationParams) -> PlaybookLaunchResponse: ...@@ -212,4 +221,5 @@ def migrate_ip_trunk(params: IPTrunkMigrationParams) -> PlaybookLaunchResponse:
f"{params.new_side['new_node']['router']['router_fqdn']}\n", f"{params.new_side['new_node']['router']['router_fqdn']}\n",
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback, callback=params.callback,
response=response,
) )
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
from typing import Any from typing import Any
from fastapi import APIRouter from fastapi import APIRouter, Response
from pydantic import BaseModel, HttpUrl from pydantic import BaseModel, HttpUrl
from lso.playbook import PlaybookLaunchResponse, get_playbook_path, run_playbook from lso.playbook import PlaybookLaunchResponse, get_playbook_path, run_playbook
...@@ -29,12 +29,13 @@ class PlaybookRunParams(BaseModel): ...@@ -29,12 +29,13 @@ class PlaybookRunParams(BaseModel):
@router.post("/") @router.post("/")
def run_playbook_endpoint(params: PlaybookRunParams) -> PlaybookLaunchResponse: def run_playbook_endpoint(params: PlaybookRunParams, response: Response) -> PlaybookLaunchResponse:
"""Launch an Ansible playbook to modify or deploy a subscription instance. """Launch an Ansible playbook to modify or deploy a subscription instance.
The response will contain either a job ID, or error information. The response will contain either a job ID, or error information.
:param params :class:`PlaybookRunParams`: Parameters for executing a playbook. :param params :class:`PlaybookRunParams`: Parameters for executing a playbook.
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -43,4 +44,5 @@ def run_playbook_endpoint(params: PlaybookRunParams) -> PlaybookLaunchResponse: ...@@ -43,4 +44,5 @@ def run_playbook_endpoint(params: PlaybookRunParams) -> PlaybookLaunchResponse:
extra_vars=params.extra_vars, extra_vars=params.extra_vars,
inventory=params.inventory, inventory=params.inventory,
callback=params.callback, callback=params.callback,
response=response,
) )
"""Routes for handling device/base_config-related requests.""" """Routes for handling device/base_config-related requests."""
from fastapi import APIRouter from fastapi import APIRouter, Response
from pydantic import BaseModel, HttpUrl from pydantic import BaseModel, HttpUrl
from lso import playbook from lso import playbook
...@@ -35,11 +35,12 @@ class NodeProvisioningParams(BaseModel): ...@@ -35,11 +35,12 @@ class NodeProvisioningParams(BaseModel):
@router.post("/") @router.post("/")
async def provision_node(params: NodeProvisioningParams) -> playbook.PlaybookLaunchResponse: async def provision_node(params: NodeProvisioningParams, response: Response) -> playbook.PlaybookLaunchResponse:
"""Launch a playbook to provision a new node. The response will contain either a job id or error information. """Launch a playbook to provision a new node. The response will contain either a job id or error information.
:param params: Parameters for provisioning a new node :param params: Parameters for provisioning a new node
:type params: :class:`NodeProvisioningParams` :type params: :class:`NodeProvisioningParams`
:param Response response: A FastAPI response used for returning error codes if needed
:return: Response from the Ansible runner, including a run ID. :return: Response from the Ansible runner, including a run ID.
:rtype: :class:`lso.playbook.PlaybookLaunchResponse` :rtype: :class:`lso.playbook.PlaybookLaunchResponse`
""" """
...@@ -55,4 +56,5 @@ async def provision_node(params: NodeProvisioningParams) -> playbook.PlaybookLau ...@@ -55,4 +56,5 @@ async def provision_node(params: NodeProvisioningParams) -> playbook.PlaybookLau
inventory=f"{params.subscription['router']['router_fqdn']}", inventory=f"{params.subscription['router']['router_fqdn']}",
extra_vars=extra_vars, extra_vars=extra_vars,
callback=params.callback, callback=params.callback,
response=response,
) )
...@@ -4,6 +4,7 @@ import tempfile ...@@ -4,6 +4,7 @@ import tempfile
from collections.abc import Callable, Generator from collections.abc import Callable, Generator
from io import StringIO from io import StringIO
from typing import Any from typing import Any
from unittest.mock import patch
import pytest import pytest
from faker import Faker from faker import Faker
...@@ -55,3 +56,12 @@ def client(data_config_filename: str) -> TestClient: ...@@ -55,3 +56,12 @@ def client(data_config_filename: str) -> TestClient:
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def faker() -> Faker: def faker() -> Faker:
return Faker(locale="en_GB") return Faker(locale="en_GB")
@pytest.fixture(scope="session", autouse=True)
def path_exists() -> bool:
"""A patch that prevents all test requests from failing since the playbook file does not exist on the filesystem."""
with patch("pathlib.Path.exists") as mock_patch:
mock_patch.return_value = True
yield mock_patch
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment