Files
telecom-platform/apps/api-server/cmd/server_routes.go
T
nutcas3 51c1ad6573 feat: Add Swagger documentation endpoint and update API route prefix from /v1 to /api/v1
- Add swaggo/files and swaggo/gin-swagger imports for Swagger documentation
- Change API route group prefix from "/v1" to "/api/v1"
- Add GET /api/v1/swagger/*any endpoint for Swagger UI documentation
- Update RBAC path from "/v1/users" to "/api/v1/users" for consistency
2026-04-30 22:49:51 +03:00

198 lines
6.4 KiB
Go

package main
import (
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/nutcas3/telecom-platform/apps/api-server/internal/middleware"
"github.com/nutcas3/telecom-platform/apps/api-server/internal/rbac"
)
// registerV1Routes wires the /v1 API routes to the provided deps.
// RBAC enforcement uses Casbin when configured, falling back to role-based
// middleware otherwise.
func registerV1Routes(router *gin.Engine, d *serverDeps) {
v1 := router.Group("/api/v1")
// Health check
v1.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
// Swagger documentation
v1.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// Charging engine integration (public for packet-gateway integration)
charging := v1.Group("/charging")
{
charging.POST("/credit/:ip/check", d.chargingH.CheckCredit)
charging.GET("/credit/:ip/balance", d.chargingH.GetBalance)
charging.POST("/credit/:ip/add", d.chargingH.AddCredit)
charging.POST("/credit/:ip/deduct", d.chargingH.DeductCredit)
}
auth := v1.Group("/auth")
{
auth.POST("/login", d.authH.Login)
auth.POST("/register", d.authH.Register)
auth.POST("/refresh", d.authH.RefreshToken)
}
protected := v1.Group("/")
protected.Use(middleware.RateLimitByUser(100)) // 100 requests per minute per user
protected.Use(middleware.AuthMiddleware(d.authSvc))
{
authProtected := protected.Group("/auth")
{
authProtected.POST("/logout", d.authH.Logout)
authProtected.GET("/profile", d.authH.GetProfile)
authProtected.POST("/change-password", d.authH.ChangePassword)
}
users := protected.Group("/users")
applyRBAC(users, d.casbinSvc, "/api/v1/users", "GET", "admin")
{
users.GET("", d.authH.GetUsers)
users.POST("", d.authH.CreateUser)
users.PUT("/:id", d.authH.UpdateUser)
users.DELETE("/:id", d.authH.DeleteUser)
}
}
apiProtected := v1.Group("/")
apiProtected.Use(middleware.RateLimitByUser(100)) // 100 requests per minute per user
apiProtected.Use(middleware.AuthMiddleware(d.authSvc))
{
registerSubscriberRoutes(apiProtected, d)
registerServicesRoutes(apiProtected, d)
registerMonitoringRoutes(apiProtected, d)
registerDeployRoutes(apiProtected, d)
registerPluginRoutes(apiProtected, d)
registerAutomationRoutes(apiProtected, d)
registerBillingRoutes(apiProtected, d)
registerConfigRoutes(apiProtected, d)
registerChaosRoutes(apiProtected, d)
}
}
// applyRBAC attaches Casbin or fallback role middleware to a group.
func applyRBAC(g *gin.RouterGroup, casbinSvc *rbac.CasbinService, path, method string, fallbackRoles ...string) {
if casbinSvc != nil {
g.Use(middleware.RequireCasbinPermission(casbinSvc, path, method))
} else {
g.Use(middleware.RequireRole(fallbackRoles...))
}
}
func registerServicesRoutes(api *gin.RouterGroup, d *serverDeps) {
svcs := api.Group("/services")
svcs.GET("", d.servicesH.List)
svcs.GET("/:id", d.servicesH.Get)
svcs.GET("/:id/logs", d.servicesH.Logs)
svcs.GET("/:id/health", d.servicesH.Health)
svcs.GET("/:id/pods", d.servicesH.PodStatus)
svcs.GET("/:id/events", d.servicesH.Events)
w := svcs.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/services", "POST", "admin", "operator")
w.POST("/:id/restart", d.servicesH.Restart)
w.POST("/:id/start", d.servicesH.Start)
w.POST("/:id/stop", d.servicesH.Stop)
w.POST("/:id/scale", d.servicesH.Scale)
}
func registerMonitoringRoutes(api *gin.RouterGroup, d *serverDeps) {
mon := api.Group("/monitoring")
mon.GET("/metrics", d.monitoringH.Metrics)
mon.GET("/alerts", d.monitoringH.Alerts)
mon.GET("/health", d.monitoringH.Health)
mon.GET("/logs", d.monitoringH.Logs)
}
func registerDeployRoutes(api *gin.RouterGroup, d *serverDeps) {
deploy := api.Group("/deploy")
deploy.GET("/status", d.deploymentsH.Status)
deploy.GET("/history", d.deploymentsH.History)
w := deploy.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/deploy", "POST", "admin", "operator")
w.POST("/start", d.deploymentsH.Start)
w.POST("/rollback", d.deploymentsH.Rollback)
}
func registerPluginRoutes(api *gin.RouterGroup, d *serverDeps) {
plugs := api.Group("/plugins")
plugs.GET("", d.pluginsH.List)
w := plugs.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/plugins", "POST", "admin")
w.POST("/install", d.pluginsH.Install)
w.POST("/:id/enable", d.pluginsH.Enable)
w.POST("/:id/disable", d.pluginsH.Disable)
if d.casbinSvc != nil {
del := plugs.Group("/")
del.Use(middleware.RequireCasbinPermission(d.casbinSvc, "/v1/plugins", "DELETE"))
del.DELETE("/:id", d.pluginsH.Uninstall)
} else {
w.DELETE("/:id", d.pluginsH.Uninstall)
}
}
func registerAutomationRoutes(api *gin.RouterGroup, d *serverDeps) {
auto := api.Group("/automation")
auto.GET("", d.automationH.List)
auto.GET("/logs", d.automationH.Logs)
w := auto.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/automation", "POST", "admin", "operator")
w.POST("", d.automationH.Create)
w.POST("/:id/run", d.automationH.Run)
w.POST("/:id/schedule", d.automationH.Schedule)
}
func registerBillingRoutes(api *gin.RouterGroup, d *serverDeps) {
bill := api.Group("/billing")
bill.GET("/invoices", d.billingH.ListInvoices)
bill.GET("/payments", d.billingH.ListPayments)
w := bill.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/billing", "POST", "admin")
w.POST("/invoices", d.billingH.GenerateInvoice)
}
func registerConfigRoutes(api *gin.RouterGroup, d *serverDeps) {
cfg := api.Group("/config")
cfg.GET("", d.configH.Get)
cfg.GET("/validate", d.configH.Validate)
w := cfg.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/config", "POST", "admin")
w.POST("", d.configH.Update)
}
func registerChaosRoutes(api *gin.RouterGroup, d *serverDeps) {
chaosGroup := api.Group("/chaos")
chaosGroup.GET("/experiments", d.chaosH.List)
chaosGroup.GET("/status", d.chaosH.Status)
w := chaosGroup.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/chaos", "POST", "admin")
w.POST("/experiments", d.chaosH.Run)
}
func registerSubscriberRoutes(api *gin.RouterGroup, d *serverDeps) {
subs := api.Group("/subscribers")
subs.GET("", d.subscriberH.ListSubscribers)
subs.GET("/:id", d.subscriberH.GetSubscriber)
subs.GET("/imsi/:imsi", d.subscriberH.GetSubscriberByIMSI)
w := subs.Group("/")
applyRBAC(w, d.casbinSvc, "/v1/subscribers", "POST", "admin", "operator")
w.POST("", d.subscriberH.CreateSubscriber)
w.PUT("/:id", d.subscriberH.UpdateSubscriber)
w.POST("/:id/suspend", d.subscriberH.SuspendSubscriber)
w.POST("/:id/terminate", d.subscriberH.TerminateSubscriber)
}