Files
NetBirdMSP-Appliance/app/main.py
twothatit 41ba835a99 Add i18n, branding, user management, health checks, and cleanup for deployment
- Multi-language support (EN/DE) with i18n engine and language files
- Configurable branding (name, subtitle, logo) in Settings
- Global default language and per-user language preference
- User management router with CRUD endpoints
- Customer status sync on start/stop/restart
- Health check fixes: derive status from container state, remove broken wget healthcheck
- Caddy reverse proxy and dashboard env templates for customer stacks
- Updated README with real hardware specs, prerequisites, and new features
- Removed .claude settings (JWT tokens) and build artifacts from tracking
- Updated .gitignore for .claude/ and Windows artifacts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:24:05 +01:00

92 lines
3.5 KiB
Python

"""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, users
# ---------------------------------------------------------------------------
# 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"])
app.include_router(users.router, prefix="/api/users", tags=["Users"])
# ---------------------------------------------------------------------------
# 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.")