253 lines
6.6 KiB
Go
253 lines
6.6 KiB
Go
package model
|
|
|
|
import (
|
|
"backend/Type"
|
|
"backend/common"
|
|
"backend/feishu"
|
|
"backend/msg"
|
|
util "backend/util"
|
|
"fmt"
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/Ullaakut/nmap"
|
|
)
|
|
|
|
const (
|
|
DEVOPS_SERVER = "log"
|
|
)
|
|
|
|
type Server struct {
|
|
AppId int `json:"AppId"`
|
|
ServerId int `json:"ServerId"`
|
|
ServerName string `json:"ServerName"`
|
|
Status int `json:"Status"`
|
|
OpenServerTime int `json:"OpenServerTime"`
|
|
Type int `json:"Type"`
|
|
}
|
|
|
|
type ServerInfo struct {
|
|
AppId int `json:"AppId" db:"AppId"`
|
|
ServerId int `json:"ServerId" db:"ServerId"`
|
|
ServerName string `json:"ServerName" db:"ServerName"`
|
|
Status int `json:"Status" db:"Status"`
|
|
CreateTime int `json:"CreateTime" db:"CreateTime"`
|
|
OpenServerTime int `json:"OpenServerTime" db:"OpenServerTime"`
|
|
StartTime int64 `json:"StartTime"`
|
|
PlayerNum int `json:"PlayerNum"`
|
|
}
|
|
|
|
func (s *Server) AppList() ([]*Type.App, error) {
|
|
Db := util.MPool.GetGameDB()
|
|
var app []*Type.App
|
|
err := Db.Select(&app, "SELECT `AppId`, `AppName`, `NodeName`, `MysqlName`, `Topic`, `tz`, `WsHost`, `Database`, `Update`, `Path` FROM app")
|
|
defer Db.Close()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to scan rows: %v", err)
|
|
}
|
|
return app, nil
|
|
}
|
|
|
|
func (s *Server) ServerList() ([]*ServerInfo, error) {
|
|
Db := util.MPool.GetGameDB()
|
|
var server []*ServerInfo
|
|
defer Db.Close()
|
|
err := Db.Select(&server, "SELECT `AppId`, `ServerId`, `ServerName`, `Status`, `CreateTime`, `OpenServerTime` FROM server where AppId = ?", s.AppId)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to scan rows: %v", err)
|
|
}
|
|
|
|
if s.Type == 1 {
|
|
return server, nil
|
|
}
|
|
var w sync.WaitGroup
|
|
for _, v := range server {
|
|
ws, err := util.GetWebsocket(v.AppId, v.ServerId)
|
|
if err != nil {
|
|
v.Status = 0
|
|
continue
|
|
}
|
|
ws.SetReadDeadline(time.Now().Add(2 * time.Second))
|
|
w.Add(1)
|
|
go func(v *ServerInfo) {
|
|
defer w.Done()
|
|
req := &msg.ReqServerInfo{}
|
|
r, err := util.SendAdminMsg(ws, req)
|
|
if err != nil {
|
|
log.Printf("failed to send admin message: %v", err)
|
|
v.Status = 0
|
|
return
|
|
}
|
|
if r["StartTime"] != nil {
|
|
v.StartTime = int64(r["StartTime"].(float64))
|
|
}
|
|
if r["PlayerNum"] != nil {
|
|
v.PlayerNum = int(r["PlayerNum"].(float64))
|
|
}
|
|
v.Status = 1
|
|
ws.Close()
|
|
}(v)
|
|
}
|
|
w.Wait()
|
|
return server, nil
|
|
}
|
|
|
|
func (s *Server) AddServer() error {
|
|
Db := util.MPool.GetGameDB()
|
|
defer Db.Close()
|
|
_, err := Db.Exec("INSERT INTO server (`AppId`, `ServerId`, `ServerName`, `Status`, `CreateTime`, `OpenServerTime`) VALUES (?, ?, ?, ?, ?, ?)",
|
|
s.AppId, s.ServerId, s.ServerName, s.Status, util.Now(), s.OpenServerTime)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to insert: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Server) UpdateApp() (string, error) {
|
|
AppConfig, err := util.GetAppConfig(s.AppId)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
ServerConfig, err := common.GetServerConfig(DEVOPS_SERVER)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
SshClient, err := NewSshClient(ServerConfig)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer SshClient.client.Close()
|
|
_, err = SshClient.RunCommand("cd /data/devops && git pull")
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to git pull: %v", err)
|
|
}
|
|
cmd := fmt.Sprintf("ansible-playbook /data/devops/playbook/%s.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
|
|
output, err := SshClient.RunCommand(cmd)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
DB := util.MPool.GetGameDB()
|
|
defer DB.Close()
|
|
DB.Exec("UPDATE app SET `Update` = ? WHERE `AppId` = ?", util.Now(), s.AppId)
|
|
feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, 执行文件更新完成", AppConfig.AppName))
|
|
|
|
return output, nil
|
|
}
|
|
|
|
func (s *Server) UpdateAppFeishu() (string, error) {
|
|
AppConfig, err := util.GetAppConfig(s.AppId)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
ServerConfig, err := common.GetServerConfig(DEVOPS_SERVER)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
SshClient, err := NewSshClient(ServerConfig)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer SshClient.client.Close()
|
|
_, err = SshClient.RunCommand("cd /data/devops && git pull")
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to git pull: %v", err)
|
|
}
|
|
cmd := fmt.Sprintf("ansible-playbook /data/devops/playbook/%s.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
|
|
output, err := SshClient.RunCommand(cmd)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
DB := util.MPool.GetGameDB()
|
|
defer DB.Close()
|
|
DB.Exec("UPDATE app SET `Update` = ? WHERE `AppId` = ?", util.Now(), s.AppId)
|
|
feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, 执行文件更新完成", AppConfig.AppName))
|
|
return output, nil
|
|
}
|
|
|
|
func (s *Server) RestartServer() (string, error) {
|
|
AppConfig, err := util.GetAppConfig(s.AppId)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
ServerConfig, err := common.GetServerConfig(AppConfig.NodeName)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
SshClient, err := NewSshClient(ServerConfig)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer SshClient.client.Close()
|
|
cmd := fmt.Sprintf("%s/tool/tool restart node %d", AppConfig.Path, s.ServerId)
|
|
output, err := SshClient.RunCommand(cmd)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 重启完成", AppConfig.AppName, s.ServerName))
|
|
return output, nil
|
|
}
|
|
|
|
func (s *Server) ReloadServer() (string, error) {
|
|
AppConfig, err := util.GetAppConfig(s.AppId)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
ws, err := util.GetWebsocket(s.AppId, s.ServerId)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get websocket: %v", err)
|
|
}
|
|
defer ws.Close()
|
|
req := &msg.ReqReload{}
|
|
_, err = util.SendAdminMsg(ws, req)
|
|
if err != nil {
|
|
log.Printf("failed to send admin message: %v", err)
|
|
}
|
|
feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 配置重载完成", AppConfig.AppName, s.ServerName))
|
|
return "success", nil
|
|
}
|
|
|
|
// 端口扫描
|
|
func PortMap(Ip string, Port string) error {
|
|
// 创建一个新的Nmap扫描器
|
|
scanner, err := nmap.NewScanner(
|
|
nmap.WithTargets(Ip), // 替换为你要扫描的目标IP地址
|
|
nmap.WithPorts(Port), // 替换为你要扫描的端口
|
|
// nmap.WithTCPFINScan(), // 使用TCP扫描
|
|
nmap.WithTimingTemplate(nmap.TimingSneaky),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 执行扫描
|
|
result, warnings, err := scanner.Run()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 打印扫描结果
|
|
for _, warning := range warnings {
|
|
log.Printf("nmap 警告: %v", warning)
|
|
}
|
|
|
|
for _, host := range result.Hosts {
|
|
if len(host.Ports) == 0 || host.Status.State != "up" {
|
|
continue
|
|
}
|
|
for _, port := range host.Ports {
|
|
if port.State.State == "filtered" {
|
|
continue
|
|
}
|
|
if port.State.State != "open" {
|
|
return fmt.Errorf("端口 %d 未监听 %v", port.ID, port)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|