Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 57d5df6

Browse filesBrowse files
committed
feat: support an identity file in CLI for ssh authentication (platform#91)
1 parent 093342a commit 57d5df6
Copy full SHA for 57d5df6

File tree

9 files changed

+81
-17
lines changed
Filter options

9 files changed

+81
-17
lines changed

‎cmd/cli/commands/client.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/client.go
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const (
2121
InsecureKey = "insecure"
2222
FwServerURLKey = "forwarding-server-url"
2323
FwLocalPortKey = "forwarding-local-port"
24+
IdentityFileKey = "identity-file"
2425
)
2526

2627
// ClientByCLIContext creates a new Database Lab API client.

‎cmd/cli/commands/clone/actions.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/clone/actions.go
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func forward(cliCtx *cli.Context) error {
261261

262262
wg := &sync.WaitGroup{}
263263

264-
port, err := retrieveClonePort(cliCtx, wg, remoteURL.Host)
264+
port, err := retrieveClonePort(cliCtx, wg, remoteURL)
265265
if err != nil {
266266
return err
267267
}
@@ -270,7 +270,9 @@ func forward(cliCtx *cli.Context) error {
270270

271271
log.Dbg(fmt.Sprintf("The clone port has been retrieved: %s", port))
272272

273-
tunnel, err := commands.BuildTunnel(cliCtx, commands.BuildHostname(remoteURL.Hostname(), port))
273+
remoteURL.Host = commands.BuildHostname(remoteURL.Hostname(), port)
274+
275+
tunnel, err := commands.BuildTunnel(cliCtx, remoteURL)
274276
if err != nil {
275277
return err
276278
}
@@ -288,7 +290,7 @@ func forward(cliCtx *cli.Context) error {
288290
return nil
289291
}
290292

291-
func retrieveClonePort(cliCtx *cli.Context, wg *sync.WaitGroup, remoteHost string) (string, error) {
293+
func retrieveClonePort(cliCtx *cli.Context, wg *sync.WaitGroup, remoteHost *url.URL) (string, error) {
292294
tunnel, err := commands.BuildTunnel(cliCtx, remoteHost)
293295
if err != nil {
294296
return "", err

‎cmd/cli/commands/config/command_list.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/config/command_list.go
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ func CommandList() []*cli.Command {
4545
Name: "forwarding-local-port",
4646
Usage: "local port for forwarding to the Database Lab instance",
4747
},
48+
&cli.StringFlag{
49+
Name: "identity-file",
50+
Usage: "select a file from which the identity (private key) for public key authentication is read",
51+
},
4852
},
4953
},
5054
{
@@ -73,6 +77,10 @@ func CommandList() []*cli.Command {
7377
Name: "forwarding-local-port",
7478
Usage: "local port for forwarding to the Database Lab instance",
7579
},
80+
&cli.StringFlag{
81+
Name: "identity-file",
82+
Usage: "select a file from which the identity (private key) for public key authentication is read",
83+
},
7684
},
7785
},
7886
{

‎cmd/cli/commands/config/environment.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/config/environment.go
+10-4Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ type Environment struct {
2828

2929
// Forwarding defines configuration for port forwarding.
3030
type Forwarding struct {
31-
ServerURL string `yaml:"server_url" json:"server_url"`
32-
LocalPort string `yaml:"local_port" json:"local_port"`
31+
ServerURL string `yaml:"server_url" json:"server_url"`
32+
LocalPort string `yaml:"local_port" json:"local_port"`
33+
IdentityFile string `yaml:"identity_file" json:"identity_file"`
3334
}
3435

3536
// AddEnvironmentToConfig adds a new environment to CLIConfig.
@@ -47,8 +48,9 @@ func AddEnvironmentToConfig(c *cli.Context, cfg *CLIConfig, environmentID string
4748
Token: c.String(commands.TokenKey),
4849
Insecure: c.Bool(commands.InsecureKey),
4950
Forwarding: Forwarding{
50-
ServerURL: c.String(commands.FwServerURLKey),
51-
LocalPort: c.String(commands.FwLocalPortKey),
51+
ServerURL: c.String(commands.FwServerURLKey),
52+
LocalPort: c.String(commands.FwLocalPortKey),
53+
IdentityFile: c.String(commands.IdentityFileKey),
5254
},
5355
}
5456

@@ -99,6 +101,10 @@ func updateEnvironmentInConfig(c *cli.Context, cfg *CLIConfig, environmentID str
99101
newEnvironment.Forwarding.LocalPort = c.String(commands.FwLocalPortKey)
100102
}
101103

104+
if c.IsSet(commands.IdentityFileKey) {
105+
newEnvironment.Forwarding.IdentityFile = c.String(commands.IdentityFileKey)
106+
}
107+
102108
if newEnvironment == environment {
103109
return errors.New("config unchanged. Set different option values to update.") // nolint
104110
}

‎cmd/cli/commands/global/actions.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/global/actions.go
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func forward(cliCtx *cli.Context) error {
6060
return err
6161
}
6262

63-
tunnel, err := commands.BuildTunnel(cliCtx, remoteURL.Host)
63+
tunnel, err := commands.BuildTunnel(cliCtx, remoteURL)
6464
if err != nil {
6565
return err
6666
}

‎cmd/cli/commands/global/command_list.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/global/command_list.go
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ func List() []*cli.Command {
4646
Name: "forwarding-local-port",
4747
Usage: "local port for forwarding to the Database Lab instance",
4848
},
49+
&cli.StringFlag{
50+
Name: "identity-file",
51+
Usage: "select a file from which the identity (private key) for public key authentication is read",
52+
},
4953
},
5054
Action: initCLI,
5155
},

‎cmd/cli/commands/port_forwarding.go

Copy file name to clipboardExpand all lines: cmd/cli/commands/port_forwarding.go
+20-7Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,31 @@ import (
1717
)
1818

1919
// BuildTunnel creates a new instance of SSH tunnel.
20-
func BuildTunnel(cliCtx *cli.Context, remoteHost string) (*portfwd.SSHTunnel, error) {
21-
remoteURL, err := url.Parse(cliCtx.String(URLKey))
20+
func BuildTunnel(cliCtx *cli.Context, remoteHost *url.URL) (*portfwd.SSHTunnel, error) {
21+
localEndpoint := forwardingLocalEndpoint(remoteHost, cliCtx.String(FwLocalPortKey))
22+
23+
serverURL, err := url.Parse(cliCtx.String(FwServerURLKey))
2224
if err != nil {
2325
return nil, err
2426
}
2527

26-
localEndpoint := forwardingLocalEndpoint(remoteURL, cliCtx.String(FwLocalPortKey))
27-
28-
serverURL, err := url.Parse(cliCtx.String(FwServerURLKey))
28+
authMethod, err := getAuthMethod(cliCtx)
2929
if err != nil {
3030
return nil, err
3131
}
3232

3333
sshConfig := &ssh.ClientConfig{
3434
User: serverURL.User.Username(),
3535
Auth: []ssh.AuthMethod{
36-
portfwd.SSHAgent(),
36+
authMethod,
3737
},
3838
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
3939
// Always accept key.
4040
return nil
4141
},
4242
}
4343

44-
tunnel := portfwd.NewTunnel(localEndpoint, serverURL.Host, remoteHost, sshConfig)
44+
tunnel := portfwd.NewTunnel(localEndpoint, serverURL.Host, remoteHost.Host, sshConfig)
4545

4646
return tunnel, nil
4747
}
@@ -54,6 +54,19 @@ func forwardingLocalEndpoint(remoteURL *url.URL, localPort string) string {
5454
return fmt.Sprintf("%s:%s", "127.0.0.1", localPort)
5555
}
5656

57+
func getAuthMethod(cliCtx *cli.Context) (ssh.AuthMethod, error) {
58+
if cliCtx.String(IdentityFileKey) != "" {
59+
authMethod, err := portfwd.ReadAuthFromIdentityFile(cliCtx.String(IdentityFileKey))
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
return authMethod, nil
65+
}
66+
67+
return portfwd.SSHAgent(), nil
68+
}
69+
5770
// BuildHostname builds a hostname string.
5871
func BuildHostname(host, port string) string {
5972
return fmt.Sprintf("%s:%s", host, port)

‎cmd/cli/main.go

Copy file name to clipboardExpand all lines: cmd/cli/main.go
+13-2Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,17 @@ func main() {
5858
&cli.StringFlag{
5959
Name: "forwarding-server-url",
6060
Usage: "forwarding server URL of Database Lab instance",
61-
EnvVars: []string{"DBLAB_FORWARDING_SERVER_URL"},
61+
EnvVars: []string{"DBLAB_CLI_FORWARDING_SERVER_URL"},
6262
},
6363
&cli.StringFlag{
6464
Name: "forwarding-local-port",
6565
Usage: "local port for forwarding to the Database Lab instance",
66-
EnvVars: []string{"DBLAB_FORWARDING_LOCAL_PORT"},
66+
EnvVars: []string{"DBLAB_CLI_FORWARDING_LOCAL_PORT"},
67+
},
68+
&cli.StringFlag{
69+
Name: "identity-file",
70+
Usage: "select a file from which the identity (private key) for public key authentication is read",
71+
EnvVars: []string{"DBLAB_CLI_IDENTITY_FILE"},
6772
},
6873
&cli.BoolFlag{
6974
Name: "debug",
@@ -126,6 +131,12 @@ func loadEnvironmentParams(c *cli.Context) error {
126131
return err
127132
}
128133
}
134+
135+
if !c.IsSet(commands.IdentityFileKey) {
136+
if err := c.Set(commands.IdentityFileKey, env.Forwarding.IdentityFile); err != nil {
137+
return err
138+
}
139+
}
129140
}
130141

131142
return nil

‎pkg/portfwd/sshtunnel.go

Copy file name to clipboardExpand all lines: pkg/portfwd/sshtunnel.go
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package portfwd
77

88
import (
99
"context"
10+
"fmt"
1011
"io"
12+
"io/ioutil"
1113
"net"
1214
"os"
1315

@@ -159,3 +161,20 @@ func SSHAgent() ssh.AuthMethod {
159161

160162
return nil
161163
}
164+
165+
// ReadAuthFromIdentityFile reads an identity file and returns an AuthMethod that uses the given key pairs.
166+
func ReadAuthFromIdentityFile(identityFilename string) (ssh.AuthMethod, error) {
167+
log.Dbg(fmt.Sprintf("Read identity file %q", identityFilename))
168+
169+
privateKey, err := ioutil.ReadFile(identityFilename)
170+
if err != nil {
171+
return nil, errors.Wrap(err, "failed to read an identity file")
172+
}
173+
174+
signer, err := ssh.ParsePrivateKey(privateKey)
175+
if err != nil {
176+
return nil, errors.Wrap(err, "failed to parse a private key")
177+
}
178+
179+
return ssh.PublicKeys(signer), nil
180+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.