abra/pkg/ssh/ssh.go

97 lines
2.2 KiB
Go
Raw Normal View History

2021-10-24 21:15:38 +00:00
package ssh
import (
"os/user"
2021-10-25 22:33:18 +00:00
"time"
2021-10-24 21:15:38 +00:00
"github.com/AlecAivazis/survey/v2"
2021-10-24 21:15:38 +00:00
"github.com/kevinburke/ssh_config"
"github.com/sfreiberg/simplessh"
"github.com/sirupsen/logrus"
2021-10-24 21:15:38 +00:00
)
// HostConfig is a SSH host config.
type HostConfig struct {
Host string
IdentityFile string
Port string
User string
}
// GetHostConfig retrieves a ~/.ssh/config config for a host.
func GetHostConfig(hostname, username, port string) (HostConfig, error) {
2021-10-24 21:15:38 +00:00
var hostConfig HostConfig
var host, idf string
2021-10-24 21:15:38 +00:00
if host = ssh_config.Get(hostname, "Hostname"); host == "" {
logrus.Debugf("no hostname found in SSH config, assuming %s", hostname)
host = hostname
2021-10-24 21:15:38 +00:00
}
if username == "" {
if username = ssh_config.Get(hostname, "User"); username == "" {
systemUser, err := user.Current()
if err != nil {
return hostConfig, err
}
logrus.Debugf("no username found in SSH config or passed on command-line, assuming %s", username)
username = systemUser.Username
}
2021-10-24 21:15:38 +00:00
}
if port == "" {
if port = ssh_config.Get(hostname, "Port"); port == "" {
logrus.Debugf("no port found in SSH config or passed on command-line, assuming 22")
port = "22"
}
2021-10-24 21:15:38 +00:00
}
idf = ssh_config.Get(hostname, "IdentityFile")
2021-10-24 21:15:38 +00:00
hostConfig.Host = host
if idf != "" {
hostConfig.IdentityFile = idf
}
2021-10-24 21:15:38 +00:00
hostConfig.Port = port
hostConfig.User = username
logrus.Debugf("constructed SSH config %s for %s", hostConfig, hostname)
2021-10-24 21:15:38 +00:00
return hostConfig, nil
}
// New creates a new SSH client connection.
func New(domainName, sshAuth, username, port string) (*simplessh.Client, error) {
var client *simplessh.Client
hostConfig, err := GetHostConfig(domainName, username, port)
if err != nil {
return client, err
}
if sshAuth == "identity-file" {
var err error
2021-10-25 22:33:18 +00:00
client, err = simplessh.ConnectWithAgentTimeout(hostConfig.Host, hostConfig.User, 5*time.Second)
if err != nil {
return client, err
}
} else {
password := ""
prompt := &survey.Password{
Message: "SSH password?",
}
if err := survey.AskOne(prompt, &password); err != nil {
return client, err
}
var err error
2021-10-25 22:33:18 +00:00
client, err = simplessh.ConnectWithPasswordTimeout(hostConfig.Host, hostConfig.User, password, 5*time.Second)
if err != nil {
return client, err
}
}
return client, nil
}