|
| 1 | +""" |
| 2 | +Core FastAPI app (setup, middleware) |
| 3 | +""" |
| 4 | +from pathlib import Path |
| 5 | +from typing import Dict, List, Optional |
| 6 | + |
| 7 | +from fastapi import APIRouter, Body, Depends, Request, Response |
| 8 | +from fastapi.encoders import jsonable_encoder |
| 9 | +from fastapi.responses import HTMLResponse |
| 10 | +from fastapi.templating import Jinja2Templates |
| 11 | + |
| 12 | +from src.app.configuration import get_actions |
| 13 | +from src.app.environment import Settings, get_settings, get_version |
| 14 | +from src.jbi.bugzilla import BugzillaWebhookRequest |
| 15 | +from src.jbi.models import Actions |
| 16 | +from src.jbi.runner import IgnoreInvalidRequestError, execute_action |
| 17 | +from src.jbi.services import jbi_service_health_map, jira_visible_projects |
| 18 | + |
| 19 | +router = APIRouter() |
| 20 | + |
| 21 | + |
| 22 | +@router.get("/", include_in_schema=False) |
| 23 | +def root(request: Request, settings: Settings = Depends(get_settings)): |
| 24 | + """Expose key configuration""" |
| 25 | + return { |
| 26 | + "title": request.app.title, |
| 27 | + "description": request.app.description, |
| 28 | + "version": request.app.version, |
| 29 | + "documentation": request.app.docs_url, |
| 30 | + "configuration": { |
| 31 | + "jira_base_url": settings.jira_base_url, |
| 32 | + "bugzilla_base_url": settings.bugzilla_base_url, |
| 33 | + }, |
| 34 | + } |
| 35 | + |
| 36 | + |
| 37 | +@router.get("/__heartbeat__") |
| 38 | +@router.head("/__heartbeat__") |
| 39 | +def heartbeat(response: Response, actions: Actions = Depends(get_actions)): |
| 40 | + """Return status of backing services, as required by Dockerflow.""" |
| 41 | + health_map = jbi_service_health_map(actions) |
| 42 | + health_checks = [] |
| 43 | + for health in health_map.values(): |
| 44 | + health_checks.extend(health.values()) |
| 45 | + if not all(health_checks): |
| 46 | + response.status_code = 503 |
| 47 | + return health_map |
| 48 | + |
| 49 | + |
| 50 | +@router.get("/__lbheartbeat__") |
| 51 | +@router.head("/__lbheartbeat__") |
| 52 | +def lbheartbeat(): |
| 53 | + """Dockerflow API for lbheartbeat: HEAD""" |
| 54 | + return {"status": "OK"} |
| 55 | + |
| 56 | + |
| 57 | +@router.get("/__version__") |
| 58 | +def version(version_json=Depends(get_version)): |
| 59 | + """Return version.json, as required by Dockerflow.""" |
| 60 | + return version_json |
| 61 | + |
| 62 | + |
| 63 | +@router.post("/bugzilla_webhook") |
| 64 | +def bugzilla_webhook( |
| 65 | + request: BugzillaWebhookRequest = Body(..., embed=False), |
| 66 | + actions: Actions = Depends(get_actions), |
| 67 | + settings: Settings = Depends(get_settings), |
| 68 | +): |
| 69 | + """API endpoint that Bugzilla Webhook Events request""" |
| 70 | + try: |
| 71 | + result = execute_action(request, actions, settings) |
| 72 | + return result |
| 73 | + except IgnoreInvalidRequestError as exception: |
| 74 | + return {"error": str(exception)} |
| 75 | + |
| 76 | + |
| 77 | +@router.get("/whiteboard_tags/") |
| 78 | +def get_whiteboard_tags( |
| 79 | + whiteboard_tag: Optional[str] = None, |
| 80 | + actions: Actions = Depends(get_actions), |
| 81 | +): |
| 82 | + """API for viewing whiteboard_tags and associated data""" |
| 83 | + if existing := actions.get(whiteboard_tag): |
| 84 | + return {whiteboard_tag: existing} |
| 85 | + return actions.by_tag |
| 86 | + |
| 87 | + |
| 88 | +@router.get("/jira_projects/") |
| 89 | +def get_jira_projects(): |
| 90 | + """API for viewing projects that are currently accessible by API""" |
| 91 | + visible_projects: List[Dict] = jira_visible_projects() |
| 92 | + return [project["key"] for project in visible_projects] |
| 93 | + |
| 94 | + |
| 95 | +SRC_DIR = Path(__file__).parents[1] |
| 96 | +templates = Jinja2Templates(directory=SRC_DIR / "templates") |
| 97 | + |
| 98 | + |
| 99 | +@router.get("/powered_by_jbi/", response_class=HTMLResponse) |
| 100 | +def powered_by_jbi( |
| 101 | + request: Request, |
| 102 | + enabled: Optional[bool] = None, |
| 103 | + actions: Actions = Depends(get_actions), |
| 104 | +): |
| 105 | + """API for `Powered By` endpoint""" |
| 106 | + context = { |
| 107 | + "request": request, |
| 108 | + "title": "Powered by JBI", |
| 109 | + "actions": jsonable_encoder(actions), |
| 110 | + "enable_query": enabled, |
| 111 | + } |
| 112 | + return templates.TemplateResponse("powered_by_template.html", context) |
0 commit comments