mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-04 00:10:25 +08:00
123 lines
3.2 KiB
Go
123 lines
3.2 KiB
Go
package mcm
|
||
|
||
import (
|
||
"errors"
|
||
"mayfly-go/internal/common/consts"
|
||
tagentity "mayfly-go/internal/tag/domain/entity"
|
||
"mayfly-go/pkg/cache"
|
||
"mayfly-go/pkg/logx"
|
||
"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
|
||
})
|
||
go checkClientAvailability(3 * time.Minute)
|
||
}
|
||
|
||
// 从缓存中获取客户端信息,不存在则回调获取机器信息函数,并新建。
|
||
// @param 机器的授权凭证名
|
||
func GetMachineCli(authCertName string, getMachine func(string) (*MachineInfo, error)) (*Cli, error) {
|
||
if load, ok := cliCache.Get(authCertName); ok {
|
||
return load.(*Cli), nil
|
||
}
|
||
|
||
mi, err := getMachine(authCertName)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
mi.Key = authCertName
|
||
c, err := mi.Conn()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
cliCache.Put(authCertName, c)
|
||
return c, nil
|
||
}
|
||
|
||
// 根据机器id从已连接的机器客户端中获取特权账号连接, 若不存在特权账号,则随机返回一个
|
||
func GetMachineCliById(machineId uint64) (*Cli, error) {
|
||
// 遍历所有机器连接实例,删除指定机器id关联的连接...
|
||
items := cliCache.Items()
|
||
|
||
var machineCli *Cli
|
||
for _, v := range items {
|
||
cli := v.Value.(*Cli)
|
||
mi := cli.Info
|
||
if mi.Id != machineId {
|
||
continue
|
||
}
|
||
machineCli = cli
|
||
|
||
// 如果是特权账号,则跳出
|
||
if mi.AuthCertType == tagentity.AuthCertTypePrivileged {
|
||
break
|
||
}
|
||
}
|
||
|
||
if machineCli != nil {
|
||
return machineCli, nil
|
||
}
|
||
return nil, errors.New("不存在该机器id的连接")
|
||
}
|
||
|
||
// 删除指定机器缓存客户端,并关闭客户端连接
|
||
func DeleteCli(id uint64) {
|
||
// 遍历所有机器连接实例,删除指定机器id关联的连接...
|
||
items := cliCache.Items()
|
||
for _, v := range items {
|
||
mi := v.Value.(*Cli).Info
|
||
if mi.Id == id {
|
||
cliCache.Delete(mi.Key)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查缓存中的客户端是否可用,不可用则关闭客户端连接
|
||
func checkClientAvailability(interval time.Duration) {
|
||
ticker := time.NewTicker(interval)
|
||
defer ticker.Stop()
|
||
|
||
for range ticker.C {
|
||
// 遍历所有机器连接实例,若存在机器连接实例使用该ssh隧道机器,则返回true,表示还在使用中...
|
||
items := cliCache.Items()
|
||
for _, v := range items {
|
||
if v == nil {
|
||
continue
|
||
}
|
||
cli := v.Value.(*Cli)
|
||
if cli.Info == nil {
|
||
continue
|
||
}
|
||
if cli.sshClient == nil {
|
||
continue
|
||
}
|
||
if cli.sshClient.Conn == nil {
|
||
continue
|
||
}
|
||
if _, _, err := cli.sshClient.Conn.SendRequest("ping", true, nil); err != nil {
|
||
logx.Errorf("machine[%s] cache client is not available: %s", cli.Info.Name, err.Error())
|
||
DeleteCli(cli.Info.Id)
|
||
}
|
||
logx.Debugf("machine[%s] cache client is available", cli.Info.Name)
|
||
}
|
||
}
|
||
}
|