/
custom_server_ssh.go
105 lines (93 loc) · 2.56 KB
/
custom_server_ssh.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package instance
import (
"context"
"fmt"
"os/exec"
"reflect"
"github.com/scaleway/scaleway-cli/internal/core"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)
type instanceSSHServerRequest struct {
Zone scw.Zone
ServerID string
Username string
Port uint
Command string
}
func serverSSHCommand() *core.Command {
return &core.Command{
Short: `SSH into a server`,
Long: `Connect to distant server via the SSH protocol.`,
Namespace: "instance",
Verb: "ssh",
Resource: "server",
ArgsType: reflect.TypeOf(instanceSSHServerRequest{}),
ArgSpecs: core.ArgSpecs{
{
Name: "server-id",
Short: "Server ID to SSH into",
Required: true,
Positional: true,
},
{
Name: "username",
Short: "Username used for the SSH connection",
Default: core.DefaultValueSetter("root"),
},
{
Name: "port",
Short: "Port used for the SSH connection",
Default: core.DefaultValueSetter("22"),
},
{
Name: "command",
Short: "Command to execute on the remote server",
},
core.ZoneArgSpec(),
},
Run: instanceServerSSHRun,
}
}
func instanceServerSSHRun(ctx context.Context, argsI interface{}) (i interface{}, e error) {
args := argsI.(*instanceSSHServerRequest)
client := core.ExtractClient(ctx)
apiInstance := instance.NewAPI(client)
serverResp, err := apiInstance.GetServer(&instance.GetServerRequest{
Zone: args.Zone,
ServerID: args.ServerID,
})
if err != nil {
return nil, err
}
if serverResp.Server.State != instance.ServerStateRunning {
return nil, &core.CliError{
Err: fmt.Errorf("server is not running"),
Hint: fmt.Sprintf("Start the instance with: %s instance server start %s --wait", core.ExtractBinaryName(ctx), serverResp.Server.ID),
}
}
if serverResp.Server.PublicIP == nil {
return nil, &core.CliError{
Err: fmt.Errorf("server does not have a public IP to connect to"),
Hint: fmt.Sprintf("Add a public IP to the instance with: %s instance server update %s ip=<ip_id>", core.ExtractBinaryName(ctx), serverResp.Server.ID),
}
}
sshArgs := []string{
serverResp.Server.PublicIP.Address.String(),
"-p", fmt.Sprintf("%d", args.Port),
"-l", args.Username,
"-t",
}
if args.Command != "" {
sshArgs = append(sshArgs, args.Command)
}
sshCmd := exec.Command("ssh", sshArgs...)
exitCode, err := core.ExecCmd(ctx, sshCmd)
if err != nil {
return nil, err
}
if exitCode != 0 {
return nil, &core.CliError{Empty: true, Code: exitCode}
}
return &core.SuccessResult{Empty: true}, nil
}