github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/connhelper/ssh/ssh.go (about)

     1  // Package ssh provides the connection helper for ssh:// URL.
     2  // Requires Docker 18.09 or later on the remote host.
     3  package ssh
     4  
     5  import (
     6  	"net/url"
     7  
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // New returns cmd and its args
    12  func New(daemonURL string) (string, []string, error) {
    13  	sp, err := parseSSHURL(daemonURL)
    14  	if err != nil {
    15  		return "", nil, err
    16  	}
    17  	return "ssh", append(sp.Args(), []string{"--", "docker", "system", "dial-stdio"}...), nil
    18  }
    19  
    20  func parseSSHURL(daemonURL string) (*sshSpec, error) {
    21  	u, err := url.Parse(daemonURL)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	if u.Scheme != "ssh" {
    26  		return nil, errors.Errorf("expected scheme ssh, got %s", u.Scheme)
    27  	}
    28  
    29  	var sp sshSpec
    30  
    31  	if u.User != nil {
    32  		sp.user = u.User.Username()
    33  		if _, ok := u.User.Password(); ok {
    34  			return nil, errors.New("ssh helper does not accept plain-text password")
    35  		}
    36  	}
    37  	sp.host = u.Hostname()
    38  	if sp.host == "" {
    39  		return nil, errors.Errorf("host is not specified")
    40  	}
    41  	sp.port = u.Port()
    42  	if u.Path != "" {
    43  		return nil, errors.Errorf("extra path: %s", u.Path)
    44  	}
    45  	if u.RawQuery != "" {
    46  		return nil, errors.Errorf("extra query: %s", u.RawQuery)
    47  	}
    48  	if u.Fragment != "" {
    49  		return nil, errors.Errorf("extra fragment: %s", u.Fragment)
    50  	}
    51  	return &sp, err
    52  }
    53  
    54  type sshSpec struct {
    55  	user string
    56  	host string
    57  	port string
    58  }
    59  
    60  func (sp *sshSpec) Args() []string {
    61  	var args []string
    62  	if sp.user != "" {
    63  		args = append(args, "-l", sp.user)
    64  	}
    65  	if sp.port != "" {
    66  		args = append(args, "-p", sp.port)
    67  	}
    68  	args = append(args, sp.host)
    69  	return args
    70  }