DockerCLI/cli/connhelper/ssh/ssh.go

65 lines
1.4 KiB
Go
Raw Normal View History

// Package ssh provides the connection helper for ssh:// URL.
package ssh
import (
"net/url"
"github.com/pkg/errors"
)
// ParseURL parses URL
func ParseURL(daemonURL string) (*Spec, error) {
u, err := url.Parse(daemonURL)
if err != nil {
return nil, err
}
if u.Scheme != "ssh" {
return nil, errors.Errorf("expected scheme ssh, got %q", u.Scheme)
}
var sp Spec
if u.User != nil {
sp.User = u.User.Username()
if _, ok := u.User.Password(); ok {
return nil, errors.New("plain-text password is not supported")
}
}
sp.Host = u.Hostname()
if sp.Host == "" {
return nil, errors.Errorf("no host specified")
}
sp.Port = u.Port()
if u.Path != "" {
return nil, errors.Errorf("extra path after the host: %q", u.Path)
}
if u.RawQuery != "" {
return nil, errors.Errorf("extra query after the host: %q", u.RawQuery)
}
if u.Fragment != "" {
return nil, errors.Errorf("extra fragment after the host: %q", u.Fragment)
}
return &sp, err
}
// Spec of SSH URL
type Spec struct {
User string
Host string
Port string
}
// Args returns args except "ssh" itself combined with optional additional command args
func (sp *Spec) Args(add ...string) []string {
var args []string
if sp.User != "" {
args = append(args, "-l", sp.User)
}
if sp.Port != "" {
args = append(args, "-p", sp.Port)
}
args = append(args, "--", sp.Host)
args = append(args, add...)
return args
}