github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/connhelper/ssh/ssh.go (about) 1 // Package ssh provides the connection helper for ssh:// URL. 2 package ssh 3 4 import ( 5 "net/url" 6 7 "github.com/pkg/errors" 8 ) 9 10 // ParseURL parses URL 11 func ParseURL(daemonURL string) (*Spec, error) { 12 u, err := url.Parse(daemonURL) 13 if err != nil { 14 return nil, err 15 } 16 if u.Scheme != "ssh" { 17 return nil, errors.Errorf("expected scheme ssh, got %q", u.Scheme) 18 } 19 20 var sp Spec 21 22 if u.User != nil { 23 sp.User = u.User.Username() 24 if _, ok := u.User.Password(); ok { 25 return nil, errors.New("plain-text password is not supported") 26 } 27 } 28 sp.Host = u.Hostname() 29 if sp.Host == "" { 30 return nil, errors.Errorf("no host specified") 31 } 32 sp.Port = u.Port() 33 if u.Path != "" { 34 return nil, errors.Errorf("extra path after the host: %q", u.Path) 35 } 36 if u.RawQuery != "" { 37 return nil, errors.Errorf("extra query after the host: %q", u.RawQuery) 38 } 39 if u.Fragment != "" { 40 return nil, errors.Errorf("extra fragment after the host: %q", u.Fragment) 41 } 42 return &sp, err 43 } 44 45 // Spec of SSH URL 46 type Spec struct { 47 User string 48 Host string 49 Port string 50 } 51 52 // Args returns args except "ssh" itself combined with optional additional command args 53 func (sp *Spec) Args(add ...string) []string { 54 var args []string 55 if sp.User != "" { 56 args = append(args, "-l", sp.User) 57 } 58 if sp.Port != "" { 59 args = append(args, "-p", sp.Port) 60 } 61 args = append(args, "--", sp.Host) 62 args = append(args, add...) 63 return args 64 }