list.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package upstream
  2. import (
  3. "net/http"
  4. "sort"
  5. "github.com/0xJacky/Nginx-UI/internal/upstream"
  6. "github.com/0xJacky/Nginx-UI/model"
  7. "github.com/0xJacky/Nginx-UI/query"
  8. "github.com/gin-gonic/gin"
  9. "github.com/uozi-tech/cosy"
  10. "github.com/uozi-tech/cosy/logger"
  11. )
  12. // UpstreamInfo represents an upstream with its configuration and health status
  13. type UpstreamInfo struct {
  14. Name string `json:"name"`
  15. Servers []upstream.ProxyTarget `json:"servers"`
  16. ConfigPath string `json:"config_path"`
  17. LastSeen string `json:"last_seen"`
  18. Status map[string]*upstream.Status `json:"status"`
  19. Enabled bool `json:"enabled"`
  20. }
  21. // GetUpstreamList returns all upstreams with their configuration and health status
  22. func GetUpstreamList(c *gin.Context) {
  23. service := upstream.GetUpstreamService()
  24. // Get all upstream definitions
  25. upstreams := service.GetAllUpstreamDefinitions()
  26. // Get availability map
  27. availabilityMap := service.GetAvailabilityMap()
  28. // Get all upstream configurations from database
  29. u := query.UpstreamConfig
  30. configs, err := u.Find()
  31. if err != nil {
  32. cosy.ErrHandler(c, err)
  33. return
  34. }
  35. // Create a map for quick lookup of enabled status by upstream name
  36. configMap := make(map[string]bool)
  37. for _, config := range configs {
  38. configMap[config.Socket] = config.Enabled
  39. }
  40. // Build response
  41. result := make([]UpstreamInfo, 0, len(upstreams))
  42. for name, def := range upstreams {
  43. // Get enabled status from database, default to true if not found
  44. enabled := true
  45. if val, exists := configMap[name]; exists {
  46. enabled = val
  47. }
  48. // Get status for each server in this upstream
  49. serverStatus := make(map[string]*upstream.Status)
  50. for _, server := range def.Servers {
  51. key := formatSocketAddress(server.Host, server.Port)
  52. if status, exists := availabilityMap[key]; exists {
  53. serverStatus[key] = status
  54. }
  55. }
  56. info := UpstreamInfo{
  57. Name: name,
  58. Servers: def.Servers,
  59. ConfigPath: def.ConfigPath,
  60. LastSeen: def.LastSeen.Format("2006-01-02 15:04:05"),
  61. Status: serverStatus,
  62. Enabled: enabled,
  63. }
  64. result = append(result, info)
  65. }
  66. // Sort by name for stable ordering
  67. sort.Slice(result, func(i, j int) bool {
  68. return result[i].Name < result[j].Name
  69. })
  70. c.JSON(http.StatusOK, gin.H{
  71. "data": result,
  72. })
  73. }
  74. // UpdateUpstreamConfigRequest represents the request body for updating upstream config
  75. type UpdateUpstreamConfigRequest struct {
  76. Enabled bool `json:"enabled"`
  77. }
  78. // UpdateUpstreamConfig updates the enabled status of an upstream
  79. func UpdateUpstreamConfig(c *gin.Context) {
  80. name := c.Param("name")
  81. var req UpdateUpstreamConfigRequest
  82. if err := c.ShouldBindJSON(&req); err != nil {
  83. cosy.ErrHandler(c, err)
  84. return
  85. }
  86. u := query.UpstreamConfig
  87. // Check if config exists
  88. config, err := u.Where(u.Socket.Eq(name)).First()
  89. if err != nil {
  90. // Create new config if not found
  91. config = &model.UpstreamConfig{
  92. Socket: name,
  93. Enabled: req.Enabled,
  94. }
  95. if err := u.Create(config); err != nil {
  96. logger.Error("Failed to create upstream config:", err)
  97. cosy.ErrHandler(c, err)
  98. return
  99. }
  100. // Invalidate cache after creating new config
  101. service := upstream.GetUpstreamService()
  102. service.InvalidateDisabledSocketsCache()
  103. } else {
  104. // Update existing config
  105. if _, err := u.Where(u.Socket.Eq(name)).Update(u.Enabled, req.Enabled); err != nil {
  106. logger.Error("Failed to update upstream config:", err)
  107. cosy.ErrHandler(c, err)
  108. return
  109. }
  110. }
  111. // Invalidate the disabled sockets cache to ensure changes take effect immediately
  112. service := upstream.GetUpstreamService()
  113. service.InvalidateDisabledSocketsCache()
  114. c.JSON(http.StatusOK, gin.H{
  115. "message": "Upstream config updated successfully",
  116. })
  117. }