Add statuspage package with service, handler, and types for exposing platform health. Implement GET /api/v1/status endpoint returning operational status, component health (API, database, gateway runtime), and control plane summary counts. Add Service.Snapshot method querying database connectivity, user/device/gateway/service/policy counts, connected device count via handshake timestamps, and gateway runtime tel
75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"nexavpn/backend/internal/audit"
|
|
"nexavpn/backend/internal/auth"
|
|
"nexavpn/backend/internal/config"
|
|
"nexavpn/backend/internal/db"
|
|
"nexavpn/backend/internal/device"
|
|
"nexavpn/backend/internal/gateway"
|
|
"nexavpn/backend/internal/group"
|
|
"nexavpn/backend/internal/httpserver"
|
|
"nexavpn/backend/internal/ipam"
|
|
"nexavpn/backend/internal/policy"
|
|
"nexavpn/backend/internal/servicecatalog"
|
|
"nexavpn/backend/internal/statuspage"
|
|
"nexavpn/backend/internal/user"
|
|
)
|
|
|
|
type App struct {
|
|
DB *pgxpool.Pool
|
|
Router http.Handler
|
|
}
|
|
|
|
func New(cfg config.Config) (*App, error) {
|
|
ctx := context.Background()
|
|
|
|
pool, err := db.Connect(ctx, cfg.DatabaseURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := db.EnsureSchema(ctx, pool); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
authRepo := auth.NewPGRepository(pool)
|
|
authService := auth.NewService(authRepo, cfg.JWTSecret, cfg.JWTIssuer, cfg.AccessTokenTTL, cfg.RefreshTokenTTL)
|
|
|
|
userService := user.NewService(user.NewPGRepository(pool))
|
|
groupService := group.NewService(group.NewPGRepository(pool))
|
|
serviceCatalogService := servicecatalog.NewService(servicecatalog.NewPGRepository(pool))
|
|
policyService := policy.NewService(policy.NewPGRepository(pool))
|
|
gatewayService := gateway.NewService(gateway.NewPGRepository(pool))
|
|
deviceService := device.NewService(device.NewPGRepository(pool), policyService, gatewayService, ipam.NewService())
|
|
auditService := audit.NewService(audit.NewPGRepository(pool))
|
|
statusService := statuspage.NewService(pool)
|
|
|
|
router := httpserver.NewRouter(cfg.JWTSecret, httpserver.Handlers{
|
|
Auth: auth.NewHandler(authService, auditService),
|
|
User: user.NewHandler(userService, auditService),
|
|
Device: device.NewHandler(deviceService, auditService),
|
|
Group: group.NewHandler(groupService, auditService),
|
|
Service: servicecatalog.NewHandler(serviceCatalogService),
|
|
Policy: policy.NewHandler(policyService, auditService),
|
|
Gateway: gateway.NewHandler(gatewayService, cfg.GatewayBootstrapToken),
|
|
Audit: audit.NewHandler(auditService),
|
|
Status: statuspage.NewHandler(statusService),
|
|
})
|
|
|
|
return &App{
|
|
DB: pool,
|
|
Router: router,
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) Close() {
|
|
if a.DB != nil {
|
|
a.DB.Close()
|
|
}
|
|
}
|