diff --git a/README.md b/README.md index 0bdaefd44b..a7cb92077d 100644 --- a/README.md +++ b/README.md @@ -1041,6 +1041,7 @@ $ scw inspect myserver | jq '.[0].public_ip.address' #### Features +* Support of `--gateway=login@host` ([#110](https://github.com/scaleway/scaleway-cli/issues/110)) * Upload local ssh key to scaleway account on `scw login` ([#100](https://github.com/scaleway/scaleway-cli/issues/100)) * Add a 'running indicator' for `scw run`, can be disabled with the new flag `--quiet` * Support of `scw -V/--verbose` option ([#83](https://github.com/scaleway/scaleway-cli/issues/83)) diff --git a/pkg/commands/cp.go b/pkg/commands/cp.go index 13a8d92925..5fd9581dd1 100644 --- a/pkg/commands/cp.go +++ b/pkg/commands/cp.go @@ -90,7 +90,7 @@ func TarFromSource(ctx CommandContext, source string, gateway string) (*io.ReadC } // execCmd contains the ssh connection + the remoteCommand - execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, gateway)) + execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, gateway, "root")) logrus.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) spawnSrc := exec.Command("ssh", execCmd...) @@ -188,7 +188,7 @@ func UntarToDest(ctx CommandContext, sourceStream *io.ReadCloser, destination st } // execCmd contains the ssh connection + the remoteCommand - execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, gateway)) + execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, gateway, "root")) logrus.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) spawnDst := exec.Command("ssh", execCmd...) diff --git a/pkg/commands/kill.go b/pkg/commands/kill.go index b8b90c3983..d95bcbca10 100644 --- a/pkg/commands/kill.go +++ b/pkg/commands/kill.go @@ -43,7 +43,7 @@ func RunKill(ctx CommandContext, args KillArgs) error { } } - execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, gateway)) + execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, gateway, "root")) logrus.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) diff --git a/pkg/commands/top.go b/pkg/commands/top.go index 7c9c9bd699..7ff50e884d 100644 --- a/pkg/commands/top.go +++ b/pkg/commands/top.go @@ -43,7 +43,7 @@ func RunTop(ctx CommandContext, args TopArgs) error { } } - execCmd := utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, gateway) + execCmd := utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, gateway, "root") logrus.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) out, err := exec.Command("ssh", execCmd...).CombinedOutput() fmt.Printf("%s", out) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 21f591db6a..1e170f6fd0 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -35,6 +35,13 @@ func quoteShellArgs(args []string) string { // SSHExec executes a command over SSH and redirects file-descriptors func SSHExec(publicIPAddress string, privateIPAddress string, command []string, checkConnection bool, gatewayIPAddress string) error { + gatewayUser := "root" + if strings.Contains(gatewayIPAddress, "@") { + parts := strings.Split(gatewayIPAddress, "@") + gatewayUser = parts[0] + gatewayIPAddress = parts[1] + } + if publicIPAddress == "" && gatewayIPAddress == "" { return errors.New("server does not have public IP") } @@ -52,7 +59,7 @@ func SSHExec(publicIPAddress string, privateIPAddress string, command []string, } } - execCmd := append(NewSSHExecCmd(publicIPAddress, privateIPAddress, true, nil, command, gatewayIPAddress)) + execCmd := append(NewSSHExecCmd(publicIPAddress, privateIPAddress, true, nil, command, gatewayUser+"@"+gatewayIPAddress, "root")) log.Debugf("Executing: ssh %s", quoteShellArgs(execCmd)) @@ -64,8 +71,9 @@ func SSHExec(publicIPAddress string, privateIPAddress string, command []string, } // NewSSHExecCmd computes execve compatible arguments to run a command via ssh -func NewSSHExecCmd(publicIPAddress string, privateIPAddress string, allocateTTY bool, sshOptions []string, command []string, gatewayIPAddress string) []string { +func NewSSHExecCmd(publicIPAddress string, privateIPAddress string, allocateTTY bool, sshOptions []string, command []string, gatewayIPAddress string, sshUser string) []string { useGateway := gatewayIPAddress != "" + execCmd := []string{} if os.Getenv("DEBUG") != "1" { @@ -80,9 +88,16 @@ func NewSSHExecCmd(publicIPAddress string, privateIPAddress string, allocateTTY execCmd = append(execCmd, strings.Join(sshOptions, " ")) } - execCmd = append(execCmd, "-l", "root") + execCmd = append(execCmd, "-l", sshUser) if useGateway { - proxyCommand := NewSSHExecCmd(gatewayIPAddress, "", allocateTTY, []string{"-W", "%h:%p"}, nil, "") + gatewayUser := "root" + if useGateway && strings.Contains(gatewayIPAddress, "@") { + parts := strings.Split(gatewayIPAddress, "@") + gatewayUser = parts[0] + gatewayIPAddress = parts[1] + } + + proxyCommand := NewSSHExecCmd(gatewayIPAddress, "", allocateTTY, []string{"-W", "%h:%p"}, nil, "", gatewayUser) execCmd = append(execCmd, privateIPAddress, "-o", "ProxyCommand=ssh "+strings.Join(proxyCommand, " ")) } else { execCmd = append(execCmd, publicIPAddress)