framework1/framework/provider/ssh/service.go

74 lines
1.7 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 ssh
import (
"context"
"github.com/Superdanda/hade/framework"
"github.com/Superdanda/hade/framework/contract"
"golang.org/x/crypto/ssh"
"sync"
)
// HadeSSH 代表hade框架的ssh实现
type HadeSSH struct {
container framework.Container // 服务容器
clients map[string]*ssh.Client // key为uniqKey, value为ssh.Client(连接池)
lock *sync.RWMutex
}
// NewHadeSSH 代表实例化Client
func NewHadeSSH(params ...interface{}) (interface{}, error) {
container := params[0].(framework.Container)
clients := make(map[string]*ssh.Client)
lock := &sync.RWMutex{}
return &HadeSSH{
container: container,
clients: clients,
lock: lock,
}, nil
}
// GetClient 获取Client实例
func (app *HadeSSH) GetClient(option ...contract.SSHOption) (*ssh.Client, error) {
logService := app.container.MustMake(contract.LogKey).(contract.Log)
// 读取默认配置
config := GetBaseConfig(app.container)
// option对opt进行修改
for _, opt := range option {
if err := opt(app.container, config); err != nil {
return nil, err
}
}
// 如果最终的config没有设置dsn,就生成dsn
key := config.UniqKey()
// 判断是否已经实例化了
app.lock.RLock()
if db, ok := app.clients[key]; ok {
app.lock.RUnlock()
return db, nil
}
app.lock.RUnlock()
// 没有实例化,那么就要进行实例化操作
app.lock.Lock()
defer app.lock.Unlock()
// 实例化
addr := config.Host + ":" + config.Port
client, err := ssh.Dial(config.NetWork, addr, config.ClientConfig)
if err != nil {
logService.Error(context.Background(), "ssh dial error", map[string]interface{}{
"err": err,
"addr": addr,
})
}
// 挂载到map中结束配置
app.clients[key] = client
return client, nil
}