liuhaijun e94826ce29 add server
Change-Id: I0760f17f6a01c0121b59fcbfafc666032dbc30af
2024-09-19 09:44:15 +00:00

459 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package outgiving
import (
"encoding/json"
err1 "errors"
"fmt"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/controller"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/controller/v1/app_manage"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/middleware"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/app_manage/node"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/app_manage/out_giving"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/app_manage/server_white_list"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/app_manage/system_parameters"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/user"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/errors"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/request"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/response"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/service/app_manage/common"
node2 "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/service/app_manage/node"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/pkg/log"
"github.com/gin-gonic/gin"
"strings"
"time"
)
// 创建分发项目
func SavePorject(c *gin.Context) {
bodyToMap := request.GetBodyToMap(c)
typeStr, _ := bodyToMap["type"].(string)
id, _ := bodyToMap["id"].(string)
workspaceId := app_manage.GetWorkspaceId(c)
bodyToMap["workspace_id"] = workspaceId
userObject, _ := c.Get(middleware.LoginUserKey)
userModel := userObject.(*user.UserObj)
if "add" == typeStr {
checkId := strings.ReplaceAll(id, "-", "")
checkId = strings.ReplaceAll(checkId, "_", "")
err := validateID(checkId)
if err != nil {
controller.FailCode(c, errors.ServerError, err, err.Error())
return
}
addOutGiving(c, id, bodyToMap, userModel)
} else {
updateGiving(c, id, bodyToMap, userModel)
}
}
func DeletePorject(c *gin.Context) {
bodyToMap := request.GetBodyToMap(c)
id, ok := bodyToMap["id"]
if !ok {
controller.Fail(c, errors.ServerError, "id不能为空")
return
}
thorough, ok := bodyToMap["thorough"]
if !ok {
controller.Fail(c, errors.ServerError, "id不能为空")
return
}
outGivingModel := out_giving.GetOutGivingModelById(id.(string))
if outGivingModel == nil {
controller.Fail(c, errors.ServerError, "没有找到对应的分发项目")
return
}
// 该项目不是节点分发项目,不能在此次删除
if !outGivingModel.OutGivingProject {
controller.Fail(c, errors.ServerError, "该项目不是节点分发项目,不能在此处删除")
return
}
outGivingNodeProjectList := outGivingModel.GetOutGivingNodeProjectList()
for _, outGivingNodeProject := range outGivingNodeProjectList {
nodeModel := node.GetNodeById(outGivingNodeProject.NodeId)
if nodeModel.Id == "" {
controller.Fail(c, errors.ServerError, "没有找到对应的节点")
return
}
resp := deleteNodeProject(nodeModel, outGivingModel.Id, thorough.(string))
if resp.Result.Code != errors.SUCCESS {
controller.FailCode(c, errors.ServerError, err1.New(resp.Result.Msg), nodeModel.Name+"节点失败: "+resp.Result.Msg)
return
}
}
rows, err := out_giving.DeleteOutGivingModelById(id.(string))
if err != nil {
controller.FailCode(c, errors.ServerError, err, "删除分发失败")
return
}
if rows >= 0 {
out_giving.DeleteOutGivingLogByOutGivingId(id.(string))
}
controller.Success(c, "删除成功")
}
func addOutGiving(c *gin.Context, id string, body map[string]interface{}, userObj *user.UserObj) {
byId := out_giving.GetOutGivingModelById(id)
if byId.Id != "" {
controller.FailCode(c, errors.ServerError, nil, "项目id已存在")
return
}
outGivingModel := out_giving.NewOutGivingModel()
outGivingModel.Id = id
outGivingModel.OutGivingProject = true
outGivingModel.CreateUser = userObj.UserID
outGivingModel.ModifyUser = userObj.UserID
tuples, err := doData(outGivingModel, body, false)
if err != nil {
controller.FailCode(c, errors.ServerError, err, err.Error())
return
}
_, err = outGivingModel.Create(outGivingModel)
if err != nil {
controller.FailCode(c, errors.ServerError, nil, "项目id已存在")
return
}
// saveNodeData
res := saveNodeData(outGivingModel, tuples, false)
if res != nil {
controller.Fail(c, errors.ServerError, res.Result.Msg)
return
}
controller.Success(c, "添加成功")
}
func updateGiving(c *gin.Context, id string, body map[string]interface{}, userObj *user.UserObj) {
outGivingModel := out_giving.GetOutGivingModelById(id)
if outGivingModel == nil {
controller.Fail(c, errors.ServerError, "没有找到对应的分发id")
return
}
tuples, err := doData(outGivingModel, body, true)
if err != nil {
controller.FailCode(c, errors.ServerError, err, err.Error())
return
}
outGivingModel.ModifyUser = userObj.UserID
outGivingModel.ModifyTimeMillis = time.Now().UnixMilli()
err = out_giving.UpdateOutGivingModel(outGivingModel, []string{"name", "group", "workspace_id", "after_opt", "secondary_directory",
"out_giving_node_project_list", "clear_old", "upload_close_first", "secondary_directory", "modify_user", "modify_time_millis"})
if err != nil {
controller.FailCode(c, errors.ServerError, err, "修改失败")
return
}
// saveNodeData 保存节点项目数据
res := saveNodeData(outGivingModel, tuples, true)
if res != nil {
controller.Fail(c, errors.ServerError, res.Result.Msg)
return
}
controller.Success(c, "修改成功")
}
// 保存节点项目数据
func saveNodeData(outGivingModel *out_giving.OutGivingModel, tuples map[string]map[string]interface{}, edit bool) *response.Response {
successTuples := map[string]interface{}{}
fail := false
for key, value := range tuples {
nodeModelId := key
n, _ := app_manage.TryGetNode(map[string]interface{}{"nodeId": nodeModelId})
dataJSON := value
jsonMessage := sendData(n, dataJSON, true)
if jsonMessage.Result.Code != errors.SUCCESS {
if !edit {
out_giving.DeleteOutGivingModelById(outGivingModel.Id)
fail = true
}
if fail {
for nodeModelId, _ = range successTuples {
resp := deleteNodeProject(n, outGivingModel.Id, "")
if resp.Result.Code != errors.SUCCESS {
log.Errorf("还原项目失败:" + resp.Result.Msg)
}
}
}
jsonMessage.Result.Msg = n.Name + "节点失败:" + jsonMessage.Result.Msg
return jsonMessage
}
successTuples[key] = value
// 同步项目信息
node2.SyncNodeProjectInfo(n, outGivingModel.Id)
}
return nil
}
// 创建项目管理的默认数据
func getDefData(outGivingModel *out_giving.OutGivingModel, body map[string]interface{}, edit bool) (map[string]interface{}, error) {
defData := make(map[string]interface{})
defData["id"] = outGivingModel.Id
defData["name"] = outGivingModel.Name
defData["group"] = outGivingModel.Group
runMode := body["runMode"]
defData["runMode"] = runMode
if runMode == "Dsl" {
dslContent := body["dslContent"]
defData["dslContent"] = dslContent
}
whitelistDirectory := body["whitelistDirectory"]
// 获取白名单
s := &system_parameters.SystemParameters{}
s.Id = server_white_list.GetId(outGivingModel.WorkspaceId)
_ = s.GetById(s)
serverWhitelist := &server_white_list.ServerWhitelist{}
if s.Value != "" {
err := json.Unmarshal([]byte(s.Value), serverWhitelist)
if err != nil {
return nil, err
}
}
var outGivingArray []string
if strings.Contains(serverWhitelist.OutGiving, "\r\n") == true {
outGivingArray = strings.Split(serverWhitelist.OutGiving, "\r\n")
} else {
outGivingArray = strings.Split(serverWhitelist.OutGiving, "\n")
}
checkPath := server_white_list.CheckPath(outGivingArray, whitelistDirectory.(string))
if !checkPath {
return nil, fmt.Errorf("请选择正确的项目路径,或者还没有配置白名单")
}
defData["whitelistDirectory"] = whitelistDirectory
logPath := body["logPath"]
if logPath != nil && strings.TrimSpace(logPath.(string)) != "" {
checkPath = server_white_list.CheckPath(outGivingArray, whitelistDirectory.(string))
if !checkPath {
return nil, fmt.Errorf("请选择正确的日志路径,或者还没有配置白名单")
}
defData["logPath"] = logPath
}
lib := body["lib"]
defData["lib"] = lib
if edit {
defData["edit"] = "on"
}
defData["previewData"] = true
return defData, nil
}
// 参考outGivingProjectEditController.example.json
func doData(outGivingModel *out_giving.OutGivingModel, body map[string]interface{}, edit bool) (map[string]map[string]interface{}, error) {
tuples := make(map[string]map[string]interface{})
outGivingModel.Name = body["name"].(string)
if outGivingModel.Name == "" {
return tuples, fmt.Errorf("分发名称不能为空")
}
outGivingModel.WorkspaceId = body["workspace_id"].(string)
if groupStr, ok := body["group"]; ok {
if groupStr != nil {
s := groupStr.(string)
outGivingModel.Group = &s
}
}
if afterOpt, ok := body["afterOpt"]; ok {
afterOptInt, err := afterOpt.(float64)
if err != true {
return tuples, fmt.Errorf("参数有误afterOpt")
}
outGivingModel.AfterOpt = int(afterOptInt)
} else {
return tuples, fmt.Errorf("请选择分发后的操作")
}
outGivingModel.IntervalTime = 10
if clearOld, ok := body["clearOld"]; ok {
//toBool := utils.StringToBool(clearOld.(string))
outGivingModel.ClearOld = clearOld.(bool)
}
if secondaryDirectory, ok := body["secondaryDirectory"]; ok {
if secondaryDirectory != nil {
s := secondaryDirectory.(string)
outGivingModel.SecondaryDirectory = &s
}
}
if uploadCloseFirst, ok := body["uploadCloseFirst"]; ok {
//toBool := utils.StringToBool(uploadCloseFirst.(string))
outGivingModel.UploadCloseFirst = uploadCloseFirst.(bool)
}
// 填充其他数据
defData, err := getDefData(outGivingModel, body, edit)
if err != nil {
return tuples, err
}
//
nodeIdsStr := body["nodeIds"]
nodeIds := strings.Split(nodeIdsStr.(string), ",")
if len(nodeIds) == 0 {
return tuples, fmt.Errorf("没有任何节点信息")
}
outGivingModels := out_giving.ListOutGivingModel()
outGivingNodeProjects := make([]out_giving.OutGivingNodeProject, 0)
var outGivingNodeProject *out_giving.OutGivingNodeProject
for _, nodeId := range nodeIds {
nodeModel, err := app_manage.TryGetNode(map[string]interface{}{"nodeId": nodeId})
if err != nil {
return tuples, fmt.Errorf("对应的节点不存在")
}
// 判断项目是否已被使用,还要兼容新增和编辑两种场景!
if outGivingModels != nil {
for _, model := range outGivingModels {
if strings.EqualFold(model.Id, outGivingModel.Id) {
continue
}
contains := model.CheckContains(nodeId, outGivingModel.Id)
if contains {
return tuples, fmt.Errorf("已经存在相同的分发项目: %s", outGivingModel.Id)
}
}
}
nodeProjectList := outGivingModel.GetOutGivingNodeProjectList()
// 分发 ID 等同于项目 ID
outGivingNodeProject = outGivingModel.GetNodeProject(nodeProjectList, nodeModel.Id, outGivingModel.Id)
if outGivingNodeProject == nil {
outGivingNodeProject = &out_giving.OutGivingNodeProject{}
}
outGivingNodeProject.NodeId = nodeModel.Id
// 分发id为项目id
outGivingNodeProject.ProjectId = outGivingModel.Id
outGivingNodeProjects = append(outGivingNodeProjects, *outGivingNodeProject)
// 准备并检查数据
allData := cloneMap(defData)
token := body[(fmt.Sprintf("%s_token", nodeModel.Id))]
allData["token"] = token
jvm := body[fmt.Sprintf("%s_jvm", nodeModel.Id)]
allData["jvm"] = jvm
args := body[fmt.Sprintf("%s_args", nodeModel.Id)]
allData["args"] = args
autoStart := body[fmt.Sprintf("%s_autoStart", nodeModel.Id)]
//allData["autoStart"] = autoStart.(bool)
if _, ok := autoStart.(bool); ok {
allData["autoStart"] = autoStart.(bool)
}
dslEnv := body[fmt.Sprintf("%s_dslEnv", nodeModel.Id)]
allData["dslEnv"] = dslEnv
jsonMessage := sendData(nodeModel, allData, false)
if jsonMessage.Result.Code != errors.SUCCESS {
return tuples, fmt.Errorf("%s节点失败%s", nodeModel.Name, jsonMessage.Result.Msg)
}
tuples[nodeModel.Id] = allData
}
if len(outGivingNodeProjects) == 0 {
return tuples, fmt.Errorf("至少选择1个节点项目")
}
// 删除已经删除的项目
err = deleteProject(outGivingModel, outGivingNodeProjects)
if err != nil {
return nil, fmt.Errorf("删除项目失败: %s", err.Error())
}
outGivingModel.SetOutGivingNodeProjectList(outGivingNodeProjects)
return tuples, nil
}
// 删除已经删除过的项目
func deleteProject(outGivingModel *out_giving.OutGivingModel, outGivingNodeProjects []out_giving.OutGivingNodeProject) error {
// 获取需要删除的节点项目
deleteNodeProjects := outGivingModel.GetDelete(outGivingNodeProjects)
if deleteNodeProjects != nil {
for _, outGivingNodeProject := range deleteNodeProjects {
nodeModel, err := app_manage.TryGetNode(map[string]interface{}{"nodeId": outGivingNodeProject.NodeId})
if err != nil {
return fmt.Errorf("节点不存在")
}
//outGivingNodeProject.GetNodeData(true) // 假设这是获取某些数据的操作,需根据实际情况实现或忽略
// 彻底删除节点项目
jsonMessage := deleteNodeProject(nodeModel, outGivingNodeProject.ProjectId, "thorough")
if jsonMessage.Result.Code != errors.SUCCESS {
return fmt.Errorf("%s节点失败%s", nodeModel.Name, jsonMessage.Result.Msg)
}
}
}
return nil
}
// 删除项目
func deleteNodeProject(nodeModel *node.Node, projectId, thorough string) *response.Response {
data := make(map[string]interface{})
data["id"] = projectId
data["thorough"] = thorough
data["nodeId"] = nodeModel.Id
resp := app_manage.TryRequestNode("", data, common.Manage_DeleteProject)
if resp.Result.Code == errors.SUCCESS {
node2.SyncNodeProjectInfo(nodeModel, projectId)
}
return resp
}
func sendData(nodeModel *node.Node, data map[string]interface{}, save bool) *response.Response {
if save {
delete(data, "previewData")
}
data["outGivingProject"] = true
data["nodeId"] = nodeModel.Id
return app_manage.TryRequestNode("", data, common.Manage_SaveProject)
}
func cloneMap(body map[string]interface{}) map[string]interface{} {
clone := make(map[string]interface{})
for k, v := range body {
// 注意这里仅实现了浅拷贝如果value本身是复杂的数据结构如嵌套的map或slice
// 那么这个拷贝过程不会递归拷贝内部结构,它们仍然会被共享。
clone[k] = v
}
return clone
}