diff --git a/microservices/kubeApi/routers/routes.py b/microservices/kubeApi/routers/routes.py index ef1b208..1a87047 100644 --- a/microservices/kubeApi/routers/routes.py +++ b/microservices/kubeApi/routers/routes.py @@ -1,6 +1,7 @@ import uuid import base64 from fastapi import APIRouter, HTTPException, Depends, Request +from fastapi.responses import JSONResponse from pydantic.main import BaseModel from starlette.responses import Response from clients.ocp_routes import get_gwa_ocp_routes, kubectl_delete, prepare_apply_routes, apply_routes, prepare_mismatched_routes, delete_routes @@ -184,6 +185,9 @@ async def verify_and_create_routes(namespace: str, request: Request): # this info from ns_attributes ns_template_version = "v2" + inserted_count = 0 + deleted_count = 0 + try: if len(insert_batch) > 0: source_folder = "%s/%s-%s" % ('/tmp/sync', f'{datetime.now():%Y%m%d%H%M%S}', secrets.token_hex(5)) @@ -194,22 +198,20 @@ async def verify_and_create_routes(namespace: str, request: Request): for route in insert_batch: overrides = {} if 'sessionCookieEnabled' in route and route['sessionCookieEnabled']: - overrides['aps.route.session.cookie.enabled'] = [ route['host'] ] + overrides['aps.route.session.cookie.enabled'] = [route['host']] + route_count = prepare_apply_routes(namespace, route['selectTag'], [ route['host']], source_folder, route["dataPlane"], ns_template_version, overrides) + logger.debug("[%s] - Prepared %d routes" % (namespace, route_count)) apply_routes(source_folder) logger.debug("[%s] - Applied %d routes" % (namespace, route_count)) + + inserted_count += route_count except Exception as ex: traceback.print_exc() logger.error("Error creating routes. %s" % (ex)) raise HTTPException(status_code=400, detail="Error creating routes. %s" % (ex)) - except SystemExit as ex: - raise ex - except BaseException: - traceback.print_exc() - logger.error("Error creating routes. %s" % (sys.exc_info()[0])) - raise HTTPException(status_code=400, detail="Error creating routes. %s" % (sys.exc_info()[0])) if len(delete_batch) > 0: logger.debug("Deleting %s routes" % (len(delete_batch))) @@ -217,18 +219,17 @@ async def verify_and_create_routes(namespace: str, request: Request): try: kubectl_delete('route', route["name"]) logger.debug("[%s] - Deleted route %s" % (namespace, route["name"])) + deleted_count += 1 except Exception as ex: traceback.print_exc() logger.error("Failed deleting route %s" % route["name"]) raise HTTPException(status_code=400, detail=str(ex)) - except SystemExit as ex: - raise ex - except BaseException: - traceback.print_exc() - logger.error("Failed deleting route %s" % route["name"]) - raise HTTPException(status_code=400, detail=str(sys.exc_info()[0])) - return Response(status_code=200, content='{"message": "synced"}') + return JSONResponse(status_code=200, content={ + "message": "synced", + "inserted_count": inserted_count, + "deleted_count": deleted_count + }) def get_data_plane(ns_attributes): default_data_plane = settings.defaultDataPlane diff --git a/microservices/kubeApi/tests/routers/test_bulk_sync.py b/microservices/kubeApi/tests/routers/test_bulk_sync.py index d0e6aa8..2eca86d 100644 --- a/microservices/kubeApi/tests/routers/test_bulk_sync.py +++ b/microservices/kubeApi/tests/routers/test_bulk_sync.py @@ -35,3 +35,6 @@ def test_bulk_sync(client): response = client.post('/namespaces/examplens/routes/sync', json=data) assert response.status_code == 200 assert response.json()['message'] == 'synced' + assert response.json()['inserted_count'] == 0 + assert response.json()['deleted_count'] == 0 + diff --git a/microservices/kubeApi/tests/routers/test_bulk_sync_new_route.py b/microservices/kubeApi/tests/routers/test_bulk_sync_new_route.py index 6208970..9dc7caa 100644 --- a/microservices/kubeApi/tests/routers/test_bulk_sync_new_route.py +++ b/microservices/kubeApi/tests/routers/test_bulk_sync_new_route.py @@ -78,4 +78,6 @@ def test_bulk_sync_new_route(client): response = client.post('/namespaces/examplens/routes/sync', json=data) assert response.status_code == 200 assert response.json()['message'] == 'synced' + assert response.json()['inserted_count'] == 1 + diff --git a/microservices/kubeApi/tests/routers/test_bulk_sync_override.py b/microservices/kubeApi/tests/routers/test_bulk_sync_override.py index 16f9d2f..b325ff5 100644 --- a/microservices/kubeApi/tests/routers/test_bulk_sync_override.py +++ b/microservices/kubeApi/tests/routers/test_bulk_sync_override.py @@ -76,4 +76,4 @@ def test_bulk_sync_new_route(client): response = client.post('/namespaces/examplens/routes/sync', json=data) assert response.status_code == 200 assert response.json()['message'] == 'synced' - + assert response.json()['inserted_count'] == 1 diff --git a/microservices/kubeApi/tests/routers/test_bulk_sync_session_cookie.py b/microservices/kubeApi/tests/routers/test_bulk_sync_session_cookie.py index 69779ce..b1d1191 100644 --- a/microservices/kubeApi/tests/routers/test_bulk_sync_session_cookie.py +++ b/microservices/kubeApi/tests/routers/test_bulk_sync_session_cookie.py @@ -1,6 +1,6 @@ from unittest import mock -def test_bulk_sync(client): +def test_bulk_sync_session_cookie(client): with mock.patch("routers.routes.get_gwa_ocp_routes") as call: call.return_value = [{ "metadata": { @@ -18,7 +18,6 @@ def test_bulk_sync(client): } }] - with mock.patch("routers.routes.prepare_apply_routes") as call_apply: call_apply.return_value = 0 @@ -35,3 +34,47 @@ def test_bulk_sync(client): response = client.post('/namespaces/examplens/routes/sync', json=data) assert response.status_code == 200 assert response.json()['message'] == 'synced' + +def test_bulk_sync_session_cookie_change(client): + with mock.patch("routers.routes.get_gwa_ocp_routes") as mock_get_routes: + mock_get_routes.return_value = [{ + "metadata": { + "name": "wild-ns-example", + "labels": { + "aps-select-tag": "ns.EXAMPLE-NS", + "aps-template-version": "v2" + } + }, + "spec": { + "host": "abc.api.gov.bc.ca", + "to": { + "name": "data-plane-1" + } + } + }] + + with mock.patch("routers.routes.prepare_apply_routes") as mock_prepare_apply: + mock_prepare_apply.return_value = 1 + + with mock.patch("routers.routes.apply_routes") as mock_apply_routes: + mock_apply_routes.return_value = None + + with mock.patch("routers.routes.delete_route") as mock_delete_route: + mock_delete_route.return_value = None # Simulate successful deletion + + with mock.patch("routers.routes.kubectl_delete") as mock_kubectl_delete: + mock_kubectl_delete.return_value = None # Simulate successful kubectl deletion + + data = [{ + "name": "wild-ns-example", + "selectTag": "ns.EXAMPLE-NS", + "dataPlane": "data-plane-1", + "host": "abc.api.gov.bc.ca", + "sessionCookieEnabled": True + }] + response = client.post('/namespaces/examplens/routes/sync', json=data) + + assert response.status_code == 200 + assert response.json()['message'] == 'synced' + assert response.json()['inserted_count'] == 1 + assert response.json()['deleted_count'] == 1