github.com/thajeztah/cli@v0.0.0-20240223162942-dc6bfac81a8b/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  	sp.Path = u.Path
    34  	if u.RawQuery != "" {
    35  		return nil, errors.Errorf("extra query after the host: %q", u.RawQuery)
    36  	}
    37  	if u.Fragment != "" {
    38  		return nil, errors.Errorf("extra fragment after the host: %q", u.Fragment)
    39  	}
    40  	return &sp, err
    41  }
    42  
    43  // Spec of SSH URL
    44  type Spec struct {
    45  	User string
    46  	Host string
    47  	Port string
    48  	Path string
    49  }
    50  
    51  // Args returns args except "ssh" itself combined with optional additional command args
    52  func (sp *Spec) Args(add ...string) []string {
    53  	var args []string
    54  	if sp.User != "" {
    55  		args = append(args, "-l", sp.User)
    56  	}
    57  	if sp.Port != "" {
    58  		args = append(args, "-p", sp.Port)
    59  	}
    60  	args = append(args, "--", sp.Host)
    61  	args = append(args, add...)
    62  	return args
    63  }