mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-04 00:10:25 +08:00
refactor: machine包调整
This commit is contained in:
@@ -159,7 +159,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, toRefs, reactive, onMounted, defineAsyncComponent, nextTick } from 'vue';
|
import { ref, toRefs, reactive, onMounted, defineAsyncComponent } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { machineApi, getMachineTerminalSocketUrl } from './api';
|
import { machineApi, getMachineTerminalSocketUrl } from './api';
|
||||||
@@ -358,7 +358,9 @@ const deleteMachine = async () => {
|
|||||||
await machineApi.del.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
await machineApi.del.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
||||||
ElMessage.success('操作成功');
|
ElMessage.success('操作成功');
|
||||||
search();
|
search();
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const serviceManager = (row: any) => {
|
const serviceManager = (row: any) => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package dbm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/internal/common/consts"
|
"mayfly-go/internal/common/consts"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -19,7 +19,7 @@ var connCache = cache.NewTimedCache(consts.DbConnExpireTime, 5*time.Second).
|
|||||||
})
|
})
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
machine.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||||
// 遍历所有db连接实例,若存在db实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
// 遍历所有db连接实例,若存在db实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
||||||
items := connCache.Items()
|
items := connCache.Items()
|
||||||
for _, v := range items {
|
for _, v := range items {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/internal/machine/api/vo"
|
"mayfly-go/internal/machine/api/vo"
|
||||||
"mayfly-go/internal/machine/application"
|
"mayfly-go/internal/machine/application"
|
||||||
"mayfly-go/internal/machine/domain/entity"
|
"mayfly-go/internal/machine/domain/entity"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
tagapp "mayfly-go/internal/tag/application"
|
tagapp "mayfly-go/internal/tag/application"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/config"
|
"mayfly-go/pkg/config"
|
||||||
@@ -54,7 +54,7 @@ func (m *Machine) Machines(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, mv := range *res.List {
|
for _, mv := range *res.List {
|
||||||
mv.HasCli = machine.HasCli(mv.Id)
|
mv.HasCli = mcm.HasCli(mv.Id)
|
||||||
}
|
}
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ func (m *Machine) DeleteMachine(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 关闭机器客户端
|
// 关闭机器客户端
|
||||||
func (m *Machine) CloseCli(rc *req.Ctx) {
|
func (m *Machine) CloseCli(rc *req.Ctx) {
|
||||||
machine.DeleteCli(GetMachineId(rc.GinCtx))
|
mcm.DeleteCli(GetMachineId(rc.GinCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取进程列表信息
|
// 获取进程列表信息
|
||||||
@@ -133,7 +133,7 @@ func (m *Machine) GetProcess(rc *req.Ctx) {
|
|||||||
|
|
||||||
cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
|
cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
|
||||||
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
||||||
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
|
||||||
|
|
||||||
res, err := cli.Run(cmd)
|
res, err := cli.Run(cmd)
|
||||||
biz.ErrIsNilAppendErr(err, "获取进程信息失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取进程信息失败: %s")
|
||||||
@@ -147,7 +147,7 @@ func (m *Machine) KillProcess(rc *req.Ctx) {
|
|||||||
|
|
||||||
cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
|
cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
|
||||||
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
||||||
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
|
||||||
|
|
||||||
res, err := cli.Run("sudo kill -9 " + pid)
|
res, err := cli.Run("sudo kill -9 " + pid)
|
||||||
biz.ErrIsNil(err, "终止进程失败: %s", res)
|
biz.ErrIsNil(err, "终止进程失败: %s", res)
|
||||||
@@ -173,30 +173,30 @@ func (m *Machine) WsSSH(g *gin.Context) {
|
|||||||
|
|
||||||
cli, err := m.MachineApp.GetCli(GetMachineId(g))
|
cli, err := m.MachineApp.GetCli(GetMachineId(g))
|
||||||
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
||||||
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
|
||||||
|
|
||||||
cols := ginx.QueryInt(g, "cols", 80)
|
cols := ginx.QueryInt(g, "cols", 80)
|
||||||
rows := ginx.QueryInt(g, "rows", 40)
|
rows := ginx.QueryInt(g, "rows", 40)
|
||||||
|
|
||||||
var recorder *machine.Recorder
|
var recorder *mcm.Recorder
|
||||||
if cli.GetMachine().EnableRecorder == 1 {
|
if cli.Info.EnableRecorder == 1 {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
// 回放文件路径为: 基础配置路径/机器id/操作日期/操作者账号/操作时间.cast
|
// 回放文件路径为: 基础配置路径/机器id/操作日期/操作者账号/操作时间.cast
|
||||||
recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.GetMachine().Id, now.Format("20060102"), rc.LoginAccount.Username)
|
recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.Info.Id, now.Format("20060102"), rc.LoginAccount.Username)
|
||||||
os.MkdirAll(recPath, 0766)
|
os.MkdirAll(recPath, 0766)
|
||||||
fileName := path.Join(recPath, fmt.Sprintf("%s.cast", now.Format("20060102_150405")))
|
fileName := path.Join(recPath, fmt.Sprintf("%s.cast", now.Format("20060102_150405")))
|
||||||
f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0766)
|
f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0766)
|
||||||
biz.ErrIsNilAppendErr(err, "创建终端回放记录文件失败: %s")
|
biz.ErrIsNilAppendErr(err, "创建终端回放记录文件失败: %s")
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
recorder = machine.NewRecorder(f)
|
recorder = mcm.NewRecorder(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
mts, err := machine.NewTerminalSession(stringx.Rand(16), wsConn, cli, rows, cols, recorder)
|
mts, err := mcm.NewTerminalSession(stringx.Rand(16), wsConn, cli, rows, cols, recorder)
|
||||||
biz.ErrIsNilAppendErr(err, "\033[1;31m连接失败: %s\033[0m")
|
biz.ErrIsNilAppendErr(err, "\033[1;31m连接失败: %s\033[0m")
|
||||||
|
|
||||||
// 记录系统操作日志
|
// 记录系统操作日志
|
||||||
rc.WithLog(req.NewLogSave("机器-终端操作"))
|
rc.WithLog(req.NewLogSave("机器-终端操作"))
|
||||||
rc.ReqParam = cli.GetMachine()
|
rc.ReqParam = cli.Info
|
||||||
req.LogHandler(rc)
|
req.LogHandler(rc)
|
||||||
|
|
||||||
mts.Start()
|
mts.Start()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"mayfly-go/internal/machine/api/vo"
|
"mayfly-go/internal/machine/api/vo"
|
||||||
"mayfly-go/internal/machine/application"
|
"mayfly-go/internal/machine/application"
|
||||||
"mayfly-go/internal/machine/domain/entity"
|
"mayfly-go/internal/machine/domain/entity"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
msgapp "mayfly-go/internal/msg/application"
|
msgapp "mayfly-go/internal/msg/application"
|
||||||
msgdto "mayfly-go/internal/msg/application/dto"
|
msgdto "mayfly-go/internal/msg/application/dto"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
@@ -72,7 +72,7 @@ func (m *MachineFile) CreateFile(rc *req.Ctx) {
|
|||||||
path := form.Path
|
path := form.Path
|
||||||
|
|
||||||
attrs := collx.Kvs("path", path)
|
attrs := collx.Kvs("path", path)
|
||||||
var mi *machine.Info
|
var mi *mcm.MachineInfo
|
||||||
var err error
|
var err error
|
||||||
if form.Type == dir {
|
if form.Type == dir {
|
||||||
attrs["type"] = "目录"
|
attrs["type"] = "目录"
|
||||||
@@ -231,7 +231,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
folderName := filepath.Dir(paths[0])
|
folderName := filepath.Dir(paths[0])
|
||||||
mcli, err := m.MachineFileApp.GetMachineCli(fid, basePath+"/"+folderName)
|
mcli, err := m.MachineFileApp.GetMachineCli(fid, basePath+"/"+folderName)
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
mi := mcli.GetMachine()
|
mi := mcli.Info
|
||||||
|
|
||||||
sftpCli, err := mcli.GetSftpCli()
|
sftpCli, err := mcli.GetSftpCli()
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
@@ -261,6 +261,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
// 设置要等待的协程数量
|
// 设置要等待的协程数量
|
||||||
wg.Add(len(chunks))
|
wg.Add(len(chunks))
|
||||||
|
|
||||||
|
isSuccess := true
|
||||||
la := rc.LoginAccount
|
la := rc.LoginAccount
|
||||||
for _, chunk := range chunks {
|
for _, chunk := range chunks {
|
||||||
go func(files []FolderFile, wg *sync.WaitGroup) {
|
go func(files []FolderFile, wg *sync.WaitGroup) {
|
||||||
@@ -268,6 +269,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
// 协程执行完成后调用Done方法
|
// 协程执行完成后调用Done方法
|
||||||
wg.Done()
|
wg.Done()
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
|
isSuccess = false
|
||||||
logx.Errorf("文件上传失败: %s", err)
|
logx.Errorf("文件上传失败: %s", err)
|
||||||
switch t := err.(type) {
|
switch t := err.(type) {
|
||||||
case errorx.BizError:
|
case errorx.BizError:
|
||||||
@@ -294,8 +296,10 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
|
|
||||||
// 等待所有协程执行完成
|
// 等待所有协程执行完成
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
if isSuccess {
|
||||||
// 保存消息并发送文件上传成功通知
|
// 保存消息并发送文件上传成功通知
|
||||||
m.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.SuccessSysMsg("文件上传成功", fmt.Sprintf("[%s]文件夹已成功上传至 %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
|
m.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.SuccessSysMsg("文件上传成功", fmt.Sprintf("[%s]文件夹已成功上传至 %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MachineFile) RemoveFile(rc *req.Ctx) {
|
func (m *MachineFile) RemoveFile(rc *req.Ctx) {
|
||||||
|
|||||||
@@ -70,11 +70,11 @@ func (m *MachineScript) RunMachineScript(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
cli, err := m.MachineApp.GetCli(machineId)
|
cli, err := m.MachineApp.GetCli(machineId)
|
||||||
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
|
||||||
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
|
||||||
|
|
||||||
res, err := cli.Run(script)
|
res, err := cli.Run(script)
|
||||||
// 记录请求参数
|
// 记录请求参数
|
||||||
rc.ReqParam = collx.Kvs("machine", cli.GetMachine(), "scriptId", scriptId, "name", ms.Name)
|
rc.ReqParam = collx.Kvs("machine", cli.Info, "scriptId", scriptId, "name", ms.Name)
|
||||||
if res == "" {
|
if res == "" {
|
||||||
biz.ErrIsNilAppendErr(err, "执行命令失败:%s")
|
biz.ErrIsNilAppendErr(err, "执行命令失败:%s")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"mayfly-go/internal/machine/api/vo"
|
"mayfly-go/internal/machine/api/vo"
|
||||||
"mayfly-go/internal/machine/domain/entity"
|
"mayfly-go/internal/machine/domain/entity"
|
||||||
"mayfly-go/internal/machine/domain/repository"
|
"mayfly-go/internal/machine/domain/repository"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
"mayfly-go/pkg/base"
|
"mayfly-go/pkg/base"
|
||||||
"mayfly-go/pkg/errorx"
|
"mayfly-go/pkg/errorx"
|
||||||
"mayfly-go/pkg/gormx"
|
"mayfly-go/pkg/gormx"
|
||||||
@@ -32,10 +32,10 @@ type Machine interface {
|
|||||||
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error)
|
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error)
|
||||||
|
|
||||||
// 获取机器连接
|
// 获取机器连接
|
||||||
GetCli(id uint64) (*machine.Cli, error)
|
GetCli(id uint64) (*mcm.Cli, error)
|
||||||
|
|
||||||
// 获取ssh隧道机器连接
|
// 获取ssh隧道机器连接
|
||||||
GetSshTunnelMachine(id int) (*machine.SshTunnelMachine, error)
|
GetSshTunnelMachine(id int) (*mcm.SshTunnelMachine, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMachineApp(machineRepo repository.Machine, authCertApp AuthCert) Machine {
|
func newMachineApp(machineRepo repository.Machine, authCertApp AuthCert) Machine {
|
||||||
@@ -84,7 +84,7 @@ func (m *machineAppImpl) Save(me *entity.Machine) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 关闭连接
|
// 关闭连接
|
||||||
machine.DeleteCli(me.Id)
|
mcm.DeleteCli(me.Id)
|
||||||
return m.UpdateById(me)
|
return m.UpdateById(me)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,16 +94,18 @@ func (m *machineAppImpl) TestConn(me *entity.Machine) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
cli, err := mi.Conn()
|
||||||
return machine.TestConn(*mi, func(u uint64) (*machine.Info, error) {
|
if err != nil {
|
||||||
return m.toMachineInfoById(u)
|
return err
|
||||||
})
|
}
|
||||||
|
cli.Close()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
|
func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
|
||||||
if status == entity.MachineStatusDisable {
|
if status == entity.MachineStatusDisable {
|
||||||
// 关闭连接
|
// 关闭连接
|
||||||
machine.DeleteCli(id)
|
mcm.DeleteCli(id)
|
||||||
}
|
}
|
||||||
machine := new(entity.Machine)
|
machine := new(entity.Machine)
|
||||||
machine.Id = id
|
machine.Id = id
|
||||||
@@ -114,7 +116,7 @@ func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
|
|||||||
// 根据条件获取机器信息
|
// 根据条件获取机器信息
|
||||||
func (m *machineAppImpl) Delete(id uint64) error {
|
func (m *machineAppImpl) Delete(id uint64) error {
|
||||||
// 关闭连接
|
// 关闭连接
|
||||||
machine.DeleteCli(id)
|
mcm.DeleteCli(id)
|
||||||
return gormx.Tx(
|
return gormx.Tx(
|
||||||
func(db *gorm.DB) error {
|
func(db *gorm.DB) error {
|
||||||
// 删除machine表信息
|
// 删除machine表信息
|
||||||
@@ -131,20 +133,20 @@ func (m *machineAppImpl) Delete(id uint64) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineAppImpl) GetCli(machineId uint64) (*machine.Cli, error) {
|
func (m *machineAppImpl) GetCli(machineId uint64) (*mcm.Cli, error) {
|
||||||
return machine.GetCli(machineId, func(mid uint64) (*machine.Info, error) {
|
return mcm.GetMachineCli(machineId, func(mid uint64) (*mcm.MachineInfo, error) {
|
||||||
return m.toMachineInfoById(mid)
|
return m.toMachineInfoById(mid)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineAppImpl) GetSshTunnelMachine(machineId int) (*machine.SshTunnelMachine, error) {
|
func (m *machineAppImpl) GetSshTunnelMachine(machineId int) (*mcm.SshTunnelMachine, error) {
|
||||||
return machine.GetSshTunnelMachine(machineId, func(mid uint64) (*machine.Info, error) {
|
return mcm.GetSshTunnelMachine(machineId, func(mid uint64) (*mcm.MachineInfo, error) {
|
||||||
return m.toMachineInfoById(mid)
|
return m.toMachineInfoById(mid)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成机器信息,根据授权凭证id填充用户密码等
|
// 生成机器信息,根据授权凭证id填充用户密码等
|
||||||
func (m *machineAppImpl) toMachineInfoById(machineId uint64) (*machine.Info, error) {
|
func (m *machineAppImpl) toMachineInfoById(machineId uint64) (*mcm.MachineInfo, error) {
|
||||||
me, err := m.GetById(new(entity.Machine), machineId)
|
me, err := m.GetById(new(entity.Machine), machineId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorx.NewBiz("机器信息不存在")
|
return nil, errorx.NewBiz("机器信息不存在")
|
||||||
@@ -153,20 +155,22 @@ func (m *machineAppImpl) toMachineInfoById(machineId uint64) (*machine.Info, err
|
|||||||
return nil, errorx.NewBiz("该机器已被停用")
|
return nil, errorx.NewBiz("该机器已被停用")
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.toMachineInfo(me)
|
if mi, err := m.toMachineInfo(me); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return mi, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineAppImpl) toMachineInfo(me *entity.Machine) (*machine.Info, error) {
|
func (m *machineAppImpl) toMachineInfo(me *entity.Machine) (*mcm.MachineInfo, error) {
|
||||||
mi := new(machine.Info)
|
mi := new(mcm.MachineInfo)
|
||||||
mi.Id = me.Id
|
mi.Id = me.Id
|
||||||
mi.Name = me.Name
|
mi.Name = me.Name
|
||||||
mi.Ip = me.Ip
|
mi.Ip = me.Ip
|
||||||
mi.Port = me.Port
|
mi.Port = me.Port
|
||||||
mi.Username = me.Username
|
mi.Username = me.Username
|
||||||
mi.TagId = me.TagId
|
|
||||||
mi.TagPath = me.TagPath
|
mi.TagPath = me.TagPath
|
||||||
mi.EnableRecorder = me.EnableRecorder
|
mi.EnableRecorder = me.EnableRecorder
|
||||||
mi.SshTunnelMachineId = me.SshTunnelMachineId
|
|
||||||
|
|
||||||
if me.UseAuthCert() {
|
if me.UseAuthCert() {
|
||||||
ac, err := m.authCertApp.GetById(new(entity.AuthCert), uint64(me.AuthCertId))
|
ac, err := m.authCertApp.GetById(new(entity.AuthCert), uint64(me.AuthCertId))
|
||||||
@@ -184,5 +188,18 @@ func (m *machineAppImpl) toMachineInfo(me *entity.Machine) (*machine.Info, error
|
|||||||
}
|
}
|
||||||
mi.Password = me.Password
|
mi.Password = me.Password
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用了ssh隧道,则将隧道机器信息也附上
|
||||||
|
if me.SshTunnelMachineId > 0 {
|
||||||
|
sshTunnelMe, err := m.GetById(new(entity.Machine), uint64(me.SshTunnelMachineId))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errorx.NewBiz("隧道机器信息不存在")
|
||||||
|
}
|
||||||
|
sshTunnelMi, err := m.toMachineInfo(sshTunnelMe)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mi.SshTunnelMachine = sshTunnelMi
|
||||||
|
}
|
||||||
return mi, nil
|
return mi, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"mayfly-go/internal/machine/domain/entity"
|
"mayfly-go/internal/machine/domain/entity"
|
||||||
"mayfly-go/internal/machine/domain/repository"
|
"mayfly-go/internal/machine/domain/repository"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
"mayfly-go/pkg/errorx"
|
"mayfly-go/pkg/errorx"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
@@ -32,18 +32,18 @@ type MachineFile interface {
|
|||||||
Delete(id uint64) error
|
Delete(id uint64) error
|
||||||
|
|
||||||
// 获取文件关联的机器信息,主要用于记录日志使用
|
// 获取文件关联的机器信息,主要用于记录日志使用
|
||||||
// GetMachine(fileId uint64) *machine.Info
|
// GetMachine(fileId uint64) *mcm.Info
|
||||||
|
|
||||||
// 检查文件路径,并返回机器id
|
// 检查文件路径,并返回机器id
|
||||||
GetMachineCli(fileId uint64, path ...string) (*machine.Cli, error)
|
GetMachineCli(fileId uint64, path ...string) (*mcm.Cli, error)
|
||||||
|
|
||||||
/** sftp 相关操作 **/
|
/** sftp 相关操作 **/
|
||||||
|
|
||||||
// 创建目录
|
// 创建目录
|
||||||
MkDir(fid uint64, path string) (*machine.Info, error)
|
MkDir(fid uint64, path string) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
// 创建文件
|
// 创建文件
|
||||||
CreateFile(fid uint64, path string) (*machine.Info, error)
|
CreateFile(fid uint64, path string) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
// 读取目录
|
// 读取目录
|
||||||
ReadDir(fid uint64, path string) ([]fs.FileInfo, error)
|
ReadDir(fid uint64, path string) ([]fs.FileInfo, error)
|
||||||
@@ -55,22 +55,22 @@ type MachineFile interface {
|
|||||||
FileStat(fid uint64, path string) (string, error)
|
FileStat(fid uint64, path string) (string, error)
|
||||||
|
|
||||||
// 读取文件内容
|
// 读取文件内容
|
||||||
ReadFile(fileId uint64, path string) (*sftp.File, *machine.Info, error)
|
ReadFile(fileId uint64, path string) (*sftp.File, *mcm.MachineInfo, error)
|
||||||
|
|
||||||
// 写文件
|
// 写文件
|
||||||
WriteFileContent(fileId uint64, path string, content []byte) (*machine.Info, error)
|
WriteFileContent(fileId uint64, path string, content []byte) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
// 文件上传
|
// 文件上传
|
||||||
UploadFile(fileId uint64, path, filename string, reader io.Reader) (*machine.Info, error)
|
UploadFile(fileId uint64, path, filename string, reader io.Reader) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
// 移除文件
|
// 移除文件
|
||||||
RemoveFile(fileId uint64, path ...string) (*machine.Info, error)
|
RemoveFile(fileId uint64, path ...string) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
Copy(fileId uint64, toPath string, paths ...string) (*machine.Info, error)
|
Copy(fileId uint64, toPath string, paths ...string) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
Mv(fileId uint64, toPath string, paths ...string) (*machine.Info, error)
|
Mv(fileId uint64, toPath string, paths ...string) (*mcm.MachineInfo, error)
|
||||||
|
|
||||||
Rename(fileId uint64, oldname string, newname string) (*machine.Info, error)
|
Rename(fileId uint64, oldname string, newname string) (*mcm.MachineInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMachineFileApp(machineFileRepo repository.MachineFile, machineApp Machine) MachineFile {
|
func newMachineFileApp(machineFileRepo repository.MachineFile, machineApp Machine) MachineFile {
|
||||||
@@ -163,7 +163,7 @@ func (m *machineFileAppImpl) FileStat(fid uint64, path string) (string, error) {
|
|||||||
return mcli.Run(fmt.Sprintf("stat -L %s", path))
|
return mcli.Run(fmt.Sprintf("stat -L %s", path))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineFileAppImpl) MkDir(fid uint64, path string) (*machine.Info, error) {
|
func (m *machineFileAppImpl) MkDir(fid uint64, path string) (*mcm.MachineInfo, error) {
|
||||||
if !strings.HasSuffix(path, "/") {
|
if !strings.HasSuffix(path, "/") {
|
||||||
path = path + "/"
|
path = path + "/"
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ func (m *machineFileAppImpl) MkDir(fid uint64, path string) (*machine.Info, erro
|
|||||||
return mi, err
|
return mi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineFileAppImpl) CreateFile(fid uint64, path string) (*machine.Info, error) {
|
func (m *machineFileAppImpl) CreateFile(fid uint64, path string) (*mcm.MachineInfo, error) {
|
||||||
mi, sftpCli, err := m.GetMachineSftpCli(fid, path)
|
mi, sftpCli, err := m.GetMachineSftpCli(fid, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -191,7 +191,7 @@ func (m *machineFileAppImpl) CreateFile(fid uint64, path string) (*machine.Info,
|
|||||||
return mi, err
|
return mi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineFileAppImpl) ReadFile(fileId uint64, path string) (*sftp.File, *machine.Info, error) {
|
func (m *machineFileAppImpl) ReadFile(fileId uint64, path string) (*sftp.File, *mcm.MachineInfo, error) {
|
||||||
mi, sftpCli, err := m.GetMachineSftpCli(fileId, path)
|
mi, sftpCli, err := m.GetMachineSftpCli(fileId, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -203,7 +203,7 @@ func (m *machineFileAppImpl) ReadFile(fileId uint64, path string) (*sftp.File, *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写文件内容
|
// 写文件内容
|
||||||
func (m *machineFileAppImpl) WriteFileContent(fileId uint64, path string, content []byte) (*machine.Info, error) {
|
func (m *machineFileAppImpl) WriteFileContent(fileId uint64, path string, content []byte) (*mcm.MachineInfo, error) {
|
||||||
mi, sftpCli, err := m.GetMachineSftpCli(fileId, path)
|
mi, sftpCli, err := m.GetMachineSftpCli(fileId, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -219,7 +219,7 @@ func (m *machineFileAppImpl) WriteFileContent(fileId uint64, path string, conten
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
func (m *machineFileAppImpl) UploadFile(fileId uint64, path, filename string, reader io.Reader) (*machine.Info, error) {
|
func (m *machineFileAppImpl) UploadFile(fileId uint64, path, filename string, reader io.Reader) (*mcm.MachineInfo, error) {
|
||||||
if !strings.HasSuffix(path, "/") {
|
if !strings.HasSuffix(path, "/") {
|
||||||
path = path + "/"
|
path = path + "/"
|
||||||
}
|
}
|
||||||
@@ -239,12 +239,12 @@ func (m *machineFileAppImpl) UploadFile(fileId uint64, path, filename string, re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
func (m *machineFileAppImpl) RemoveFile(fileId uint64, path ...string) (*machine.Info, error) {
|
func (m *machineFileAppImpl) RemoveFile(fileId uint64, path ...string) (*mcm.MachineInfo, error) {
|
||||||
mcli, err := m.GetMachineCli(fileId, path...)
|
mcli, err := m.GetMachineCli(fileId, path...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
minfo := mcli.GetMachine()
|
minfo := mcli.Info
|
||||||
|
|
||||||
// 优先使用命令删除(速度快),sftp需要递归遍历删除子文件等
|
// 优先使用命令删除(速度快),sftp需要递归遍历删除子文件等
|
||||||
res, err := mcli.Run(fmt.Sprintf("rm -rf %s", strings.Join(path, " ")))
|
res, err := mcli.Run(fmt.Sprintf("rm -rf %s", strings.Join(path, " ")))
|
||||||
@@ -267,13 +267,13 @@ func (m *machineFileAppImpl) RemoveFile(fileId uint64, path ...string) (*machine
|
|||||||
return minfo, err
|
return minfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineFileAppImpl) Copy(fileId uint64, toPath string, paths ...string) (*machine.Info, error) {
|
func (m *machineFileAppImpl) Copy(fileId uint64, toPath string, paths ...string) (*mcm.MachineInfo, error) {
|
||||||
mcli, err := m.GetMachineCli(fileId, paths...)
|
mcli, err := m.GetMachineCli(fileId, paths...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mi := mcli.GetMachine()
|
mi := mcli.Info
|
||||||
res, err := mcli.Run(fmt.Sprintf("cp -r %s %s", strings.Join(paths, " "), toPath))
|
res, err := mcli.Run(fmt.Sprintf("cp -r %s %s", strings.Join(paths, " "), toPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mi, errors.New(res)
|
return mi, errors.New(res)
|
||||||
@@ -281,13 +281,13 @@ func (m *machineFileAppImpl) Copy(fileId uint64, toPath string, paths ...string)
|
|||||||
return mi, err
|
return mi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineFileAppImpl) Mv(fileId uint64, toPath string, paths ...string) (*machine.Info, error) {
|
func (m *machineFileAppImpl) Mv(fileId uint64, toPath string, paths ...string) (*mcm.MachineInfo, error) {
|
||||||
mcli, err := m.GetMachineCli(fileId, paths...)
|
mcli, err := m.GetMachineCli(fileId, paths...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mi := mcli.GetMachine()
|
mi := mcli.Info
|
||||||
res, err := mcli.Run(fmt.Sprintf("mv %s %s", strings.Join(paths, " "), toPath))
|
res, err := mcli.Run(fmt.Sprintf("mv %s %s", strings.Join(paths, " "), toPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mi, errorx.NewBiz(res)
|
return mi, errorx.NewBiz(res)
|
||||||
@@ -295,7 +295,7 @@ func (m *machineFileAppImpl) Mv(fileId uint64, toPath string, paths ...string) (
|
|||||||
return mi, err
|
return mi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineFileAppImpl) Rename(fileId uint64, oldname string, newname string) (*machine.Info, error) {
|
func (m *machineFileAppImpl) Rename(fileId uint64, oldname string, newname string) (*mcm.MachineInfo, error) {
|
||||||
mi, sftpCli, err := m.GetMachineSftpCli(fileId, newname)
|
mi, sftpCli, err := m.GetMachineSftpCli(fileId, newname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -304,7 +304,7 @@ func (m *machineFileAppImpl) Rename(fileId uint64, oldname string, newname strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取文件机器cli
|
// 获取文件机器cli
|
||||||
func (m *machineFileAppImpl) GetMachineCli(fid uint64, inputPath ...string) (*machine.Cli, error) {
|
func (m *machineFileAppImpl) GetMachineCli(fid uint64, inputPath ...string) (*mcm.Cli, error) {
|
||||||
mf := m.GetById(fid)
|
mf := m.GetById(fid)
|
||||||
if mf == nil {
|
if mf == nil {
|
||||||
return nil, errorx.NewBiz("文件不存在")
|
return nil, errorx.NewBiz("文件不存在")
|
||||||
@@ -320,7 +320,7 @@ func (m *machineFileAppImpl) GetMachineCli(fid uint64, inputPath ...string) (*ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取文件机器 sftp cli
|
// 获取文件机器 sftp cli
|
||||||
func (m *machineFileAppImpl) GetMachineSftpCli(fid uint64, inputPath ...string) (*machine.Info, *sftp.Client, error) {
|
func (m *machineFileAppImpl) GetMachineSftpCli(fid uint64, inputPath ...string) (*mcm.MachineInfo, *sftp.Client, error) {
|
||||||
mcli, err := m.GetMachineCli(fid, inputPath...)
|
mcli, err := m.GetMachineCli(fid, inputPath...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -331,5 +331,5 @@ func (m *machineFileAppImpl) GetMachineSftpCli(fid uint64, inputPath ...string)
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return mcli.GetMachine(), sftpCli, nil
|
return mcli.Info, sftpCli, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,291 +0,0 @@
|
|||||||
package machine
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"mayfly-go/internal/common/consts"
|
|
||||||
"mayfly-go/internal/machine/domain/entity"
|
|
||||||
"mayfly-go/pkg/cache"
|
|
||||||
"mayfly-go/pkg/errorx"
|
|
||||||
"mayfly-go/pkg/logx"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/sftp"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 机器信息
|
|
||||||
type Info struct {
|
|
||||||
Id uint64 `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Ip string `json:"ip"` // IP地址
|
|
||||||
Port int `json:"-"` // 端口号
|
|
||||||
|
|
||||||
AuthMethod int8 `json:"-"` // 授权认证方式
|
|
||||||
Username string `json:"-"` // 用户名
|
|
||||||
Password string `json:"-"`
|
|
||||||
Passphrase string `json:"-"` // 私钥口令
|
|
||||||
|
|
||||||
Status int8 `json:"-"` // 状态 1:启用;2:停用
|
|
||||||
SshTunnelMachineId int `json:"-"` // ssh隧道机器id
|
|
||||||
EnableRecorder int8 `json:"-"` // 是否启用终端回放记录
|
|
||||||
TagId uint64 `json:"-"`
|
|
||||||
TagPath string `json:"tagPath"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Info) UseSshTunnel() bool {
|
|
||||||
return m.SshTunnelMachineId > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取记录日志的描述
|
|
||||||
func (m *Info) GetLogDesc() string {
|
|
||||||
return fmt.Sprintf("Machine[id=%d, tag=%s, name=%s, ip=%s:%d]", m.Id, m.TagPath, m.Name, m.Ip, m.Port)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 客户端信息
|
|
||||||
type Cli struct {
|
|
||||||
machine *Info
|
|
||||||
|
|
||||||
client *ssh.Client // ssh客户端
|
|
||||||
sftpClient *sftp.Client // sftp客户端
|
|
||||||
|
|
||||||
sshTunnelMachineId int
|
|
||||||
}
|
|
||||||
|
|
||||||
// 连接
|
|
||||||
func (c *Cli) connect() error {
|
|
||||||
// 如果已经有client则直接返回
|
|
||||||
if c.client != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
m := c.machine
|
|
||||||
sshClient, err := GetSshClient(m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.client = sshClient
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭client并从缓存中移除,如果使用隧道则也关闭
|
|
||||||
func (c *Cli) Close() {
|
|
||||||
m := c.machine
|
|
||||||
logx.Info(fmt.Sprintf("关闭机器客户端连接-> id: %d, name: %s, ip: %s", m.Id, m.Name, m.Ip))
|
|
||||||
if c.client != nil {
|
|
||||||
c.client.Close()
|
|
||||||
c.client = nil
|
|
||||||
}
|
|
||||||
if c.sftpClient != nil {
|
|
||||||
c.sftpClient.Close()
|
|
||||||
c.sftpClient = nil
|
|
||||||
}
|
|
||||||
if c.sshTunnelMachineId > 0 {
|
|
||||||
CloseSshTunnelMachine(c.sshTunnelMachineId, c.machine.Id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取sftp client
|
|
||||||
func (c *Cli) GetSftpCli() (*sftp.Client, error) {
|
|
||||||
if c.client == nil {
|
|
||||||
if err := c.connect(); err != nil {
|
|
||||||
return nil, errorx.NewBiz("连接ssh失败: %s", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sftpclient := c.sftpClient
|
|
||||||
// 如果sftpClient为nil,则连接
|
|
||||||
if sftpclient == nil {
|
|
||||||
sc, serr := sftp.NewClient(c.client)
|
|
||||||
if serr != nil {
|
|
||||||
return nil, errorx.NewBiz("获取sftp client失败: %s", serr.Error())
|
|
||||||
}
|
|
||||||
sftpclient = sc
|
|
||||||
c.sftpClient = sftpclient
|
|
||||||
}
|
|
||||||
|
|
||||||
return sftpclient, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取session
|
|
||||||
func (c *Cli) GetSession() (*ssh.Session, error) {
|
|
||||||
if c.client == nil {
|
|
||||||
if err := c.connect(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c.client.NewSession()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行shell
|
|
||||||
// @param shell shell脚本命令
|
|
||||||
// @return 返回执行成功或错误的消息
|
|
||||||
func (c *Cli) Run(shell string) (string, error) {
|
|
||||||
session, err := c.GetSession()
|
|
||||||
if err != nil {
|
|
||||||
c.Close()
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer session.Close()
|
|
||||||
buf, err := session.CombinedOutput(shell)
|
|
||||||
if err != nil {
|
|
||||||
return string(buf), err
|
|
||||||
}
|
|
||||||
return string(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Cli) GetMachine() *Info {
|
|
||||||
return c.machine
|
|
||||||
}
|
|
||||||
|
|
||||||
// 机器客户端连接缓存,指定时间内没有访问则会被关闭
|
|
||||||
var cliCache = cache.NewTimedCache(consts.MachineConnExpireTime, 5*time.Second).
|
|
||||||
WithUpdateAccessTime(true).
|
|
||||||
OnEvicted(func(_, value any) {
|
|
||||||
value.(*Cli).Close()
|
|
||||||
})
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
|
||||||
// 遍历所有机器连接实例,若存在机器连接实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
|
||||||
items := cliCache.Items()
|
|
||||||
for _, v := range items {
|
|
||||||
if v.Value.(*Cli).sshTunnelMachineId == machineId {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否存在指定id的客户端连接
|
|
||||||
func HasCli(machineId uint64) bool {
|
|
||||||
if _, ok := cliCache.Get(machineId); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除指定机器客户端,并关闭客户端连接
|
|
||||||
func DeleteCli(id uint64) {
|
|
||||||
cliCache.Delete(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从缓存中获取客户端信息,不存在则回调获取机器信息函数,并新建
|
|
||||||
func GetCli(machineId uint64, getMachine func(uint64) (*Info, error)) (*Cli, error) {
|
|
||||||
if load, ok := cliCache.Get(machineId); ok {
|
|
||||||
return load.(*Cli), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
me, err := getMachine(machineId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = IfUseSshTunnelChangeIpPort(me, getMachine)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errorx.NewBiz("ssh隧道连接失败: %s", err.Error())
|
|
||||||
}
|
|
||||||
c, err := newClient(me)
|
|
||||||
if err != nil {
|
|
||||||
CloseSshTunnelMachine(me.SshTunnelMachineId, me.Id)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.sshTunnelMachineId = me.SshTunnelMachineId
|
|
||||||
|
|
||||||
cliCache.Put(machineId, c)
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 测试连接,使用传值的方式,而非引用。因为如果使用了ssh隧道,则ip和端口会变为本地映射地址与端口
|
|
||||||
func TestConn(me Info, getSshTunnelMachine func(uint64) (*Info, error)) error {
|
|
||||||
originId := me.Id
|
|
||||||
if originId == 0 {
|
|
||||||
// 随机设置一个ip,如果使用了隧道则用于临时保存隧道
|
|
||||||
me.Id = uint64(time.Now().Nanosecond())
|
|
||||||
}
|
|
||||||
|
|
||||||
err := IfUseSshTunnelChangeIpPort(&me, getSshTunnelMachine)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ssh隧道连接失败: %s", err.Error())
|
|
||||||
}
|
|
||||||
if me.UseSshTunnel() {
|
|
||||||
defer CloseSshTunnelMachine(me.SshTunnelMachineId, me.Id)
|
|
||||||
}
|
|
||||||
sshClient, err := GetSshClient(&me)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer sshClient.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果使用了ssh隧道,则修改机器ip port为暴露的ip port
|
|
||||||
func IfUseSshTunnelChangeIpPort(me *Info, getMachine func(uint64) (*Info, error)) error {
|
|
||||||
if !me.UseSshTunnel() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
sshTunnelMachine, err := GetSshTunnelMachine(me.SshTunnelMachineId, func(u uint64) (*Info, error) {
|
|
||||||
return getMachine(u)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
exposeIp, exposePort, err := sshTunnelMachine.OpenSshTunnel(me.Id, me.Ip, me.Port)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// 修改机器ip地址
|
|
||||||
me.Ip = exposeIp
|
|
||||||
me.Port = exposePort
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetSshClient(m *Info) (*ssh.Client, error) {
|
|
||||||
config := &ssh.ClientConfig{
|
|
||||||
User: m.Username,
|
|
||||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
Timeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.AuthMethod == entity.AuthCertAuthMethodPassword {
|
|
||||||
config.Auth = []ssh.AuthMethod{ssh.Password(m.Password)}
|
|
||||||
} else if m.AuthMethod == entity.MachineAuthMethodPublicKey {
|
|
||||||
var key ssh.Signer
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if len(m.Passphrase) > 0 {
|
|
||||||
key, err = ssh.ParsePrivateKeyWithPassphrase([]byte(m.Password), []byte(m.Passphrase))
|
|
||||||
} else {
|
|
||||||
key, err = ssh.ParsePrivateKey([]byte(m.Password))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
|
|
||||||
}
|
|
||||||
|
|
||||||
addr := fmt.Sprintf("%s:%d", m.Ip, m.Port)
|
|
||||||
sshClient, err := ssh.Dial("tcp", addr, config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return sshClient, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据机器信息创建客户端对象
|
|
||||||
func newClient(machine *Info) (*Cli, error) {
|
|
||||||
if machine == nil {
|
|
||||||
return nil, errorx.NewBiz("机器不存在")
|
|
||||||
}
|
|
||||||
|
|
||||||
logx.Infof("[%s]机器连接:%s:%d", machine.Name, machine.Ip, machine.Port)
|
|
||||||
cli := new(Cli)
|
|
||||||
cli.machine = machine
|
|
||||||
err := cli.connect()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return cli, nil
|
|
||||||
}
|
|
||||||
97
server/internal/machine/mcm/client.go
Normal file
97
server/internal/machine/mcm/client.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package mcm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"mayfly-go/pkg/errorx"
|
||||||
|
"mayfly-go/pkg/logx"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/sftp"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 机器客户端
|
||||||
|
type Cli struct {
|
||||||
|
Info *MachineInfo // 机器信息
|
||||||
|
|
||||||
|
sshClient *ssh.Client // ssh客户端
|
||||||
|
sftpClient *sftp.Client // sftp客户端
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取sftp client
|
||||||
|
func (c *Cli) GetSftpCli() (*sftp.Client, error) {
|
||||||
|
if c.sshClient == nil {
|
||||||
|
return nil, errorx.NewBiz("请先进行机器客户端连接")
|
||||||
|
}
|
||||||
|
sftpclient := c.sftpClient
|
||||||
|
// 如果sftpClient为nil,则连接
|
||||||
|
if sftpclient == nil {
|
||||||
|
sc, serr := sftp.NewClient(c.sshClient)
|
||||||
|
if serr != nil {
|
||||||
|
return nil, errorx.NewBiz("获取sftp client失败: %s", serr.Error())
|
||||||
|
}
|
||||||
|
sftpclient = sc
|
||||||
|
c.sftpClient = sftpclient
|
||||||
|
}
|
||||||
|
|
||||||
|
return sftpclient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取session
|
||||||
|
func (c *Cli) GetSession() (*ssh.Session, error) {
|
||||||
|
if c.sshClient == nil {
|
||||||
|
return nil, errorx.NewBiz("请先进行机器客户端连接")
|
||||||
|
}
|
||||||
|
return c.sshClient.NewSession()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行shell
|
||||||
|
// @param shell shell脚本命令
|
||||||
|
// @return 返回执行成功或错误的消息
|
||||||
|
func (c *Cli) Run(shell string) (string, error) {
|
||||||
|
session, err := c.GetSession()
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer session.Close()
|
||||||
|
buf, err := session.CombinedOutput(shell)
|
||||||
|
if err != nil {
|
||||||
|
return string(buf), err
|
||||||
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取机器的所有状态信息
|
||||||
|
func (c *Cli) GetAllStats() *Stats {
|
||||||
|
res, _ := c.Run(StatsShell)
|
||||||
|
infos := strings.Split(res, "-----")
|
||||||
|
stats := new(Stats)
|
||||||
|
getUptime(infos[0], stats)
|
||||||
|
getHostname(infos[1], stats)
|
||||||
|
getLoad(infos[2], stats)
|
||||||
|
getMemInfo(infos[3], stats)
|
||||||
|
getFSInfo(infos[4], stats)
|
||||||
|
getInterfaces(infos[5], stats)
|
||||||
|
getInterfaceInfo(infos[6], stats)
|
||||||
|
getCPU(infos[7], stats)
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭client并从缓存中移除,如果使用隧道则也关闭
|
||||||
|
func (c *Cli) Close() {
|
||||||
|
m := c.Info
|
||||||
|
logx.Info(fmt.Sprintf("关闭机器客户端连接-> id: %d, name: %s, ip: %s", m.Id, m.Name, m.Ip))
|
||||||
|
if c.sshClient != nil {
|
||||||
|
c.sshClient.Close()
|
||||||
|
c.sshClient = nil
|
||||||
|
}
|
||||||
|
if c.sftpClient != nil {
|
||||||
|
c.sftpClient.Close()
|
||||||
|
c.sftpClient = nil
|
||||||
|
}
|
||||||
|
if c.Info.SshTunnelMachine != nil {
|
||||||
|
logx.Infof("关闭机器的隧道信息: machineId=%d, sshTunnelMachineId=%d", c.Info.Id, c.Info.SshTunnelMachine.Id)
|
||||||
|
CloseSshTunnelMachine(int(c.Info.SshTunnelMachine.Id), c.Info.Id)
|
||||||
|
}
|
||||||
|
}
|
||||||
61
server/internal/machine/mcm/client_cache.go
Normal file
61
server/internal/machine/mcm/client_cache.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package mcm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"mayfly-go/internal/common/consts"
|
||||||
|
"mayfly-go/pkg/cache"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 机器客户端连接缓存,指定时间内没有访问则会被关闭
|
||||||
|
var cliCache = cache.NewTimedCache(consts.MachineConnExpireTime, 5*time.Second).
|
||||||
|
WithUpdateAccessTime(true).
|
||||||
|
OnEvicted(func(_, value any) {
|
||||||
|
value.(*Cli).Close()
|
||||||
|
})
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||||
|
// 遍历所有机器连接实例,若存在机器连接实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
||||||
|
items := cliCache.Items()
|
||||||
|
for _, v := range items {
|
||||||
|
sshTunnelMachine := v.Value.(*Cli).Info.SshTunnelMachine
|
||||||
|
if sshTunnelMachine != nil && int(sshTunnelMachine.Id) == machineId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中获取客户端信息,不存在则回调获取机器信息函数,并新建
|
||||||
|
func GetMachineCli(machineId uint64, getMachine func(uint64) (*MachineInfo, error)) (*Cli, error) {
|
||||||
|
if load, ok := cliCache.Get(machineId); ok {
|
||||||
|
return load.(*Cli), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
me, err := getMachine(machineId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := me.Conn()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cliCache.Put(machineId, c)
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否存在指定id的客户端连接
|
||||||
|
func HasCli(machineId uint64) bool {
|
||||||
|
if _, ok := cliCache.Get(machineId); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除指定机器客户端,并关闭客户端连接
|
||||||
|
func DeleteCli(id uint64) {
|
||||||
|
cliCache.Delete(id)
|
||||||
|
}
|
||||||
117
server/internal/machine/mcm/machine.go
Normal file
117
server/internal/machine/mcm/machine.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package mcm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"mayfly-go/internal/machine/domain/entity"
|
||||||
|
"mayfly-go/pkg/errorx"
|
||||||
|
"mayfly-go/pkg/logx"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 机器信息
|
||||||
|
type MachineInfo struct {
|
||||||
|
Id uint64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
Ip string `json:"ip"` // IP地址
|
||||||
|
Port int `json:"-"` // 端口号
|
||||||
|
AuthMethod int8 `json:"-"` // 授权认证方式
|
||||||
|
Username string `json:"-"` // 用户名
|
||||||
|
Password string `json:"-"`
|
||||||
|
Passphrase string `json:"-"` // 私钥口令
|
||||||
|
|
||||||
|
SshTunnelMachine *MachineInfo `json:"-"` // ssh隧道机器
|
||||||
|
EnableRecorder int8 `json:"-"` // 是否启用终端回放记录
|
||||||
|
TagPath string `json:"tagPath"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MachineInfo) UseSshTunnel() bool {
|
||||||
|
return m.SshTunnelMachine != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接
|
||||||
|
func (mi *MachineInfo) Conn() (*Cli, error) {
|
||||||
|
logx.Infof("[%s]机器连接:%s:%d", mi.Name, mi.Ip, mi.Port)
|
||||||
|
|
||||||
|
// 如果使用了ssh隧道,则修改机器ip port为暴露的ip port
|
||||||
|
err := mi.IfUseSshTunnelChangeIpPort()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errorx.NewBiz("ssh隧道连接失败: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
cli := &Cli{Info: mi}
|
||||||
|
sshClient, err := GetSshClient(mi)
|
||||||
|
if err != nil {
|
||||||
|
if mi.UseSshTunnel() {
|
||||||
|
CloseSshTunnelMachine(int(mi.SshTunnelMachine.Id), mi.Id)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cli.sshClient = sshClient
|
||||||
|
return cli, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果使用了ssh隧道,则修改机器ip port为暴露的ip port
|
||||||
|
func (me *MachineInfo) IfUseSshTunnelChangeIpPort() error {
|
||||||
|
if !me.UseSshTunnel() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
originId := me.Id
|
||||||
|
if originId == 0 {
|
||||||
|
// 随机设置一个id,如果使用了隧道则用于临时保存隧道
|
||||||
|
me.Id = uint64(time.Now().Nanosecond())
|
||||||
|
}
|
||||||
|
|
||||||
|
sshTunnelMachine, err := GetSshTunnelMachine(int(me.SshTunnelMachine.Id), func(u uint64) (*MachineInfo, error) {
|
||||||
|
return me.SshTunnelMachine, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
exposeIp, exposePort, err := sshTunnelMachine.OpenSshTunnel(me.Id, me.Ip, me.Port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 修改机器ip地址
|
||||||
|
me.Ip = exposeIp
|
||||||
|
me.Port = exposePort
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSshClient(m *MachineInfo) (*ssh.Client, error) {
|
||||||
|
config := &ssh.ClientConfig{
|
||||||
|
User: m.Username,
|
||||||
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.AuthMethod == entity.AuthCertAuthMethodPassword {
|
||||||
|
config.Auth = []ssh.AuthMethod{ssh.Password(m.Password)}
|
||||||
|
} else if m.AuthMethod == entity.MachineAuthMethodPublicKey {
|
||||||
|
var key ssh.Signer
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if len(m.Passphrase) > 0 {
|
||||||
|
key, err = ssh.ParsePrivateKeyWithPassphrase([]byte(m.Password), []byte(m.Passphrase))
|
||||||
|
} else {
|
||||||
|
key, err = ssh.ParsePrivateKey([]byte(m.Password))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := fmt.Sprintf("%s:%d", m.Ip, m.Port)
|
||||||
|
sshClient, err := ssh.Dial("tcp", addr, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return sshClient, nil
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package machine
|
package mcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package machine
|
package mcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package machine
|
package mcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -136,15 +136,15 @@ func (stm *SshTunnelMachine) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取ssh隧道机器,方便统一管理充当ssh隧道的机器,避免创建多个ssh client
|
// 获取ssh隧道机器,方便统一管理充当ssh隧道的机器,避免创建多个ssh client
|
||||||
func GetSshTunnelMachine(machineId int, getMachine func(uint64) (*Info, error)) (*SshTunnelMachine, error) {
|
func GetSshTunnelMachine(machineId int, getMachine func(uint64) (*MachineInfo, error)) (*SshTunnelMachine, error) {
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
sshTunnelMachine := sshTunnelMachines[machineId]
|
sshTunnelMachine := sshTunnelMachines[machineId]
|
||||||
if sshTunnelMachine != nil {
|
if sshTunnelMachine != nil {
|
||||||
return sshTunnelMachine, nil
|
return sshTunnelMachine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
|
|
||||||
me, err := getMachine(uint64(machineId))
|
me, err := getMachine(uint64(machineId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package machine
|
package mcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -71,21 +71,6 @@ echo '-----'
|
|||||||
top -b -n 1 | grep Cpu
|
top -b -n 1 | grep Cpu
|
||||||
`
|
`
|
||||||
|
|
||||||
func (c *Cli) GetAllStats() *Stats {
|
|
||||||
res, _ := c.Run(StatsShell)
|
|
||||||
infos := strings.Split(res, "-----")
|
|
||||||
stats := new(Stats)
|
|
||||||
getUptime(infos[0], stats)
|
|
||||||
getHostname(infos[1], stats)
|
|
||||||
getLoad(infos[2], stats)
|
|
||||||
getMemInfo(infos[3], stats)
|
|
||||||
getFSInfo(infos[4], stats)
|
|
||||||
getInterfaces(infos[5], stats)
|
|
||||||
getInterfaceInfo(infos[6], stats)
|
|
||||||
getCPU(infos[7], stats)
|
|
||||||
return stats
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUptime(uptime string, stats *Stats) (err error) {
|
func getUptime(uptime string, stats *Stats) (err error) {
|
||||||
parts := strings.Fields(uptime)
|
parts := strings.Fields(uptime)
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package machine
|
package mcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package machine
|
package mcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -2,7 +2,7 @@ package mgm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"mayfly-go/internal/common/consts"
|
"mayfly-go/internal/common/consts"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -18,7 +18,7 @@ var connCache = cache.NewTimedCache(consts.MongoConnExpireTime, 5*time.Second).
|
|||||||
})
|
})
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
machine.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||||
// 遍历所有mongo连接实例,若存在redis实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
// 遍历所有mongo连接实例,若存在redis实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
||||||
items := connCache.Items()
|
items := connCache.Items()
|
||||||
for _, v := range items {
|
for _, v := range items {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package rdm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/internal/common/consts"
|
"mayfly-go/internal/common/consts"
|
||||||
"mayfly-go/internal/machine/infrastructure/machine"
|
"mayfly-go/internal/machine/mcm"
|
||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -19,7 +19,7 @@ var connCache = cache.NewTimedCache(consts.RedisConnExpireTime, 5*time.Second).
|
|||||||
})
|
})
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
machine.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
|
||||||
// 遍历所有redis连接实例,若存在redis实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
// 遍历所有redis连接实例,若存在redis实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
||||||
items := connCache.Items()
|
items := connCache.Items()
|
||||||
for _, v := range items {
|
for _, v := range items {
|
||||||
|
|||||||
Reference in New Issue
Block a user