Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions server/request_server/api/routes/_ticket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Shared helpers for handling ticket creation across request routes."""

from __future__ import annotations

import logging
from collections.abc import Awaitable
from typing import Any

from fastapi import HTTPException, status

from request_server.core.config import settings

_TICKET_FAILURE_DETAIL = (
"The request could not be forwarded to our ticket system. Please try again later."
)


async def raise_on_ticket_failure(
ticket_task: Awaitable[str | None],
*,
entity_id: Any,
entity_label: str,
logger: logging.Logger,
) -> str | None:
"""Await a ticket-creation coroutine and raise HTTPException on failure.

Returns the ticket key on success, or None when the configured ticket
system deliberately produces no ticket (e.g. NoOp). Callers should defer
committing the request row until after this returns so an exception
triggers a rollback of the pending INSERT.
"""
try:
ticket_key = await ticket_task
except Exception as exc:
logger.exception("Error creating ticket for %s %s", entity_label, entity_id)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail=_TICKET_FAILURE_DETAIL,
) from exc

if ticket_key:
logger.info("Created ticket %s for %s %s", ticket_key, entity_label, entity_id)
return ticket_key

if settings.ticket_system_enabled:
logger.error("Ticket service returned no key for %s %s", entity_label, entity_id)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail=_TICKET_FAILURE_DETAIL,
)

return None
35 changes: 13 additions & 22 deletions server/request_server/api/routes/artemis_developer_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from request_server.core.config import settings
from request_server.api.routes._ticket import raise_on_ticket_failure
from request_server.core.security import CurrentUser, get_current_user, get_optional_current_user
from request_server.db.session import get_db
from request_server.models.artemis_developer_request import (
Expand Down Expand Up @@ -82,34 +82,25 @@ async def create_artemis_developer_request(
)

db.add(artemis_request)
await db.commit()
await db.flush()
await db.refresh(artemis_request)

# Create ticket in the configured ticket system
try:
ticket_key = await handle_artemis_ticket_creation(
ticket_key = await raise_on_ticket_failure(
handle_artemis_ticket_creation(
get_ticket_service(),
artemis_request,
is_authenticated=is_authenticated,
requester_username=current_user.username if current_user else None,
)
if ticket_key:
artemis_request.jira_ticket_key = ticket_key
await db.commit()
await db.refresh(artemis_request)
logger.info(
f"Created ticket {ticket_key} for Artemis developer request {artemis_request.id}"
)
elif settings.ticket_system != "debug":
logger.warning(
f"Failed to create ticket for Artemis developer request {artemis_request.id}"
)
except Exception as e:
logger.error(
f"Error creating ticket for Artemis developer request {artemis_request.id}: {e}"
)
# Don't fail the request if ticket creation fails
),
entity_id=artemis_request.id,
entity_label="Artemis developer request",
logger=logger,
)
if ticket_key:
artemis_request.jira_ticket_key = ticket_key

await db.commit()
await db.refresh(artemis_request)
return artemis_request


Expand Down
29 changes: 13 additions & 16 deletions server/request_server/api/routes/support_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from request_server.core.config import settings
from request_server.api.routes._ticket import raise_on_ticket_failure
from request_server.core.security import CurrentUser, get_current_user, get_optional_current_user
from request_server.db.session import get_db
from request_server.models.support_request import (
Expand Down Expand Up @@ -68,28 +68,25 @@ async def create_support_request(
)

db.add(support_request)
await db.commit()
await db.flush()
await db.refresh(support_request)

# Create ticket in the configured ticket system
try:
ticket_key = await handle_support_ticket_creation(
ticket_key = await raise_on_ticket_failure(
handle_support_ticket_creation(
get_ticket_service(),
support_request,
is_authenticated=is_authenticated,
requester_username=current_user.username if current_user else None,
)
if ticket_key:
support_request.jira_ticket_key = ticket_key
await db.commit()
await db.refresh(support_request)
logger.info(f"Created ticket {ticket_key} for support request {support_request.id}")
elif settings.ticket_system != "debug":
logger.warning(f"Failed to create ticket for support request {support_request.id}")
except Exception as e:
logger.error(f"Error creating ticket for support request {support_request.id}: {e}")
# Don't fail the request if ticket creation fails
),
entity_id=support_request.id,
entity_label="support request",
logger=logger,
)
if ticket_key:
support_request.jira_ticket_key = ticket_key

await db.commit()
await db.refresh(support_request)
return support_request


Expand Down
29 changes: 13 additions & 16 deletions server/request_server/api/routes/tum_guest_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from request_server.core.config import settings
from request_server.api.routes._ticket import raise_on_ticket_failure
from request_server.core.security import CurrentUser, get_current_user, get_optional_current_user
from request_server.db.session import get_db
from request_server.models.tum_guest_request import Gender as GenderModel
Expand Down Expand Up @@ -109,28 +109,25 @@ async def create_tum_guest_request(
)

db.add(guest_request)
await db.commit()
await db.flush()
await db.refresh(guest_request)

# Create ticket in the configured ticket system
try:
ticket_key = await handle_tum_guest_ticket_creation(
ticket_key = await raise_on_ticket_failure(
handle_tum_guest_ticket_creation(
get_ticket_service(),
guest_request,
is_authenticated=is_authenticated,
requester_username=current_user.username if current_user else None,
)
if ticket_key:
guest_request.jira_ticket_key = ticket_key
await db.commit()
await db.refresh(guest_request)
logger.info(f"Created ticket {ticket_key} for TUM guest request {guest_request.id}")
elif settings.ticket_system != "debug":
logger.warning(f"Failed to create ticket for TUM guest request {guest_request.id}")
except Exception as e:
logger.error(f"Error creating ticket for TUM guest request {guest_request.id}: {e}")
# Don't fail the request if ticket creation fails
),
entity_id=guest_request.id,
entity_label="TUM guest request",
logger=logger,
)
if ticket_key:
guest_request.jira_ticket_key = ticket_key

await db.commit()
await db.refresh(guest_request)
return guest_request


Expand Down
29 changes: 12 additions & 17 deletions server/request_server/api/routes/vm_access_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from request_server.api.routes._ticket import raise_on_ticket_failure
from request_server.api.routes.ssh_keys import parse_ssh_key
from request_server.core.config import settings
from request_server.core.security import CurrentUser, get_current_user
from request_server.db.session import get_db
from request_server.models.ssh_key import SSHKey
Expand Down Expand Up @@ -117,25 +117,20 @@ async def create_vm_access_request(
)

db.add(access_request)
await db.commit()
await db.flush()
await db.refresh(access_request)

# Create ticket in the configured ticket system
try:
ticket_key = await handle_vm_access_ticket_creation(
get_ticket_service(), access_request, ssh_public_key
)
if ticket_key:
access_request.jira_ticket_key = ticket_key
await db.commit()
await db.refresh(access_request)
logger.info(f"Created ticket {ticket_key} for VM access request {access_request.id}")
elif settings.ticket_system != "debug":
logger.warning(f"Failed to create ticket for VM access request {access_request.id}")
except Exception as e:
logger.error(f"Error creating ticket for VM access request {access_request.id}: {e}")
# Don't fail the request if ticket creation fails
ticket_key = await raise_on_ticket_failure(
handle_vm_access_ticket_creation(get_ticket_service(), access_request, ssh_public_key),
entity_id=access_request.id,
entity_label="VM access request",
logger=logger,
)
if ticket_key:
access_request.jira_ticket_key = ticket_key

await db.commit()
await db.refresh(access_request)
return access_request


Expand Down
29 changes: 12 additions & 17 deletions server/request_server/api/routes/vm_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from request_server.api.routes._ticket import raise_on_ticket_failure
from request_server.api.routes.ssh_keys import parse_ssh_key
from request_server.core.config import settings
from request_server.core.security import CurrentUser, get_current_user
from request_server.db.session import get_db
from request_server.models.ssh_key import SSHKey
Expand Down Expand Up @@ -134,25 +134,20 @@ async def create_vm_request(
)

db.add(vm_request)
await db.commit()
await db.flush()
await db.refresh(vm_request)

# Create ticket in the configured ticket system
try:
ticket_key = await handle_vm_ticket_creation(
get_ticket_service(), vm_request, ssh_public_key
)
if ticket_key:
vm_request.jira_ticket_key = ticket_key
await db.commit()
await db.refresh(vm_request)
logger.info(f"Created ticket {ticket_key} for VM request {vm_request.id}")
elif settings.ticket_system != "debug":
logger.warning(f"Failed to create ticket for VM request {vm_request.id}")
except Exception as e:
logger.error(f"Error creating ticket for VM request {vm_request.id}: {e}")
# Don't fail the request if ticket creation fails
ticket_key = await raise_on_ticket_failure(
handle_vm_ticket_creation(get_ticket_service(), vm_request, ssh_public_key),
entity_id=vm_request.id,
entity_label="VM request",
logger=logger,
)
if ticket_key:
vm_request.jira_ticket_key = ticket_key

await db.commit()
await db.refresh(vm_request)
return vm_request


Expand Down
Loading