Compare commits
No commits in common. "de0f97ce7d6ff178405a27aa8b9249f478535b1e" and "b06f970dd8f17214cb843a7ee48dc2e156b85faa" have entirely different histories.
de0f97ce7d
...
b06f970dd8
|
|
@ -99,11 +99,6 @@ func Init() error {
|
|||
fmt.Println("friend table:", err)
|
||||
}
|
||||
|
||||
err = db.AutoMigrate(&Shell{})
|
||||
if err != nil {
|
||||
fmt.Println("shell table:", err)
|
||||
}
|
||||
|
||||
DB = db
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
85
dao/shell.go
85
dao/shell.go
|
|
@ -1,85 +0,0 @@
|
|||
package dao
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"log"
|
||||
"videoplayer/proto"
|
||||
)
|
||||
|
||||
type Shell struct {
|
||||
gorm.Model
|
||||
AuthID uint `gorm:"column:auth_id"`
|
||||
Server string `gorm:"column:server"`
|
||||
ShellName string `gorm:"column:shell_name"`
|
||||
ShellContent string `gorm:"column:shell_content"`
|
||||
Status int `gorm:"column:status"` // 0 未执行 1 执行中 2 执行完成
|
||||
ShellResult string `gorm:"column:shell_result"`
|
||||
}
|
||||
|
||||
func CreateShell(shellName, shellContent, server string, uid uint) uint {
|
||||
shell := Shell{ShellName: shellName, ShellContent: shellContent, Server: server, AuthID: uid}
|
||||
var res *gorm.DB
|
||||
if proto.Config.SERVER_SQL_LOG {
|
||||
res = DB.Debug().Create(&shell)
|
||||
} else {
|
||||
res = DB.Create(&shell)
|
||||
}
|
||||
if res.Error != nil {
|
||||
return 0
|
||||
}
|
||||
return shell.ID
|
||||
}
|
||||
|
||||
func FindShellByID(id, uid uint) []Shell {
|
||||
var shell Shell
|
||||
var result *gorm.DB
|
||||
|
||||
if proto.Config.SERVER_SQL_LOG {
|
||||
result = DB.Debug().Where("id = ? & auth_id = ?", id, uid).First(&shell)
|
||||
} else {
|
||||
result = DB.Where("id = ? & auth_id = ?", id, uid).First(&shell)
|
||||
}
|
||||
var res []Shell
|
||||
res = append(res, shell)
|
||||
if result.Error != nil {
|
||||
log.Fatalf("FindShellByID failed: %v", result.Error)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func FindShellByAuthID(auth_id int) []Shell {
|
||||
var shells []Shell
|
||||
if proto.Config.SERVER_SQL_LOG {
|
||||
DB.Debug().Exec("select * from shells where auth_id = ? order by created_at desc limit 100", auth_id).Scan(&shells)
|
||||
} else {
|
||||
DB.Exec("select * from shells where auth_id = ? order by created_at desc limit 100", auth_id).Scan(&shells)
|
||||
}
|
||||
return shells
|
||||
}
|
||||
|
||||
func UpdateShellByID(id, authId uint, shellName, shellContent string, status int, shellResult string) bool {
|
||||
pd := FindShellByID(id, authId)
|
||||
if pd[0].ID == 0 {
|
||||
return false
|
||||
}
|
||||
var result *gorm.DB
|
||||
if proto.Config.SERVER_SQL_LOG {
|
||||
result = DB.Debug().Model(&Shell{}).Where("id = ? and auth_id = ?", id, authId).Updates(Shell{ShellName: shellName, ShellContent: shellContent, Status: status, ShellResult: shellResult})
|
||||
} else {
|
||||
result = DB.Model(&Shell{}).Where("id = ? and auth_id = ?", id, authId).Updates(Shell{ShellName: shellName, ShellContent: shellContent, Status: status, ShellResult: shellResult})
|
||||
}
|
||||
if result.Error != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FindShellWillRunByServer(server string, uid uint) []Shell {
|
||||
var shells []Shell
|
||||
if proto.Config.SERVER_SQL_LOG {
|
||||
DB.Debug().Exec("select * from shells where server = ? and auth_id = ? and status = 0 order by created_at desc limit 100", server, uid).Scan(&shells)
|
||||
} else {
|
||||
DB.Exec("select * from shells where server = ? and auth_id = ? and status = 0 order by created_at desc limit 100", server, uid).Scan(&shells)
|
||||
}
|
||||
return shells
|
||||
}
|
||||
104
handler/shell.go
104
handler/shell.go
|
|
@ -1,104 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"videoplayer/proto"
|
||||
"videoplayer/service"
|
||||
)
|
||||
|
||||
type ShellHandler struct {
|
||||
}
|
||||
|
||||
type CreateShellReq struct {
|
||||
ShellName string `json:"shell_name"`
|
||||
ShellContent string `json:"shell_content"`
|
||||
Server string `json:"server"`
|
||||
}
|
||||
type UpdateShellReq struct {
|
||||
ID uint `json:"id"`
|
||||
ShellName string `json:"shell_name"`
|
||||
ShellContent string `json:"shell_content"`
|
||||
Server string `json:"server"`
|
||||
Status int `json:"status"`
|
||||
ShellResult string `json:"shell_result"`
|
||||
}
|
||||
|
||||
type UpdateShellReqV2 struct {
|
||||
Shells []UpdateShellReq `json:"shells"`
|
||||
}
|
||||
|
||||
type UpdateShellResp struct {
|
||||
ID uint `json:"id" form:"id"`
|
||||
Status int `json:"status" form:"status"`
|
||||
}
|
||||
|
||||
func SetUpShellGroup(router *gin.Engine) {
|
||||
shellGroup := router.Group("/shell") //持续集成、部署
|
||||
shellHandler := ShellHandler{}
|
||||
shellGroup.POST("/create", shellHandler.CreateShell)
|
||||
shellGroup.POST("/list", shellHandler.ListShell)
|
||||
shellGroup.POST("/update", shellHandler.UpdateShell)
|
||||
shellGroup.POST("/server_will_run_list", shellHandler.ServerWillRun)
|
||||
}
|
||||
|
||||
func (s *ShellHandler) CreateShell(c *gin.Context) {
|
||||
user_id, _ := c.Get("id")
|
||||
uid := int(user_id.(float64))
|
||||
var req CreateShellReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, gin.H{"code": proto.ShellCreateFailed, "message": "参数错误", "data": err.Error()})
|
||||
} else {
|
||||
id := service.CreateShell(req.ShellName, req.ShellContent, req.Server, uid)
|
||||
if id == 0 {
|
||||
c.JSON(200, gin.H{"code": proto.ShellCreateFailed, "message": "创建失败,id is 0", "data": ""})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "创建成功", "data": id})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ShellHandler) ListShell(c *gin.Context) {
|
||||
user_id, _ := c.Get("id")
|
||||
id := int(user_id.(float64))
|
||||
shells := service.FindShellByAuthID(id)
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "获取成功", "data": shells})
|
||||
}
|
||||
|
||||
func (s *ShellHandler) UpdateShell(c *gin.Context) {
|
||||
var req UpdateShellReqV2
|
||||
user_id, _ := c.Get("id")
|
||||
id := int(user_id.(float64))
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, gin.H{"code": proto.ShellUpdateFailed, "message": "参数错误", "data": err.Error()})
|
||||
} else {
|
||||
var resp []UpdateShellResp
|
||||
for _, v := range req.Shells {
|
||||
if service.UpdateShellByID(v.ID, uint(id), v.ShellName, v.ShellContent, v.Server, v.Status, v.ShellResult) {
|
||||
resp = append(resp, UpdateShellResp{ID: v.ID, Status: v.Status})
|
||||
} else {
|
||||
resp = append(resp, UpdateShellResp{ID: v.ID, Status: -1})
|
||||
}
|
||||
}
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "更新成功", "data": resp})
|
||||
}
|
||||
}
|
||||
|
||||
type ServerWillRunReq struct {
|
||||
Server string `json:"server"`
|
||||
}
|
||||
|
||||
func (s *ShellHandler) ServerWillRun(c *gin.Context) {
|
||||
user_id, _ := c.Get("id")
|
||||
id := int(user_id.(float64))
|
||||
var req ServerWillRunReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(200, gin.H{"code": proto.ShellUpdateFailed, "message": "参数错误", "data": err.Error()})
|
||||
} else {
|
||||
willRunShells, err2 := service.FindShellWillRunByServer(req.Server, id)
|
||||
if err2 != nil {
|
||||
c.JSON(200, gin.H{"code": proto.ShellUpdateFailed, "message": "获取失败", "data": err2.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "获取成功", "data": willRunShells})
|
||||
}
|
||||
}
|
||||
2
main.go
2
main.go
|
|
@ -39,7 +39,6 @@ func main() {
|
|||
handler.SetUpCIDGroup(r) // CID,持续集成、部署
|
||||
handler.SetUpToolGroup(r) // Tool
|
||||
handler.SetUpFileGroup(r) // File
|
||||
handler.SetUpShellGroup(r) // Shell
|
||||
defer dao.Close()
|
||||
defer worker.CloseRedis()
|
||||
//定时任务
|
||||
|
|
@ -198,7 +197,6 @@ func myTask() {
|
|||
}
|
||||
//其它定时任务-通用
|
||||
RunGeneralCron()
|
||||
service.ShellWillRunFromServer()
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,9 +68,4 @@ const (
|
|||
UpdateConfigFailed = 91 // 更新配置失败
|
||||
DeleteConfigFailed = 92 // 删除配置失败
|
||||
SearchConfigFileFailed = 93 // 获取配置失败
|
||||
|
||||
ShellCreateFailed = 100 // 创建shell失败
|
||||
ShellUpdateFailed = 101 // 更新shell失败
|
||||
ShellDeleteFailed = 102 // 删除shell失败
|
||||
ShellSearchFailed = 103 // 获取shell失败
|
||||
)
|
||||
|
|
|
|||
|
|
@ -84,29 +84,3 @@ type SyncUserReq struct {
|
|||
Device string `json:"device" form:"device"`
|
||||
Confirm UserSyncConfirm `json:"confirm" form:"confirm"`
|
||||
}
|
||||
|
||||
// shell待执行
|
||||
type SyncUserShellReq struct {
|
||||
Token string `json:"token" form:"token"`
|
||||
Server string `json:"server" form:"server"`
|
||||
}
|
||||
|
||||
type UpdateShellReq struct {
|
||||
ID uint `json:"id"`
|
||||
ShellName string `json:"shell_name"`
|
||||
ShellContent string `json:"shell_content"`
|
||||
Server string `json:"server"`
|
||||
Status int `json:"status"`
|
||||
ShellResult string `json:"shell_result"`
|
||||
}
|
||||
|
||||
// shell 执行结果返回
|
||||
type SyncUserShellResp struct {
|
||||
Token string `json:"token" form:"token"`
|
||||
Shells []UpdateShellReq `json:"shells" form:"shells"`
|
||||
}
|
||||
|
||||
type UpdateShellRespV2 struct {
|
||||
ID uint `json:"id" form:"id"`
|
||||
Status int `json:"status" form:"status"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"videoplayer/dao"
|
||||
"videoplayer/proto"
|
||||
"videoplayer/worker"
|
||||
)
|
||||
|
||||
func CreateShell(shellName, shellContent, server string, uid int) uint {
|
||||
id := dao.CreateShell(shellName, shellContent, server, uint(uid))
|
||||
return id
|
||||
}
|
||||
|
||||
func FindShellByAuthID(id int) []dao.Shell {
|
||||
return dao.FindShellByAuthID(id)
|
||||
}
|
||||
|
||||
func UpdateShellByID(id, authId uint, shellName, shellContent, server string, status int, shellResult string) bool {
|
||||
return dao.UpdateShellByID(id, authId, shellName, shellContent, status, shellResult)
|
||||
}
|
||||
|
||||
func FindShellWillRunByServer(server string, uid int) ([]dao.Shell, error) {
|
||||
var shells []dao.Shell
|
||||
var err error
|
||||
if server == "" {
|
||||
//err设置为server为空
|
||||
err = errors.New("server is empty")
|
||||
return shells, err
|
||||
}
|
||||
shells = dao.FindShellWillRunByServer(server, uint(uid))
|
||||
//设置状态为执行中
|
||||
for _, v := range shells {
|
||||
dao.UpdateShellByID(v.ID, uint(uid), v.ShellName, v.ShellContent, v.Status+1, v.ShellResult)
|
||||
}
|
||||
return shells, err
|
||||
}
|
||||
|
||||
// 从服务器定时获取shell、执行并返回结果
|
||||
func ShellWillRunFromServer() {
|
||||
shells, err := GetShellWillRunFromMaster(proto.Config.SERVER_NAME)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var resp []proto.UpdateShellReq
|
||||
|
||||
for _, v := range shells {
|
||||
//执行shell脚本,go执行命令
|
||||
res, err2 := RunShell(v.ShellContent)
|
||||
if err2 != "" {
|
||||
resp = append(resp, proto.UpdateShellReq{ID: v.ID, Server: v.Server, Status: 2, ShellResult: err2})
|
||||
} else {
|
||||
resp = append(resp, proto.UpdateShellReq{ID: v.ID, Server: v.Server, Status: 2, ShellResult: res})
|
||||
}
|
||||
}
|
||||
//返回执行结果
|
||||
url := "https://" + proto.Config.MASTER_SERVER_DOMAIN + "/shell/update"
|
||||
var req proto.SyncUserShellResp
|
||||
req.Token = worker.GetRedisSetMembers("super_permission_tokens")[0]
|
||||
req.Shells = resp
|
||||
resp_data, err := worker.SyncDataFromMasterShellReq3(url, req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
//更新执行结果
|
||||
for _, v := range resp_data {
|
||||
if v.Status < 0 {
|
||||
log.Fatalln("update shell failed:", v.ID, v.Status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从服务器从主服务器获取待执行的shell
|
||||
func GetShellWillRunFromMaster(server string) ([]dao.Shell, error) {
|
||||
master := proto.Config.MASTER_SERVER_DOMAIN
|
||||
//发起请求获取待执行的shell
|
||||
url := "https://" + master + "/shell//server_will_run_list"
|
||||
var req proto.SyncUserShellReq
|
||||
req.Server = server
|
||||
req.Token = worker.GetRedisSetMembers("super_permission_tokens")[0]
|
||||
shells, err := worker.SyncDataFromMasterShellReq2(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return shells, nil
|
||||
}
|
||||
|
||||
func RunShell(script string) (res, err string) {
|
||||
cmd := exec.Command("/bin/bash", "-c", script)
|
||||
// 使用bytes.Buffer捕获输出
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err3 := cmd.Run()
|
||||
err3_info := ""
|
||||
if err3 != nil {
|
||||
err3_info = err3.Error()
|
||||
}
|
||||
return strings.TrimSpace(out.String()), err3_info
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"videoplayer/dao"
|
||||
"videoplayer/proto"
|
||||
)
|
||||
|
||||
|
|
@ -136,18 +135,6 @@ type Response struct {
|
|||
Data proto.UserSync `json:"data"`
|
||||
}
|
||||
|
||||
type ShellResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data []dao.Shell `json:"data"`
|
||||
}
|
||||
|
||||
type ShellResponseV2 struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data []proto.UpdateShellRespV2 `json:"data"`
|
||||
}
|
||||
|
||||
// 获取数据,全量及增量
|
||||
func SyncDataFromMasterReq2(url string, data proto.SyncUserReq) (proto.UserSync, error) {
|
||||
defer func() {
|
||||
|
|
@ -191,89 +178,3 @@ func SyncDataFromMasterReq2(url string, data proto.SyncUserReq) (proto.UserSync,
|
|||
fmt.Println("SyncDataFromMasterReq2 result add data:", len(res.Add), "update data:", len(res.Update), "delete data:", len(res.Delete))
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// 获取待执行的shell
|
||||
func SyncDataFromMasterShellReq2(url string, data proto.SyncUserShellReq) ([]dao.Shell, error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("SyncDataFromMasterReq2 error:", r)
|
||||
}
|
||||
}()
|
||||
|
||||
var res []dao.Shell
|
||||
//从接口获取数据
|
||||
json_data, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(json_data))
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
//传输数据
|
||||
if client == nil {
|
||||
client = &http.Client{}
|
||||
}
|
||||
//获取数据
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
//解析数据
|
||||
responseBod, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
var response ShellResponse
|
||||
err = json.Unmarshal(responseBod, &response)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res = response.Data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// 获取待执行的shell
|
||||
func SyncDataFromMasterShellReq3(url string, data proto.SyncUserShellResp) ([]proto.UpdateShellRespV2, error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("SyncDataFromMasterReq2 error:", r)
|
||||
}
|
||||
}()
|
||||
|
||||
var res []proto.UpdateShellRespV2
|
||||
//从接口获取数据
|
||||
json_data, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(json_data))
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
//传输数据
|
||||
if client == nil {
|
||||
client = &http.Client{}
|
||||
}
|
||||
//获取数据
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
//解析数据
|
||||
responseBod, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
var response ShellResponseV2
|
||||
err = json.Unmarshal(responseBod, &response)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res = response.Data
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue