1
0
mirror of https://github.com/rancher/rke.git synced 2025-04-28 11:36:27 +00:00
rke/hosts/dialer.go

123 lines
2.8 KiB
Go
Raw Normal View History

2017-10-29 09:45:21 +00:00
package hosts
import (
"fmt"
"net"
"net/http"
2018-03-27 21:07:16 +00:00
"time"
2017-10-29 09:45:21 +00:00
"golang.org/x/crypto/ssh"
)
2018-03-27 21:07:16 +00:00
const (
DockerDialerTimeout = 30
)
2017-12-16 03:38:15 +00:00
type DialerFactory func(h *Host) (func(network, address string) (net.Conn, error), error)
2017-12-16 03:38:15 +00:00
type dialer struct {
signer ssh.Signer
sshKeyString string
sshAddress string
sshPassphrase []byte
username string
netConn string
dockerSocket string
useSSHAgentAuth bool
2017-10-29 09:45:21 +00:00
}
func newDialer(h *Host, kind string) (*dialer, error) {
2017-12-16 03:38:15 +00:00
dialer := &dialer{
sshAddress: fmt.Sprintf("%s:%s", h.Address, h.Port),
username: h.User,
dockerSocket: h.DockerSocket,
sshKeyString: h.SSHKey,
netConn: "unix",
sshPassphrase: []byte(h.SavedKeyPhrase),
useSSHAgentAuth: h.SSHAgentAuth,
}
2017-10-29 09:45:21 +00:00
if dialer.sshKeyString == "" {
dialer.sshKeyString = privateKeyPath(h.SSHKeyPath)
}
switch kind {
case "network", "health":
dialer.netConn = "tcp"
}
if len(dialer.dockerSocket) == 0 {
dialer.dockerSocket = "/var/run/docker.sock"
}
return dialer, nil
}
func SSHFactory(h *Host) (func(network, address string) (net.Conn, error), error) {
dialer, err := newDialer(h, "docker")
return dialer.Dial, err
}
func LocalConnFactory(h *Host) (func(network, address string) (net.Conn, error), error) {
dialer, err := newDialer(h, "network")
return dialer.Dial, err
}
func (d *dialer) DialDocker(network, addr string) (net.Conn, error) {
return d.Dial(network, addr)
}
func (d *dialer) DialLocalConn(network, addr string) (net.Conn, error) {
return d.Dial(network, addr)
}
func (d *dialer) Dial(network, addr string) (net.Conn, error) {
conn, err := d.getSSHTunnelConnection()
2017-10-29 09:45:21 +00:00
if err != nil {
return nil, fmt.Errorf("Failed to dial ssh using address [%s]: %v", d.sshAddress, err)
2017-10-29 09:45:21 +00:00
}
// Docker Socket....
if d.netConn == "unix" {
addr = d.dockerSocket
network = d.netConn
2017-10-29 09:45:21 +00:00
}
remote, err := conn.Dial(network, addr)
2017-10-29 09:45:21 +00:00
if err != nil {
return nil, fmt.Errorf("Failed to dial to %s: %v", addr, err)
2017-10-29 09:45:21 +00:00
}
return remote, err
}
2017-12-16 03:38:15 +00:00
func (d *dialer) getSSHTunnelConnection() (*ssh.Client, error) {
cfg, err := getSSHConfig(d.username, d.sshKeyString, d.sshPassphrase, d.useSSHAgentAuth)
if err != nil {
return nil, fmt.Errorf("Error configuring SSH: %v", err)
}
// Establish connection with SSH server
return ssh.Dial("tcp", d.sshAddress, cfg)
}
2017-12-16 03:38:15 +00:00
func (h *Host) newHTTPClient(dialerFactory DialerFactory) (*http.Client, error) {
factory := dialerFactory
if factory == nil {
2017-12-16 03:38:15 +00:00
factory = SSHFactory
}
dialer, err := factory(h)
if err != nil {
return nil, err
}
2018-03-27 21:07:16 +00:00
dockerDialerTimeout := time.Second * DockerDialerTimeout
2017-12-16 03:38:15 +00:00
return &http.Client{
Transport: &http.Transport{
2018-03-27 21:07:16 +00:00
Dial: dialer,
TLSHandshakeTimeout: dockerDialerTimeout,
IdleConnTimeout: dockerDialerTimeout,
ResponseHeaderTimeout: dockerDialerTimeout,
2017-12-16 03:38:15 +00:00
},
}, nil
}