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

505 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 assets
import (
"bytes"
"encoding/json"
err1 "errors"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/controller"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model"
node2 "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/workspace"
"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/service"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/service/app_manage/assets"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/service/app_manage/common"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/validator"
"github.com/gin-gonic/gin"
"strconv"
"strings"
)
type MachinePageBody struct {
PageInfo *request.PageInfo `json:"pageInfo" binding:"required"`
Name string `json:"name"`
Version string `json:"version"`
GroupName string `json:"groupName"`
}
type T struct {
GroupName string `json:"groupName"`
Version string `json:"version"`
Name string `json:"name"`
PageInfo struct {
CurrentPage int `json:"currentPage"`
Order string `json:"order"`
OrderField string `json:"order_field"`
PageSize int `json:"pageSize"`
} `json:"pageInfo"`
}
func PageMachine(c *gin.Context) {
var pageBody MachinePageBody
err := c.ShouldBindJSON(&pageBody)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
//pageBody.PageInfo.Order = "create_time_millis desc"
n := node2.NewMachine()
fields := map[string]interface{}{}
if pageBody.Name != "" {
fields["name"] = pageBody.Name
}
if pageBody.Version != "" {
fields["cfn_agent_version"] = pageBody.Version
}
if pageBody.GroupName != "" {
fields["group_name"] = pageBody.GroupName
}
page := &model.PageConfig{}
page.Covert(pageBody.PageInfo)
result, err := n.Page(n, page, fields)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "内部错误!")
return
}
page.Data = result
controller.Success(c, page)
}
func EditMachine(c *gin.Context) {
n := &node2.MachineNode{}
err := validator.CheckPostParams(c, n)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
if n.Id == "" {
n.Handler = n
fields := map[string]interface{}{}
fields["cfn_agent_url"] = n.CfnAgentUrl
list, err := n.GetAll(n, fields, nil)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
if len(list.([]node2.MachineNode)) > 0 {
controller.FailCode(c, errors.InvalidParameter, err, "对应的节点已经存在啦")
return
}
}
err = assets.TestMachineNode(n)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "节点连接失败,请检查节点是否在线")
return
}
status := 1
n.Status = status
// testHttpProxy()
if n.Id == "" {
m := 0
n.TransportMode = m
n.SetUserName(service.GetUserName(c))
_, err = n.Create(n)
} else {
n.SetModifyUserName(service.GetUserName(c))
column := []string{"name", "group_name", "cfn_agent_url", "cfn_agent_username", "cfn_agent_password", "template_node", "cfn_agent_timeout", "cfn_agent_http_proxy", "cfn_agent_http_proxy_type", "transport_encryption"}
_, err = n.Update(n, column)
}
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
controller.Success(c, "")
}
func DeleteMachine(c *gin.Context) {
id := c.PostForm("id")
if id == "" {
controller.FailCode(c, errors.InvalidParameter, nil, "请检查参数!")
return
}
m := &node2.MachineNode{}
m.Id = id
err := m.GetById(m)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, nil, "请检查参数!")
return
}
n := node2.New()
fields := make(map[string]interface{})
fields["machine_id"] = id
list, err := n.GetAll(n, fields, nil)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
count := len(list.([]node2.Node))
if count > 0 {
controller.FailCode(c, errors.ServerError, err, "当前机器还关联"+strconv.Itoa(count)+"个节点,不能删除")
return
}
_, err = m.Delete(m)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
controller.Success(c, "")
}
func Distribute(c *gin.Context) {
ids := c.PostForm("ids")
if ids == "" {
controller.Success(c, "")
return
}
mids := strings.Split(ids, ",")
if len(mids) == 0 {
controller.Success(c, "")
return
}
workspaceId := c.PostForm("workspaceId")
w := &workspace.Workspace{}
w.Id = workspaceId
err := w.GetById(w)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "工作空间不存在!")
return
}
fields := map[string]interface{}{}
fields["workspace_id"] = workspaceId
for _, mid := range mids {
m := &node2.MachineNode{}
m.Id = mid
err = m.GetById(m)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "机器不存在!")
return
}
n := node2.New()
fields["machine_id"] = mid
list, _ := n.GetAll(n, fields, nil)
if len(list.([]node2.Node)) > 0 {
continue
}
n = &node2.Node{}
n.MachineId = m.Id
n.WorkspaceId = workspaceId
n.Name = m.Name
n.OpenStatus = 1
n.Group = m.Group
n.Url = m.CfnAgentUrl
n.LoginName = m.CfnAgentUsername
n.LoginPwd = m.CfnAgentPassword
n.SetUserName(service.GetUserName(c))
_, err = n.Create(n)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
}
controller.Success(c, "")
}
func ListMachineGroup(c *gin.Context) {
m := &node2.MachineNode{}
result, _ := m.ListGroup()
controller.Success(c, result)
}
func ListTemplateNode(c *gin.Context) {
m := node2.NewMachine()
fields := map[string]interface{}{}
fields["template_node"] = 1
result, err := m.GetAll(m, fields, nil)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
controller.Success(c, result)
}
func Whitelist(c *gin.Context) {
machineId := c.PostForm("machineId")
m := &node2.MachineNode{}
m.Id = machineId
err := m.GetById(m)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "没有对应的机器")
return
}
result := assets.GetAgentWhitelist(m)
controller.Success(c, result)
}
func SaveWhitelist(c *gin.Context) {
ids := c.PostForm("ids")
if ids == "" {
controller.Success(c, "")
return
}
mids := strings.Split(ids, ",")
if len(mids) == 0 {
controller.Success(c, "")
return
}
formData := make(map[string]string)
for key, value := range c.Request.PostForm {
formData[key] = value[0]
}
body, _ := json.Marshal(formData)
for _, mid := range mids {
m := &node2.MachineNode{}
m.Id = mid
err := m.GetById(m)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "没有对应的机器")
return
}
resp, err := common.Request(m, "", common.WhitelistDirectory_Submit, nil, nil, bytes.NewReader(body))
if err != nil {
controller.FailCode(c, errors.ServerError, err, "分发节点失败")
return
}
if !resp.IsBusinessSuccess() {
controller.FailCode(c, errors.ServerError, err1.New(resp.Result.Msg), "分发节点失败")
return
}
}
controller.Success(c, "")
}
const config_data = `jpom:
# jpom 数据存储路径, 如果调试模式运行默认路径为【${user.home}/jpom/】,安装运行默认为jar包文件的父级
path:
# 集群配置
cluster:
# 集群Id默认为 default 不区分大小写,只能是字母或者数字,长度小于 20
id: default
# 心跳监控时间 (需要大于零) 单位秒 最小配置 5 秒
heart-second: 30
node:
# 节点心跳监控时间 (需要大于零) 单位秒 最小配置 5秒
heart-second: 30
# 节点统计日志保留天数,如果小于等于 0 不自动删除
stat-log-keep-days: 3
# 上传文件的超时时间 单位秒,最短5秒钟
upload-file-timeout: 300
# 节点文件分片上传大小,单位 M建议小于 5MB需要考虑插件端上传文件大小限制
upload-file-slice-size: 1
# 节点文件分片上传并发数,最小1 最大 服务端 CPU 核心数
upload-file-concurrent: 2
# web socket 消息最大长度
web-socket-message-size-limit: 5MB
system:
# cron 定时器是否开启匹配秒
timer-match-second: false
# 旧包文件保留个数
old-jars-count: 2
# 系统日志编码格式
log-charset: UTF-8
# 控制台编码格式
console-charset:
# 在线升级允许降级-操作
allowed-downgrade: false
user:
# 用户连续登录失败次数,超过此数将被限制登录
always-login-error: 5
# IP连续登录失败次数超过此数将被限制登录
always-ip-login-error: 10
# 当ip连续登录失败锁定对应IP时长5h、1d
ip-error-lock-time: 5h
# 是否强制提醒用户开启 mfa
force-mfa: false
#登录token失效时间(单位:小时),默认为24
token-expired: 24
#登录token失效后自动续签时间单位分钟默认为60不自动续签
token-renewal: 60
# jwt 签名(加密)的key 长度建议控制到 16位
token-jwt-key:
web:
# 前端接口 超时时间 单位秒(最小 5 秒)
api-timeout: 20
# 禁用页面引导导航
disabled-guide: false
# 禁用登录图形验证码 (一般用于服务器没有字体或者开启了两部验证后才关闭图形验证码)
disabled-captcha: false
# 前端消息弹出位置,可选 topLeft topRight bottomLeft bottomRight
notification-placement:
# 前端消息传输需要编码或者加密 目前支持NONE、BASE64
transport-encryption: NONE
# 查看日志时初始读取最后多少行默认100不读取
init-read-line: 10
db:
# 数据库默认 支持 H2、MYSQL
mode: H2
# 日志存储条数,将自动清理旧数据,配置小于等于零则不清理
log-storage-count: 10000
# H2 模式无需配置 mysql 配置 jdbc 地址
url:
# 数据库账号 默认 jpom
user-name: jpom
# 数据库密码 默认 jpom 如果自行配置请保证密码强度
user-pwd: jpom
# h2 数据库缓存大小 kilobyte 1KB 1,024 megabyte 1MB 1,048,576
cache-size: 50MB
# 自动备份间隔天数 小于等于 0 不自动备份
auto-backup-interval-day: 1
# 自动备份保留天数 小于等于 0不自动删除自动备份数据
auto-backup-reserve-day: 5
# 数据库连接池相关配置
max-active: 500
initial-size: 10
max-wait: 10
min-idle: 1
# 控制台是否打印 sql 信息
show-sql: false
# 构建相关配置
build:
# 最多保存多少份历史记录
max-history-count: 1000
# 单个最多保存多少份历史记录
item-max-history-count: 50
# 构建命令是否检查 存在删除命令
check-delete-command: true
# 构建线程池大小,小于 1 则为不限制,默认大小为 5
pool-size: 5
# 构建任务等待数量,超过此数量将取消构建任务,值最小为 1
pool-wait-queue: 10
# 日志显示 压缩折叠显示进度比例 范围 1-100
log-reduce-progress-ratio: 5
file-storage:
# 文件中心存储路径
save-pah:
scan-static-dir-cron: 0 0/1 * * *
# 是否开启静态文件目录监听
watch-monitor-static-dir: true
# 监听静态文件目录层级
watch-monitor-max-depth: 5
assets:
# 监控线程池大小,小于等于0 为CPU核心数
monitor-pool-size: 0
# 监控任务等待数量,超过此数量将取消监控任务,值最小为 1
monitor-pool-wait-queue: 500
# ssh 资产
ssh:
# 监控频率
monitor-cron: 0 0/1 * * * ?
# 指定分组不启用监控功能(如果想禁用所有配置 * 即可)
disable-monitor-group-name:
- 禁用监控
# docker 资产
docker:
# 监控频率
monitor-cron: 0 0/1 * * * ?
server:
#运行端口号
port: 2122
servlet:
session:
cookie:
name: JPOMID-SERVER
timeout: 1H
encoding:
charset: UTF-8
force: true
enabled: true
forceRequest: true
forceResponse: true
compression:
# gzip 压缩
enabled: true
#mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,image/png
min-response-size: 2048
tomcat:
uri-encoding: UTF-8
spring:
web:
resources:
static-locations: classpath:/dist/
cache:
period: 1D
mvc:
throw-exception-if-no-handler-found: true
log-request-details: true
servlet:
multipart:
# 上传文件大小限制
max-request-size: 2GB
max-file-size: 1GB
h2:
console:
# 是否开启 web 访问数据库url: http://${ip}:${port}/h2-console
enabled: false
# 是否允许远程访问(开启此配置有安全风险),默认为 false当部署到服务器上之后是否可以通过其他浏览器访问数据库
settings:
web-allow-others: false
`
func ConfigData(c *gin.Context) {
machineId := c.PostForm("machineId")
m := &node2.MachineNode{}
m.Id = machineId
err := m.GetById(m)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "没有对应的机器")
return
}
resp, err := common.Request3(m, "", common.SystemGetConfig, nil)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "分发节点失败")
return
}
if !resp.IsBusinessSuccess() {
controller.FailCode(c, errors.ServerError, err1.New(resp.Result.Msg), "分发节点失败")
return
}
controller.Success(c, resp.Result.Data)
}
// todo 暂不允许修改运行配置
func SaveConfig(c *gin.Context) {
ids := c.PostForm("ids")
if ids == "" {
controller.Success(c, "")
return
}
mids := strings.Split(ids, ",")
if len(mids) == 0 {
controller.Success(c, "")
return
}
content := c.PostForm("content")
restart := c.PostForm("restart")
formData := make(map[string]string)
formData["content"] = content
formData["restart"] = restart
for _, mid := range mids {
m := &node2.MachineNode{}
m.Id = mid
err := m.GetById(m)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "没有对应的机器")
return
}
resp, err := common.Request4(m, common.SystemSaveConfig, formData)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "分发节点失败")
return
}
if !resp.IsSuccess() {
controller.FailCode(c, errors.ServerError, err1.New(resp.Result.Msg), "分发节点失败")
return
}
}
controller.Success(c, "修改成功")
}