mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2026-05-07 06:23:39 +08:00
163 lines
4.7 KiB
Go
163 lines
4.7 KiB
Go
package upstream
|
|
|
|
import (
|
|
"net/http"
|
|
"sort"
|
|
|
|
"github.com/0xJacky/Nginx-UI/internal/upstream"
|
|
"github.com/0xJacky/Nginx-UI/model"
|
|
"github.com/0xJacky/Nginx-UI/query"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/uozi-tech/cosy"
|
|
"github.com/uozi-tech/cosy/logger"
|
|
)
|
|
|
|
// SocketInfo represents a socket with its configuration and health status
|
|
type SocketInfo struct {
|
|
Socket string `json:"socket"` // host:port
|
|
Host string `json:"host"` // hostname/IP
|
|
Port string `json:"port"` // port number
|
|
Type string `json:"type"` // proxy_pass, grpc_pass, or upstream
|
|
IsConsul bool `json:"is_consul"` // whether this is a consul service
|
|
UpstreamName string `json:"upstream_name"` // which upstream this belongs to (if any)
|
|
LastCheck string `json:"last_check"` // last time health check was performed
|
|
Status *upstream.Status `json:"status"` // health check status
|
|
Enabled bool `json:"enabled"` // whether health check is enabled
|
|
}
|
|
|
|
// GetSocketList returns all sockets with their configuration and health status
|
|
func GetSocketList(c *gin.Context) {
|
|
service := upstream.GetUpstreamService()
|
|
|
|
// Get all target infos
|
|
targets := service.GetTargetInfos()
|
|
|
|
// Get availability map
|
|
availabilityMap := service.GetAvailabilityMap()
|
|
|
|
// Get all socket configurations from database
|
|
u := query.UpstreamConfig
|
|
configs, err := u.Find()
|
|
if err != nil {
|
|
cosy.ErrHandler(c, err)
|
|
return
|
|
}
|
|
|
|
// Create a map for quick lookup of enabled status
|
|
configMap := make(map[string]bool)
|
|
for _, config := range configs {
|
|
configMap[config.Socket] = config.Enabled
|
|
}
|
|
|
|
// Build response
|
|
result := make([]SocketInfo, 0, len(targets))
|
|
for _, target := range targets {
|
|
socketAddr := formatSocketAddress(target.Host, target.Port)
|
|
|
|
// Get enabled status from database, default to true if not found
|
|
enabled := true
|
|
if val, exists := configMap[socketAddr]; exists {
|
|
enabled = val
|
|
}
|
|
|
|
// Get health status
|
|
var status *upstream.Status
|
|
if s, exists := availabilityMap[socketAddr]; exists {
|
|
status = s
|
|
}
|
|
|
|
// Find which upstream this belongs to
|
|
upstreamName := findUpstreamForSocket(service, target.ProxyTarget)
|
|
|
|
info := SocketInfo{
|
|
Socket: socketAddr,
|
|
Host: target.Host,
|
|
Port: target.Port,
|
|
Type: target.Type,
|
|
IsConsul: target.IsConsul,
|
|
UpstreamName: upstreamName,
|
|
LastCheck: target.LastSeen.Format("2006-01-02 15:04:05"),
|
|
Status: status,
|
|
Enabled: enabled,
|
|
}
|
|
result = append(result, info)
|
|
}
|
|
|
|
// Sort by socket address for stable ordering
|
|
sort.Slice(result, func(i, j int) bool {
|
|
return result[i].Socket < result[j].Socket
|
|
})
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"data": result,
|
|
})
|
|
}
|
|
|
|
// UpdateSocketConfigRequest represents the request body for updating socket config
|
|
type UpdateSocketConfigRequest struct {
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
// UpdateSocketConfig updates the enabled status of a socket
|
|
func UpdateSocketConfig(c *gin.Context) {
|
|
socket := c.Param("socket")
|
|
|
|
var req UpdateSocketConfigRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
cosy.ErrHandler(c, err)
|
|
return
|
|
}
|
|
|
|
u := query.UpstreamConfig
|
|
|
|
// Check if config exists
|
|
config, err := u.Where(u.Socket.Eq(socket)).First()
|
|
if err != nil {
|
|
// Create new config if not found
|
|
config = &model.UpstreamConfig{
|
|
Socket: socket,
|
|
Enabled: req.Enabled,
|
|
}
|
|
if err := u.Create(config); err != nil {
|
|
logger.Error("Failed to create socket config:", err)
|
|
cosy.ErrHandler(c, err)
|
|
return
|
|
}
|
|
// Invalidate cache after creating new config
|
|
service := upstream.GetUpstreamService()
|
|
service.InvalidateDisabledSocketsCache()
|
|
} else {
|
|
// Update existing config
|
|
if _, err := u.Where(u.Socket.Eq(socket)).Update(u.Enabled, req.Enabled); err != nil {
|
|
logger.Error("Failed to update socket config:", err)
|
|
cosy.ErrHandler(c, err)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Invalidate the disabled sockets cache to ensure changes take effect immediately
|
|
service := upstream.GetUpstreamService()
|
|
service.InvalidateDisabledSocketsCache()
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "Socket config updated successfully",
|
|
})
|
|
}
|
|
|
|
// findUpstreamForSocket finds which upstream a socket belongs to
|
|
func findUpstreamForSocket(service *upstream.Service, target upstream.ProxyTarget) string {
|
|
socketAddr := formatSocketAddress(target.Host, target.Port)
|
|
upstreams := service.GetAllUpstreamDefinitions()
|
|
|
|
for name, upstream := range upstreams {
|
|
for _, server := range upstream.Servers {
|
|
serverAddr := formatSocketAddress(server.Host, server.Port)
|
|
if serverAddr == socketAddr {
|
|
return name
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|