mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
feat: 数据库、redis、mongo支持ssh隧道等
This commit is contained in:
@@ -24,58 +24,6 @@ type Cli struct {
|
||||
sftpClient *sftp.Client
|
||||
}
|
||||
|
||||
// 机器客户端连接缓存,45分钟内没有访问则会被关闭
|
||||
var cliCache = cache.NewTimedCache(45*time.Minute, 5*time.Second).
|
||||
WithUpdateAccessTime(true).
|
||||
OnEvicted(func(key interface{}, value interface{}) {
|
||||
value.(*Cli).Close()
|
||||
})
|
||||
|
||||
// 是否存在指定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) *entity.Machine) (*Cli, error) {
|
||||
cli, err := cliCache.ComputeIfAbsent(machineId, func(key interface{}) (interface{}, error) {
|
||||
c, err := newClient(getMachine(machineId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
})
|
||||
|
||||
if cli != nil {
|
||||
return cli.(*Cli), err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//根据机器信息创建客户端对象
|
||||
func newClient(machine *entity.Machine) (*Cli, error) {
|
||||
if machine == nil {
|
||||
return nil, errors.New("机器不存在")
|
||||
}
|
||||
|
||||
global.Log.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
|
||||
}
|
||||
|
||||
//连接
|
||||
func (c *Cli) connect() error {
|
||||
// 如果已经有client则直接返回
|
||||
@@ -83,16 +31,7 @@ func (c *Cli) connect() error {
|
||||
return nil
|
||||
}
|
||||
m := c.machine
|
||||
config := ssh.ClientConfig{
|
||||
User: m.Username,
|
||||
Auth: []ssh.AuthMethod{ssh.Password(m.Password)},
|
||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
addr := fmt.Sprintf("%s:%d", m.Ip, m.Port)
|
||||
sshClient, err := ssh.Dial("tcp", addr, &config)
|
||||
sshClient, err := GetSshClient(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -100,25 +39,6 @@ func (c *Cli) connect() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
func TestConn(m *entity.Machine) error {
|
||||
config := ssh.ClientConfig{
|
||||
User: m.Username,
|
||||
Auth: []ssh.AuthMethod{ssh.Password(m.Password)},
|
||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
addr := fmt.Sprintf("%s:%d", m.Ip, m.Port)
|
||||
sshClient, err := ssh.Dial("tcp", addr, &config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sshClient.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// 关闭client和并从缓存中移除
|
||||
func (c *Cli) Close() {
|
||||
m := c.machine
|
||||
@@ -184,3 +104,91 @@ func (c *Cli) Run(shell string) (*string, error) {
|
||||
func (c *Cli) GetMachine() *entity.Machine {
|
||||
return c.machine
|
||||
}
|
||||
|
||||
// 机器客户端连接缓存,45分钟内没有访问则会被关闭
|
||||
var cliCache = cache.NewTimedCache(45*time.Minute, 5*time.Second).
|
||||
WithUpdateAccessTime(true).
|
||||
OnEvicted(func(_, value interface{}) {
|
||||
value.(*Cli).Close()
|
||||
})
|
||||
|
||||
// 是否存在指定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) *entity.Machine) (*Cli, error) {
|
||||
cli, err := cliCache.ComputeIfAbsent(machineId, func(_ interface{}) (interface{}, error) {
|
||||
c, err := newClient(getMachine(machineId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
})
|
||||
|
||||
if cli != nil {
|
||||
return cli.(*Cli), err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
func TestConn(m *entity.Machine) error {
|
||||
sshClient, err := GetSshClient(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sshClient.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetSshClient(m *entity.Machine) (*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.MachineAuthMethodPassword {
|
||||
config.Auth = []ssh.AuthMethod{ssh.Password(m.Password)}
|
||||
} else if m.AuthMethod == entity.MachineAuthMethodPublicKey {
|
||||
if signer, err := ssh.ParsePrivateKey([]byte(m.Password)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
config.Auth = []ssh.AuthMethod{ssh.PublicKeys(signer)}
|
||||
}
|
||||
}
|
||||
|
||||
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 *entity.Machine) (*Cli, error) {
|
||||
if machine == nil {
|
||||
return nil, errors.New("机器不存在")
|
||||
}
|
||||
|
||||
global.Log.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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user