- Create LogsHandler with all log query endpoints - Implement QueryLogs for LogsQL queries - Implement StatsQuery for time-series statistics - Implement GetFacets for field facets - Implement TailLogs for real-time streaming (NDJSON) - Implement ExportLogs with JSON and CSV support - Wire up logs handler in router - Add VictoriaLogs client initialization Closes #13 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
183 lines
6.0 KiB
Go
183 lines
6.0 KiB
Go
package api
|
|
|
|
import (
|
|
"database/sql"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/yourusername/victorialogs-manager/internal/api/handlers"
|
|
"github.com/yourusername/victorialogs-manager/internal/api/middleware"
|
|
"github.com/yourusername/victorialogs-manager/internal/config"
|
|
"github.com/yourusername/victorialogs-manager/internal/repository"
|
|
"github.com/yourusername/victorialogs-manager/internal/services"
|
|
"github.com/yourusername/victorialogs-manager/internal/utils"
|
|
"github.com/yourusername/victorialogs-manager/pkg/vlogs"
|
|
)
|
|
|
|
// NewRouter creates and configures the main router
|
|
func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
|
// Set Gin mode
|
|
gin.SetMode(gin.ReleaseMode)
|
|
|
|
router := gin.New()
|
|
|
|
// Global middleware
|
|
router.Use(gin.Recovery())
|
|
router.Use(middleware.CORSMiddleware())
|
|
router.Use(middleware.RequestLogger())
|
|
|
|
// Initialize JWT manager
|
|
jwtManager := utils.NewJWTManager(
|
|
cfg.Auth.JWTSecret,
|
|
cfg.Auth.AccessTokenDuration,
|
|
cfg.Auth.RefreshTokenDuration,
|
|
)
|
|
|
|
// Initialize repositories
|
|
userRepo := repository.NewUserRepository(db)
|
|
|
|
// Initialize VictoriaLogs client
|
|
vlogsClient := vlogs.NewClient(cfg.VictoriaLogs.URL, cfg.VictoriaLogs.Timeout)
|
|
|
|
// Initialize services
|
|
authService := services.NewAuthService(userRepo, jwtManager)
|
|
userService := services.NewUserService(userRepo)
|
|
logsService := services.NewLogsService(vlogsClient)
|
|
|
|
// Initialize handlers
|
|
authHandler := handlers.NewAuthHandler(authService)
|
|
userHandler := handlers.NewUserHandler(userService)
|
|
logsHandler := handlers.NewLogsHandler(logsService)
|
|
|
|
// Health check endpoint
|
|
router.GET("/health", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"status": "ok",
|
|
"service": "victorialogs-manager",
|
|
})
|
|
})
|
|
|
|
// API v1 routes
|
|
v1 := router.Group("/api/v1")
|
|
{
|
|
// Authentication routes (public)
|
|
auth := v1.Group("/auth")
|
|
{
|
|
auth.POST("/login", authHandler.Login)
|
|
auth.POST("/refresh", authHandler.RefreshToken)
|
|
}
|
|
|
|
// Protected auth routes (require authentication)
|
|
authProtected := v1.Group("/auth")
|
|
authProtected.Use(middleware.AuthMiddleware(jwtManager))
|
|
{
|
|
authProtected.GET("/me", authHandler.GetMe)
|
|
authProtected.POST("/change-password", authHandler.ChangePassword)
|
|
}
|
|
|
|
// User management routes (admin only)
|
|
users := v1.Group("/users")
|
|
users.Use(middleware.AuthMiddleware(jwtManager))
|
|
users.Use(middleware.RequireAdmin())
|
|
{
|
|
users.GET("", userHandler.ListUsers)
|
|
users.POST("", userHandler.CreateUser)
|
|
users.GET("/:id", userHandler.GetUser)
|
|
users.PUT("/:id", userHandler.UpdateUser)
|
|
users.DELETE("/:id", userHandler.DeleteUser)
|
|
users.POST("/:id/reset-password", userHandler.ResetUserPassword)
|
|
}
|
|
|
|
// Log querying routes (protected)
|
|
logs := v1.Group("/logs")
|
|
logs.Use(middleware.AuthMiddleware(jwtManager))
|
|
{
|
|
logs.POST("/query", logsHandler.QueryLogs)
|
|
logs.POST("/tail", logsHandler.TailLogs)
|
|
logs.POST("/facets", logsHandler.GetFacets)
|
|
logs.POST("/stats", logsHandler.StatsQuery)
|
|
logs.POST("/export", logsHandler.ExportLogs)
|
|
}
|
|
|
|
// Alert management routes (protected)
|
|
alerts := v1.Group("/alerts")
|
|
alerts.Use(middleware.AuthMiddleware(jwtManager))
|
|
{
|
|
alerts.GET("/rules", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
alerts.POST("/rules", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
alerts.GET("/rules/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
alerts.PUT("/rules/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
alerts.DELETE("/rules/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
alerts.POST("/reload", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
alerts.GET("/active", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
}
|
|
|
|
// Pattern detection routes (protected)
|
|
patterns := v1.Group("/patterns")
|
|
patterns.Use(middleware.AuthMiddleware(jwtManager))
|
|
{
|
|
patterns.GET("", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
patterns.POST("", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
patterns.PUT("/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
patterns.DELETE("/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
patterns.POST("/detect", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
patterns.POST("/ml/train", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
patterns.POST("/ml/detect", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
}
|
|
|
|
// Report routes (protected)
|
|
reports := v1.Group("/reports")
|
|
reports.Use(middleware.AuthMiddleware(jwtManager))
|
|
{
|
|
reports.GET("", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
reports.POST("", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
reports.GET("/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
reports.PUT("/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
reports.DELETE("/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
reports.POST("/:id/execute", func(c *gin.Context) {
|
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
|
})
|
|
}
|
|
}
|
|
|
|
return router
|
|
}
|