123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- package sites
- import (
- "context"
- "net/http"
- "time"
- "github.com/0xJacky/Nginx-UI/internal/sitecheck"
- "github.com/0xJacky/Nginx-UI/model"
- "github.com/0xJacky/Nginx-UI/query"
- "github.com/gin-gonic/gin"
- "github.com/spf13/cast"
- "github.com/uozi-tech/cosy"
- "github.com/uozi-tech/cosy/logger"
- )
- // GetSiteNavigation returns all sites for navigation dashboard
- func GetSiteNavigation(c *gin.Context) {
- service := sitecheck.GetService()
- sites := service.GetSites()
- c.JSON(http.StatusOK, gin.H{
- "data": sites,
- })
- }
- // GetSiteNavigationStatus returns the status of site checking service
- func GetSiteNavigationStatus(c *gin.Context) {
- service := sitecheck.GetService()
- c.JSON(http.StatusOK, gin.H{
- "running": service.IsRunning(),
- })
- }
- // UpdateSiteOrder updates the custom order of sites
- func UpdateSiteOrder(c *gin.Context) {
- var req struct {
- OrderedIds []uint64 `json:"ordered_ids" binding:"required"`
- }
- if !cosy.BindAndValid(c, &req) {
- return
- }
- if err := updateSiteOrderBatchByIds(req.OrderedIds); err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- c.JSON(http.StatusOK, gin.H{
- "message": "Order updated successfully",
- })
- }
- // updateSiteOrderBatchByIds updates site order in batch using IDs
- func updateSiteOrderBatchByIds(orderedIds []uint64) error {
- sc := query.SiteConfig
- for i, id := range orderedIds {
- if _, err := sc.Where(sc.ID.Eq(id)).Update(sc.CustomOrder, i); err != nil {
- return err
- }
- }
- return nil
- }
- // GetHealthCheck gets health check configuration for a site
- func GetHealthCheck(c *gin.Context) {
- id := cast.ToUint64(c.Param("id"))
- sc := query.SiteConfig
- siteConfig, err := sc.Where(sc.ID.Eq(id)).First()
- if err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- ensureHealthCheckConfig(siteConfig)
- c.JSON(http.StatusOK, siteConfig)
- }
- // createDefaultHealthCheckConfig creates default health check configuration
- func createDefaultHealthCheckConfig() *model.HealthCheckConfig {
- return &model.HealthCheckConfig{
- Protocol: "http",
- Method: "GET",
- Path: "/",
- ExpectedStatus: []int{200},
- GRPCMethod: "Check",
- }
- }
- // ensureHealthCheckConfig ensures health check config is not nil
- func ensureHealthCheckConfig(siteConfig *model.SiteConfig) {
- if siteConfig.HealthCheckConfig == nil {
- siteConfig.HealthCheckConfig = createDefaultHealthCheckConfig()
- }
- }
- // UpdateHealthCheck updates health check configuration for a site
- func UpdateHealthCheck(c *gin.Context) {
- id := cast.ToUint64(c.Param("id"))
- var req model.SiteConfig
- if !cosy.BindAndValid(c, &req) {
- return
- }
- sc := query.SiteConfig
- siteConfig, err := sc.Where(sc.ID.Eq(id)).First()
- if err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- siteConfig.HealthCheckEnabled = req.HealthCheckEnabled
- siteConfig.CheckInterval = req.CheckInterval
- siteConfig.Timeout = req.Timeout
- siteConfig.UserAgent = req.UserAgent
- siteConfig.MaxRedirects = req.MaxRedirects
- siteConfig.FollowRedirects = req.FollowRedirects
- siteConfig.CheckFavicon = req.CheckFavicon
- if req.HealthCheckConfig != nil {
- siteConfig.HealthCheckConfig = req.HealthCheckConfig
- }
- if err = query.SiteConfig.Save(siteConfig); err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- c.JSON(http.StatusOK, gin.H{
- "message": "Health check configuration updated successfully",
- })
- }
- // TestHealthCheck tests a health check configuration without saving it
- func TestHealthCheck(c *gin.Context) {
- id := cast.ToUint64(c.Param("id"))
- var req struct {
- Config *model.HealthCheckConfig `json:"config" binding:"required"`
- }
- if !cosy.BindAndValid(c, &req) {
- return
- }
- // Get site config to determine the host for testing
- sc := query.SiteConfig
- siteConfig, err := sc.Where(sc.ID.Eq(id)).First()
- if err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- // Create enhanced checker and test the configuration
- enhancedChecker := sitecheck.NewEnhancedSiteChecker()
- ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
- defer cancel()
- // Convert host to URL for testing
- testURL := siteConfig.Scheme + "://" + siteConfig.Host
- result, err := enhancedChecker.CheckSiteWithConfig(ctx, testURL, req.Config)
- if err != nil {
- logger.Errorf("Health check test failed for %s: %v", siteConfig.Host, err)
- c.JSON(http.StatusOK, gin.H{
- "success": false,
- "error": err.Error(),
- "response_time": 0,
- })
- return
- }
- success := result.Status == "online"
- errorMsg := ""
- if !success && result.Error != "" {
- errorMsg = result.Error
- }
- c.JSON(http.StatusOK, gin.H{
- "success": success,
- "response_time": result.ResponseTime,
- "status": result.Status,
- "status_code": result.StatusCode,
- "error": errorMsg,
- })
- }
|