2023-10-30 17:34:56 +08:00
|
|
|
|
package mcm
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2024-04-09 12:55:51 +08:00
|
|
|
|
"errors"
|
2023-10-30 17:34:56 +08:00
|
|
|
|
"mayfly-go/internal/common/consts"
|
2024-04-09 12:55:51 +08:00
|
|
|
|
tagentity "mayfly-go/internal/tag/domain/entity"
|
2023-10-30 17:34:56 +08:00
|
|
|
|
"mayfly-go/pkg/cache"
|
2024-02-23 22:53:17 +08:00
|
|
|
|
"mayfly-go/pkg/logx"
|
2023-10-30 17:34:56 +08:00
|
|
|
|
"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
|
|
|
|
|
|
})
|
2024-02-23 22:53:17 +08:00
|
|
|
|
go checkClientAvailability(3 * time.Minute)
|
2023-10-30 17:34:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
// 从缓存中获取客户端信息,不存在则回调获取机器信息函数,并新建。
|
|
|
|
|
|
// @param 机器的授权凭证名
|
|
|
|
|
|
func GetMachineCli(authCertName string, getMachine func(string) (*MachineInfo, error)) (*Cli, error) {
|
|
|
|
|
|
if load, ok := cliCache.Get(authCertName); ok {
|
2023-10-30 17:34:56 +08:00
|
|
|
|
return load.(*Cli), nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi, err := getMachine(authCertName)
|
2023-10-30 17:34:56 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2024-04-09 12:55:51 +08:00
|
|
|
|
mi.Key = authCertName
|
|
|
|
|
|
c, err := mi.Conn()
|
2023-10-30 17:34:56 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
cliCache.Put(authCertName, c)
|
2023-10-30 17:34:56 +08:00
|
|
|
|
return c, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-09 12:55:51 +08:00
|
|
|
|
// 根据机器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的连接")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-23 22:53:17 +08:00
|
|
|
|
// 删除指定机器缓存客户端,并关闭客户端连接
|
2023-10-30 17:34:56 +08:00
|
|
|
|
func DeleteCli(id uint64) {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
// 遍历所有机器连接实例,删除指定机器id关联的连接...
|
|
|
|
|
|
items := cliCache.Items()
|
|
|
|
|
|
for _, v := range items {
|
|
|
|
|
|
mi := v.Value.(*Cli).Info
|
|
|
|
|
|
if mi.Id == id {
|
|
|
|
|
|
cliCache.Delete(mi.Key)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-30 17:34:56 +08:00
|
|
|
|
}
|
2024-02-23 22:53:17 +08:00
|
|
|
|
|
|
|
|
|
|
// 检查缓存中的客户端是否可用,不可用则关闭客户端连接
|
|
|
|
|
|
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 {
|
2024-02-24 16:30:29 +08:00
|
|
|
|
if v == nil {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2024-02-23 22:53:17 +08:00
|
|
|
|
cli := v.Value.(*Cli)
|
2024-02-29 22:12:50 +08:00
|
|
|
|
if cli.Info == nil {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2024-03-02 19:08:19 +08:00
|
|
|
|
if cli.sshClient == nil {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
if cli.sshClient.Conn == nil {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2024-02-23 22:53:17 +08:00
|
|
|
|
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)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|