diff --git a/api/helpers.go b/api/helpers.go index ec53a3ab70..5aac8ccc67 100644 --- a/api/helpers.go +++ b/api/helpers.go @@ -5,6 +5,7 @@ package api import ( + "errors" "fmt" "os" "strings" @@ -37,6 +38,36 @@ type ScalewayImageInterface struct { Type string } +func ResolveGateway(api *ScalewayAPI, gateway string) (string, error) { + if gateway == "" { + return "", nil + } + + // Parses optional type prefix, i.e: "server:name" -> "name" + _, gateway = parseNeedle(gateway) + + servers, err := api.ResolveServer(gateway) + if err != nil { + return "", err + } + + if len(servers) == 0 { + return gateway, nil + } + + if len(servers) > 1 { + showResolverResults(gateway, servers) + return "", errors.New(fmt.Sprintf("Gateway '%s' is ambiguous", gateway)) + } + + // if len(servers) == 1 { + server, err := api.GetServer(servers[0].Identifier) + if err != nil { + return "", err + } + return server.PublicAddress.IP, nil +} + // CreateVolumeFromHumanSize creates a volume on the API with a human readable size func CreateVolumeFromHumanSize(api *ScalewayAPI, size string) (*string, error) { bytes, err := humanize.ParseBytes(size) diff --git a/commands/cp.go b/commands/cp.go index 43775891f5..222f7d9678 100644 --- a/commands/cp.go +++ b/commands/cp.go @@ -52,7 +52,7 @@ var cpHelp bool // -h, --help flag var cpGateway string // -g, --gateway flag // TarFromSource creates a stream buffer with the tarballed content of the user source -func TarFromSource(api *api.ScalewayAPI, source string) (*io.ReadCloser, error) { +func TarFromSource(apiClient *api.ScalewayAPI, source string) (*io.ReadCloser, error) { var tarOutputStream io.ReadCloser // source is a server address + path (scp-like uri) @@ -63,9 +63,9 @@ func TarFromSource(api *api.ScalewayAPI, source string) (*io.ReadCloser, error) return nil, fmt.Errorf("invalid source uri, see 'scw cp -h' for usage") } - serverID := api.GetServerID(serverParts[0]) + serverID := apiClient.GetServerID(serverParts[0]) - server, err := api.GetServer(serverID) + server, err := apiClient.GetServer(serverID) if err != nil { return nil, err } @@ -83,8 +83,14 @@ func TarFromSource(api *api.ScalewayAPI, source string) (*io.ReadCloser, error) remoteCommand = append(remoteCommand, "-cf", "-") remoteCommand = append(remoteCommand, base) + // Resolve gateway + gateway, err := api.ResolveGateway(apiClient, cpGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", cpGateway, err) + } + // execCmd contains the ssh connection + the remoteCommand - execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, cpGateway)) + execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, gateway)) log.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) spawnSrc := exec.Command("ssh", execCmd...) @@ -141,7 +147,7 @@ func TarFromSource(api *api.ScalewayAPI, source string) (*io.ReadCloser, error) } // UntarToDest writes to user destination the streamed tarball in input -func UntarToDest(api *api.ScalewayAPI, sourceStream *io.ReadCloser, destination string) error { +func UntarToDest(apiClient *api.ScalewayAPI, sourceStream *io.ReadCloser, destination string) error { // destination is a server address + path (scp-like uri) if strings.Index(destination, ":") > -1 { log.Debugf("Streaming using ssh and untaring remotely") @@ -150,9 +156,9 @@ func UntarToDest(api *api.ScalewayAPI, sourceStream *io.ReadCloser, destination return fmt.Errorf("invalid destination uri, see 'scw cp -h' for usage") } - serverID := api.GetServerID(serverParts[0]) + serverID := apiClient.GetServerID(serverParts[0]) - server, err := api.GetServer(serverID) + server, err := apiClient.GetServer(serverID) if err != nil { return err } @@ -166,8 +172,14 @@ func UntarToDest(api *api.ScalewayAPI, sourceStream *io.ReadCloser, destination } remoteCommand = append(remoteCommand, "-xf", "-") + // Resolve gateway + gateway, err := api.ResolveGateway(apiClient, cpGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", cpGateway, err) + } + // execCmd contains the ssh connection + the remoteCommand - execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, cpGateway)) + execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, false, nil, remoteCommand, gateway)) log.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) spawnDst := exec.Command("ssh", execCmd...) diff --git a/commands/exec.go b/commands/exec.go index b47e3e793e..d04a1e2f47 100644 --- a/commands/exec.go +++ b/commands/exec.go @@ -57,8 +57,13 @@ func runExec(cmd *types.Command, args []string) { serverID := cmd.API.GetServerID(args[0]) + // Resolve gateway + gateway, err := api.ResolveGateway(cmd.API, execGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", execGateway, err) + } + var server *api.ScalewayServer - var err error if execW { // --wait server, err = api.WaitForServerReady(cmd.API, serverID) @@ -80,7 +85,7 @@ func runExec(cmd *types.Command, args []string) { }() } - err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args[1:], !execW, execGateway) + err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args[1:], !execW, gateway) if err != nil { log.Fatalf("%v", err) os.Exit(1) diff --git a/commands/kill.go b/commands/kill.go index 7afcbc4d65..7b88f1be98 100644 --- a/commands/kill.go +++ b/commands/kill.go @@ -11,6 +11,7 @@ import ( log "github.com/Sirupsen/logrus" + "github.com/scaleway/scaleway-cli/api" types "github.com/scaleway/scaleway-cli/commands/types" "github.com/scaleway/scaleway-cli/utils" ) @@ -47,7 +48,13 @@ func runKill(cmd *types.Command, args []string) { log.Fatalf("Failed to get server information for %s: %v", serverID, err) } - execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, killGateway)) + // Resolve gateway + gateway, err := api.ResolveGateway(cmd.API, killGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", killGateway, err) + } + + execCmd := append(utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, gateway)) log.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) diff --git a/commands/logs.go b/commands/logs.go index 255b505f00..320768812f 100644 --- a/commands/logs.go +++ b/commands/logs.go @@ -7,6 +7,7 @@ package commands import ( log "github.com/Sirupsen/logrus" + "github.com/scaleway/scaleway-cli/api" types "github.com/scaleway/scaleway-cli/commands/types" "github.com/scaleway/scaleway-cli/utils" ) @@ -43,8 +44,14 @@ func runLogs(cmd *types.Command, args []string) { // FIXME: switch to serial history when API is ready + // Resolve gateway + gateway, err := api.ResolveGateway(cmd.API, logsGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", logsGateway, err) + } + command := []string{"dmesg"} - err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, command, true, logsGateway) + err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, command, true, gateway) if err != nil { log.Fatalf("Command execution failed: %v", err) } diff --git a/commands/port.go b/commands/port.go index 03f180a2f3..91be26bec8 100644 --- a/commands/port.go +++ b/commands/port.go @@ -7,6 +7,7 @@ package commands import ( log "github.com/Sirupsen/logrus" + "github.com/scaleway/scaleway-cli/api" types "github.com/scaleway/scaleway-cli/commands/types" "github.com/scaleway/scaleway-cli/utils" ) @@ -41,8 +42,14 @@ func runPort(cmd *types.Command, args []string) { log.Fatalf("Failed to get server information for %s: %v", serverID, err) } + // Resolve gateway + gateway, err := api.ResolveGateway(cmd.API, portGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", portGateway, err) + } + command := []string{"netstat -lutn 2>/dev/null | grep LISTEN"} - err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, command, true, portGateway) + err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, command, true, gateway) if err != nil { log.Fatalf("Command execution failed: %v", err) } diff --git a/commands/run.go b/commands/run.go index b90428b375..926c73f57d 100644 --- a/commands/run.go +++ b/commands/run.go @@ -110,12 +110,18 @@ func runRun(cmd *types.Command, args []string) { } log.Debugf("Server is ready: %s", server.PublicAddress.IP) + // Resolve gateway + gateway, err := api.ResolveGateway(cmd.API, runGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", runGateway, err) + } + // exec -w SERVER COMMAND ARGS... log.Debugf("Executing command") if len(args) < 2 { - err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, []string{}, false, runGateway) + err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, []string{}, false, gateway) } else { - err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args[1:], false, runGateway) + err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args[1:], false, gateway) } if err != nil { log.Debugf("Command execution failed: %v", err) diff --git a/commands/top.go b/commands/top.go index 5389cfa9b1..ec5b318711 100644 --- a/commands/top.go +++ b/commands/top.go @@ -11,6 +11,7 @@ import ( log "github.com/Sirupsen/logrus" + "github.com/scaleway/scaleway-cli/api" types "github.com/scaleway/scaleway-cli/commands/types" "github.com/scaleway/scaleway-cli/utils" ) @@ -46,7 +47,13 @@ func runTop(cmd *types.Command, args []string) { log.Fatalf("Failed to get server information for %s: %v", serverID, err) } - execCmd := utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, topGateway) + // Resolve gateway + gateway, err := api.ResolveGateway(cmd.API, topGateway) + if err != nil { + log.Fatalf("Cannot resolve Gateway '%s': %v", topGateway, err) + } + + execCmd := utils.NewSSHExecCmd(server.PublicAddress.IP, server.PrivateIP, true, nil, []string{command}, gateway) log.Debugf("Executing: ssh %s", strings.Join(execCmd, " ")) out, err := exec.Command("ssh", execCmd...).CombinedOutput() fmt.Printf("%s", out)