mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
feat(cluster): add reload and restart for nginx
This commit is contained in:
parent
c086455772
commit
2d437ff0cc
24 changed files with 2897 additions and 1239 deletions
|
@ -1,6 +1,8 @@
|
|||
package cluster
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/uozi-tech/cosy"
|
||||
|
@ -17,6 +19,38 @@ func GetGroupList(c *gin.Context) {
|
|||
}).PagingList()
|
||||
}
|
||||
|
||||
func ReloadNginx(c *gin.Context) {
|
||||
var json struct {
|
||||
NodeIDs []uint64 `json:"node_ids" binding:"required"`
|
||||
}
|
||||
|
||||
if !cosy.BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
go syncReload(json.NodeIDs)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func RestartNginx(c *gin.Context) {
|
||||
var json struct {
|
||||
NodeIDs []uint64 `json:"node_ids" binding:"required"`
|
||||
}
|
||||
|
||||
if !cosy.BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
go syncRestart(json.NodeIDs)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func AddGroup(c *gin.Context) {
|
||||
cosy.Core[model.EnvGroup](c).
|
||||
SetValidRules(gin.H{
|
||||
|
|
126
api/cluster/nginx.go
Normal file
126
api/cluster/nginx.go
Normal file
|
@ -0,0 +1,126 @@
|
|||
package cluster
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/0xJacky/Nginx-UI/internal/notification"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/query"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/uozi-tech/cosy/logger"
|
||||
)
|
||||
|
||||
type syncResult struct {
|
||||
Node string `json:"node"`
|
||||
Resp string `json:"resp"`
|
||||
}
|
||||
|
||||
// syncReload handle reload nginx on remote nodes
|
||||
func syncReload(nodeIDs []uint64) {
|
||||
if len(nodeIDs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
e := query.Environment
|
||||
nodes, err := e.Where(e.ID.In(nodeIDs...)).Find()
|
||||
if err != nil {
|
||||
logger.Error("Failed to get environment nodes:", err)
|
||||
return
|
||||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(len(nodes))
|
||||
|
||||
for _, node := range nodes {
|
||||
go func(node *model.Environment) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
buf := make([]byte, 1024)
|
||||
runtime.Stack(buf, false)
|
||||
logger.Error(err)
|
||||
}
|
||||
}()
|
||||
defer wg.Done()
|
||||
|
||||
client := resty.New()
|
||||
client.SetBaseURL(node.URL)
|
||||
resp, err := client.R().
|
||||
SetHeader("X-Node-Secret", node.Token).
|
||||
Post("/api/nginx/reload")
|
||||
if err != nil {
|
||||
notification.Error("Reload Remote Nginx Error", "", err.Error())
|
||||
return
|
||||
}
|
||||
if resp.StatusCode() != http.StatusOK {
|
||||
notification.Error("Reload Remote Nginx Error",
|
||||
"Reload Nginx on %{node} failed, response: %{resp}", syncResult{
|
||||
Node: node.Name,
|
||||
Resp: resp.String(),
|
||||
})
|
||||
return
|
||||
}
|
||||
notification.Success("Reload Remote Nginx Success",
|
||||
"Reload Nginx on %{node} successfully", syncResult{
|
||||
Node: node.Name,
|
||||
})
|
||||
}(node)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// syncRestart handle restart nginx on remote nodes
|
||||
func syncRestart(nodeIDs []uint64) {
|
||||
if len(nodeIDs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
e := query.Environment
|
||||
nodes, err := e.Where(e.ID.In(nodeIDs...)).Find()
|
||||
if err != nil {
|
||||
logger.Error("Failed to get environment nodes:", err)
|
||||
return
|
||||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(len(nodes))
|
||||
|
||||
for _, node := range nodes {
|
||||
go func(node *model.Environment) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
buf := make([]byte, 1024)
|
||||
runtime.Stack(buf, false)
|
||||
logger.Error(err)
|
||||
}
|
||||
}()
|
||||
defer wg.Done()
|
||||
|
||||
client := resty.New()
|
||||
client.SetBaseURL(node.URL)
|
||||
resp, err := client.R().
|
||||
SetHeader("X-Node-Secret", node.Token).
|
||||
Post("/api/nginx/restart")
|
||||
if err != nil {
|
||||
notification.Error("Restart Remote Nginx Error", "", err.Error())
|
||||
return
|
||||
}
|
||||
if resp.StatusCode() != http.StatusOK {
|
||||
notification.Error("Restart Remote Nginx Error",
|
||||
"Restart Nginx on %{node} failed, response: %{resp}", syncResult{
|
||||
Node: node.Name,
|
||||
Resp: resp.String(),
|
||||
})
|
||||
return
|
||||
}
|
||||
notification.Success("Restart Remote Nginx Success",
|
||||
"Restart Nginx on %{node} successfully", syncResult{
|
||||
Node: node.Name,
|
||||
})
|
||||
}(node)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
|
@ -17,6 +17,9 @@ func InitRouter(r *gin.RouterGroup) {
|
|||
// Node
|
||||
r.GET("node", GetCurrentNode)
|
||||
|
||||
r.POST("environments/reload_nginx", ReloadNginx)
|
||||
r.POST("environments/restart_nginx", RestartNginx)
|
||||
|
||||
r.GET("env_groups", GetGroupList)
|
||||
r.GET("env_groups/:id", GetGroup)
|
||||
r.POST("env_groups", AddGroup)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue