diff --git a/app/demo_adapter.py b/app/demo_adapter.py index 635b4176..d8a912d2 100644 --- a/app/demo_adapter.py +++ b/app/demo_adapter.py @@ -29,7 +29,6 @@ from .routers.status import models as status_models from .routers.task import facility_adapter as task_adapter from .routers.task import models as task_models -from .request_context import get_iri_facility_project from .types.models import Capability from .types.user import User from .types.scalars import AllocationUnit @@ -562,8 +561,6 @@ async def submit_job( user: User, job_spec: compute_models.JobSpec, ) -> compute_models.Job: - facility_project = get_iri_facility_project() - account = facility_project or (job_spec.attributes.account if job_spec.attributes else None) return compute_models.Job( id="job_123", status=compute_models.JobStatus( @@ -571,7 +568,7 @@ async def submit_job( time=utc_timestamp(), message="job submitted", exit_code=0, - meta_data={"account": account}, + meta_data={"account": "account1"}, ), ) @@ -582,8 +579,6 @@ async def update_job( job_spec: compute_models.JobSpec, job_id: str, ) -> compute_models.Job: - facility_project = get_iri_facility_project() - account = facility_project or (job_spec.attributes.account if job_spec.attributes else None) return compute_models.Job( id=job_id, status=compute_models.JobStatus( @@ -591,7 +586,7 @@ async def update_job( time=utc_timestamp(), message="job updated", exit_code=0, - meta_data={"account": account}, + meta_data={"account": "account1"}, ), ) diff --git a/app/main.py b/app/main.py index 30480024..1f6faccc 100644 --- a/app/main.py +++ b/app/main.py @@ -17,7 +17,7 @@ from . import config from .apilogger import configure_logging -from .request_context import _api_url_base, _iri_facility_project, set_api_url_base +from .request_context import set_api_url_base, _api_url_base from app.routers.error_handlers import install_error_handlers from app.routers.facility import facility @@ -58,14 +58,12 @@ class _ExternalRequestContextMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): - url_token = _api_url_base.set(None) - facility_project_token = _iri_facility_project.set(None) + token = _api_url_base.set(None) try: set_api_url_base(request) return await call_next(request) finally: - _api_url_base.reset(url_token) - _iri_facility_project.reset(facility_project_token) + _api_url_base.reset(token) APP.add_middleware(_ExternalRequestContextMiddleware) diff --git a/app/request_context.py b/app/request_context.py index 8f95f072..cc8c8828 100644 --- a/app/request_context.py +++ b/app/request_context.py @@ -6,7 +6,6 @@ from . import config _api_url_base: ContextVar[str | None] = ContextVar("_api_url_base", default=None) -_iri_facility_project: ContextVar[str | None] = ContextVar("_iri_facility_project", default=None) def _first_header_value(value: str | None) -> str: @@ -23,8 +22,6 @@ def set_api_url_base(request: Request) -> None: api_url = config.API_URL.strip("/") if host: _api_url_base.set(f"{proto}://{host}{prefix}{api_prefix}/{api_url}") - facility_project = _first_header_value(request.headers.get("x-iri-facility-project")) - _iri_facility_project.set(facility_project or None) def get_url_prefix() -> str: @@ -33,8 +30,3 @@ def get_url_prefix() -> str: if value: return value return f"{config.API_URL_ROOT}{config.API_PREFIX}{config.API_URL}" - - -def get_iri_facility_project() -> str | None: - """Return the facility-native project/account identifier forwarded by RIG.""" - return _iri_facility_project.get() diff --git a/app/routers/compute/compute.py b/app/routers/compute/compute.py index 467edd70..963d9e34 100644 --- a/app/routers/compute/compute.py +++ b/app/routers/compute/compute.py @@ -5,7 +5,6 @@ from ...types.http import forbidExtraQueryParams from ...types.scalars import StrictHTTPBool from ...types.user import User -from ...request_context import get_iri_facility_project from .. import iri_router from ..error_handlers import DEFAULT_RESPONSES from ..iri_meta import iri_meta_dict @@ -35,22 +34,6 @@ async def get_resources( return await status_router.adapter.get_resources_for_endpoint(status_models.Endpoint.compute) -def _validate_project_account_source(job_spec: models.JobSpec) -> None: - """Require exactly one project/account source: job spec account or forwarded header.""" - spec_account = job_spec.attributes.account if job_spec.attributes else None - header_account = get_iri_facility_project() - if spec_account and header_account: - raise HTTPException( - status_code=400, - detail="Specify project/account in exactly one place: job_spec.attributes.account or X-IRI-Facility-Project, not both.", - ) - if not spec_account and not header_account: - raise HTTPException( - status_code=400, - detail="Project/account must be specified in exactly one place: job_spec.attributes.account or X-IRI-Facility-Project.", - ) - - @router.post( "/job/{resource_id:str}", response_model=models.Job, @@ -74,8 +57,6 @@ async def submit_job( This command will attempt to submit a job and return its id. """ - _validate_project_account_source(job_spec) - # look up the resource (todo: maybe ensure it's available) resource = await status_router.adapter.get_resource(resource_id) @@ -108,8 +89,6 @@ async def update_job( - **job_request**: a PSIJ job spec as defined here """ - _validate_project_account_source(job_spec) - # look up the resource (todo: maybe ensure it's available) resource = await status_router.adapter.get_resource(resource_id) diff --git a/test/test_facility_project_header.py b/test/test_facility_project_header.py deleted file mode 100644 index af3301d6..00000000 --- a/test/test_facility_project_header.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -"""Regression tests for facility-project header propagation into compute submission.""" - -import os -import unittest - -from fastapi.testclient import TestClient - -os.environ.setdefault("IRI_SHOW_MISSING_ROUTES", "true") - -from app.main import APP - - -class FacilityProjectHeaderTests(unittest.TestCase): - def test_compute_submit_uses_forwarded_facility_project_header(self): - client = TestClient(APP) - - resources_response = client.get("/api/v1/status/resources") - self.assertEqual(resources_response.status_code, 200) - resource_id = resources_response.json()[0]["id"] - - response = client.post( - f"/api/v1/compute/job/{resource_id}", - headers={ - "authorization": "Bearer 12345", - "x-iri-facility-project": "ns011", - }, - json={"executable": "/bin/echo", "arguments": ["hello"]}, - ) - - self.assertEqual(response.status_code, 200) - body = response.json() - self.assertEqual(body["status"]["meta_data"]["account"], "ns011") - - def test_compute_submit_uses_job_spec_account_when_header_absent(self): - client = TestClient(APP) - - resources_response = client.get("/api/v1/status/resources") - self.assertEqual(resources_response.status_code, 200) - resource_id = resources_response.json()[0]["id"] - - response = client.post( - f"/api/v1/compute/job/{resource_id}", - headers={"authorization": "Bearer 12345"}, - json={ - "executable": "/bin/echo", - "arguments": ["hello"], - "attributes": {"account": "ns011"}, - }, - ) - - self.assertEqual(response.status_code, 200) - body = response.json() - self.assertEqual(body["status"]["meta_data"]["account"], "ns011") - - def test_compute_submit_rejects_missing_project_account(self): - client = TestClient(APP) - - resources_response = client.get("/api/v1/status/resources") - self.assertEqual(resources_response.status_code, 200) - resource_id = resources_response.json()[0]["id"] - - response = client.post( - f"/api/v1/compute/job/{resource_id}", - headers={"authorization": "Bearer 12345"}, - json={"executable": "/bin/echo", "arguments": ["hello"]}, - ) - - self.assertEqual(response.status_code, 400) - self.assertIn("exactly one place", response.json()["detail"]) - - def test_compute_submit_rejects_duplicate_project_account_sources(self): - client = TestClient(APP) - - resources_response = client.get("/api/v1/status/resources") - self.assertEqual(resources_response.status_code, 200) - resource_id = resources_response.json()[0]["id"] - - response = client.post( - f"/api/v1/compute/job/{resource_id}", - headers={ - "authorization": "Bearer 12345", - "x-iri-facility-project": "ns011", - }, - json={ - "executable": "/bin/echo", - "arguments": ["hello"], - "attributes": {"account": "also-present"}, - }, - ) - - self.assertEqual(response.status_code, 400) - self.assertIn("not both", response.json()["detail"]) - - -if __name__ == "__main__": - unittest.main()