"""FastAPI entry point for NetBird MSP Appliance.""" import logging import os from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from fastapi.staticfiles import StaticFiles from app.database import init_db from app.routers import auth, customers, deployments, monitoring, settings # --------------------------------------------------------------------------- # Logging # --------------------------------------------------------------------------- LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO").upper() logging.basicConfig( level=getattr(logging, LOG_LEVEL, logging.INFO), format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", ) logger = logging.getLogger(__name__) # --------------------------------------------------------------------------- # Application # --------------------------------------------------------------------------- app = FastAPI( title="NetBird MSP Appliance", description="Multi-tenant NetBird management platform for MSPs", version="1.0.0", docs_url="/api/docs", redoc_url="/api/redoc", openapi_url="/api/openapi.json", ) # CORS — allow same-origin; adjust if needed app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # --------------------------------------------------------------------------- # Routers # --------------------------------------------------------------------------- app.include_router(auth.router, prefix="/api/auth", tags=["Authentication"]) app.include_router(settings.router, prefix="/api/settings", tags=["Settings"]) app.include_router(customers.router, prefix="/api/customers", tags=["Customers"]) app.include_router(deployments.router, prefix="/api/customers", tags=["Deployments"]) app.include_router(monitoring.router, prefix="/api/monitoring", tags=["Monitoring"]) # --------------------------------------------------------------------------- # Static files — serve the frontend SPA # --------------------------------------------------------------------------- STATIC_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static") if os.path.isdir(STATIC_DIR): app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") # Serve index.html at root from fastapi.responses import FileResponse @app.get("/", include_in_schema=False) async def serve_index(): """Serve the main dashboard.""" index_path = os.path.join(STATIC_DIR, "index.html") if os.path.isfile(index_path): return FileResponse(index_path) return JSONResponse({"message": "NetBird MSP Appliance API is running."}) # --------------------------------------------------------------------------- # Health endpoint (unauthenticated) # --------------------------------------------------------------------------- @app.get("/api/health", tags=["Health"]) async def health_check(): """Simple health check endpoint for Docker HEALTHCHECK.""" return {"status": "ok", "service": "netbird-msp-appliance"} # --------------------------------------------------------------------------- # Startup event # --------------------------------------------------------------------------- @app.on_event("startup") async def startup_event(): """Initialize database tables on startup.""" logger.info("Starting NetBird MSP Appliance...") init_db() logger.info("Database initialized.")