Skip to content

Commit cc907a2

Browse files
authored
Merge pull request #120 from davrodpin/alias/cli-flags
Add flags to "start alias" command
2 parents 92f82af + 1452fd8 commit cc907a2

File tree

5 files changed

+170
-15
lines changed

5 files changed

+170
-15
lines changed

alias/alias.go

+7
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ func (a Alias) ParseTunnelFlags() (*TunnelFlags, error) {
167167
return tf, nil
168168
}
169169

170+
// Merge overwrites certain Alias attributes based on the given TunnelFlags.
171+
func (a *Alias) Merge(tunnelFlags *TunnelFlags) {
172+
a.Verbose = tunnelFlags.Verbose
173+
a.Insecure = tunnelFlags.Insecure
174+
a.Detach = tunnelFlags.Detach
175+
}
176+
170177
func (a Alias) String() string {
171178
return fmt.Sprintf("[verbose: %t, insecure: %t, detach: %t, source: %s, destination: %s, server: %s, key: %s, keep-alive-interval: %s, connection-retries: %d, wait-and-retry: %s, ssh-agent: %s, timeout: %s]",
172179
a.Verbose,

alias/alias_test.go

+132
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111
"testing"
1212
"text/template"
13+
"time"
1314

1415
"github.com/davrodpin/mole/alias"
1516
)
@@ -241,6 +242,137 @@ func TestShowAll(t *testing.T) {
241242
}
242243
}
243244

245+
func TestAliasMerge(t *testing.T) {
246+
keepAliveInterval, _ := time.ParseDuration("5s")
247+
248+
tests := []struct {
249+
alias alias.Alias
250+
tunnelFlags *alias.TunnelFlags
251+
}{
252+
{
253+
alias.Alias{
254+
Verbose: false,
255+
Insecure: false,
256+
Detach: false,
257+
Source: []string{"127.0.0.1:80"},
258+
Destination: []string{"172.17.0.100:8080"},
259+
Server: "[email protected]:22",
260+
Key: "path/to/key/1",
261+
KeepAliveInterval: "3s",
262+
ConnectionRetries: 3,
263+
WaitAndRetry: "10s",
264+
SshAgent: "path/to/sshagent",
265+
Timeout: "3s",
266+
},
267+
&alias.TunnelFlags{
268+
Verbose: true,
269+
Insecure: true,
270+
Detach: true,
271+
Source: alias.AddressInputList([]alias.AddressInput{alias.AddressInput{Host: "127.0.0.1", Port: "80"}}),
272+
Destination: alias.AddressInputList([]alias.AddressInput{alias.AddressInput{Host: "172.17.0.100", Port: "8080"}}),
273+
Server: alias.AddressInput{Host: "acme.com", Port: "22"},
274+
Key: "path/to/key/2",
275+
KeepAliveInterval: keepAliveInterval,
276+
ConnectionRetries: 10,
277+
},
278+
},
279+
}
280+
281+
for id, test := range tests {
282+
test.alias.Merge(test.tunnelFlags)
283+
284+
if test.alias.Verbose != test.tunnelFlags.Verbose {
285+
t.Errorf("alias verbose doesn't match on test %d: expected: %t, value: %t", id, test.tunnelFlags.Verbose, test.alias.Verbose)
286+
}
287+
288+
if test.alias.Insecure != test.tunnelFlags.Insecure {
289+
t.Errorf("alias insecure doesn't match on test %d: expected: %t, value: %t", id, test.tunnelFlags.Insecure, test.alias.Insecure)
290+
}
291+
292+
if test.alias.Detach != test.tunnelFlags.Detach {
293+
t.Errorf("alias detach doesn't match on test %d: expected: %t, value: %t", id, test.tunnelFlags.Detach, test.alias.Detach)
294+
}
295+
}
296+
297+
}
298+
299+
func TestParseAlias(t *testing.T) {
300+
kai, _ := time.ParseDuration("3s")
301+
war, _ := time.ParseDuration("5s")
302+
tim, _ := time.ParseDuration("1s")
303+
304+
flags := alias.TunnelFlags{
305+
TunnelType: "local",
306+
Verbose: false,
307+
Insecure: false,
308+
Detach: false,
309+
Source: alias.AddressInputList{alias.AddressInput{Host: "127.0.0.1", Port: "8080"}},
310+
Destination: alias.AddressInputList{alias.AddressInput{Host: "172.17.0.100", Port: "80"}},
311+
Server: alias.AddressInput{},
312+
Key: "path/to/key/1",
313+
KeepAliveInterval: kai,
314+
ConnectionRetries: 3,
315+
WaitAndRetry: war,
316+
SshAgent: "path/to/sshagent",
317+
Timeout: tim,
318+
}
319+
320+
al := flags.ParseAlias("aliasName")
321+
322+
if flags.TunnelType != al.TunnelType {
323+
t.Errorf("tunnelType does not match: expected: %s, value: %s", flags.TunnelType, al.TunnelType)
324+
}
325+
326+
if flags.Verbose != al.Verbose {
327+
t.Errorf("verbose does not match: expected: %t, value: %t", flags.Verbose, al.Verbose)
328+
}
329+
330+
if flags.Insecure != al.Insecure {
331+
t.Errorf("insecure does not match: expected: %t, value: %t", flags.Insecure, al.Insecure)
332+
}
333+
334+
if flags.Detach != al.Detach {
335+
t.Errorf("detach does not match: expected: %t, value: %t", flags.Detach, al.Detach)
336+
}
337+
338+
if !reflect.DeepEqual(flags.Source.List(), al.Source) {
339+
t.Errorf("source does not match: expected: %s, value: %s", flags.Source.List(), al.Source)
340+
}
341+
342+
if !reflect.DeepEqual(flags.Destination.List(), al.Destination) {
343+
t.Errorf("destination does not match: expected: %s, value: %s", flags.Destination.List(), al.Destination)
344+
}
345+
346+
if flags.Server.String() != al.Server {
347+
t.Errorf("server does not match: expected: %s, value: %s", flags.Server.String(), al.Server)
348+
}
349+
350+
if flags.Key != al.Key {
351+
t.Errorf("key does not match: expected: %s, value: %s", flags.Key, al.Key)
352+
}
353+
354+
if flags.KeepAliveInterval.String() != al.KeepAliveInterval {
355+
t.Errorf("keep alive interval does not match: expected: %s, value: %s", flags.KeepAliveInterval.String(), al.KeepAliveInterval)
356+
}
357+
358+
if flags.ConnectionRetries != al.ConnectionRetries {
359+
t.Errorf("connection retries does not match: expected: %d, value: %d", flags.ConnectionRetries, al.ConnectionRetries)
360+
}
361+
362+
if flags.WaitAndRetry.String() != al.WaitAndRetry {
363+
t.Errorf("wait and retry does not match: expected: %s, value: %s", flags.WaitAndRetry.String(), al.WaitAndRetry)
364+
}
365+
366+
if flags.SshAgent != al.SshAgent {
367+
t.Errorf("ssh agent does not match: expected: %s, value: %s", flags.SshAgent, al.SshAgent)
368+
}
369+
370+
if flags.Timeout.String() != al.Timeout {
371+
t.Errorf("timeout does not match: expected: %s, value: %s", flags.Timeout.String(), al.Timeout)
372+
}
373+
374+
}
375+
244376
func addAlias() (*alias.Alias, error) {
245377
a := &alias.Alias{
246378
Name: "alias",

cmd/root.go

+6-11
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,23 @@ provide 0 to never give up or a negative number to disable`)
6363
return nil
6464
}
6565

66-
func start(alias string, tunnelFlags *alias.TunnelFlags) {
66+
func start(id string, tunnelFlags *alias.TunnelFlags) {
6767
if tunnelFlags.Detach {
6868
var err error
6969

70-
if alias == "" {
70+
if id == "" {
7171
u, err := uuid.NewV4()
7272
if err != nil {
7373
log.Errorf("error could not generate uuid: %v", err)
7474
os.Exit(1)
7575
}
76-
alias = u.String()[:8]
76+
id = u.String()[:8]
7777
}
7878

79-
err = startDaemonProcess(alias)
79+
err = startDaemonProcess(id)
8080
if err != nil {
8181
log.WithFields(log.Fields{
82-
"alias": alias,
82+
"id": id,
8383
}).Errorf("error starting ssh tunnel: %v", err)
8484
os.Exit(1)
8585
}
@@ -204,12 +204,7 @@ func startDaemonProcess(aliasName string) error {
204204
return nil
205205
}
206206

207-
func startWithAlias(aliasName string) error {
208-
a, err := alias.Get(aliasName)
209-
if err != nil {
210-
return err
211-
}
212-
207+
func startFromAlias(aliasName string, a *alias.Alias) error {
213208
f, err := a.ParseTunnelFlags()
214209
if err != nil {
215210
return err

cmd/start_alias.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import (
44
"errors"
55
"os"
66

7+
"github.com/davrodpin/mole/alias"
78
log "github.com/sirupsen/logrus"
89
"github.com/spf13/cobra"
910
)
1011

1112
var startAliasCmd = &cobra.Command{
1213
Use: "alias [name]",
1314
Short: "Starts a ssh tunnel by alias",
14-
Long: "Starts a ssh tunnel by alias",
15+
Long: `Starts a ssh tunnel by alias
16+
17+
The flags provided through this command can be used to override the one with the
18+
same name stored in the alias.
19+
`,
1520
Args: func(cmd *cobra.Command, args []string) error {
1621
if len(args) < 1 {
1722
return errors.New("alias name not provided")
@@ -22,14 +27,28 @@ var startAliasCmd = &cobra.Command{
2227
return nil
2328
},
2429
Run: func(cmd *cobra.Command, arg []string) {
25-
err := startWithAlias(aliasName)
30+
var err error
31+
32+
a, err := alias.Get(aliasName)
33+
if err != nil {
34+
log.WithError(err).Errorf("failed to start tunnel from alias %s", aliasName)
35+
os.Exit(1)
36+
}
37+
38+
a.Merge(tunnelFlags)
39+
40+
err = startFromAlias(aliasName, a)
2641
if err != nil {
27-
log.Errorf("failed to start tunnel: %v", err)
42+
log.WithError(err).Errorf("failed to start tunnel from alias %s", aliasName)
2843
os.Exit(1)
2944
}
3045
},
3146
}
3247

3348
func init() {
49+
startAliasCmd.Flags().BoolVarP(&tunnelFlags.Verbose, "verbose", "v", false, "increase log verbosity")
50+
startAliasCmd.Flags().BoolVarP(&tunnelFlags.Insecure, "insecure", "i", false, "skip host key validation when connecting to ssh server")
51+
startAliasCmd.Flags().BoolVarP(&tunnelFlags.Detach, "detach", "x", false, "run process in background")
52+
3453
startCmd.AddCommand(startAliasCmd)
3554
}

cmd/start_local.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ Destination endpoints are adrresess that can be reached from the jump server.
2929
}
3030

3131
func init() {
32-
err := bindFlags(tunnelFlags, localCmd)
32+
var err error
33+
34+
err = bindFlags(tunnelFlags, localCmd)
3335
if err != nil {
3436
log.WithError(err).Error("error parsing command line arguments")
3537
os.Exit(1)

0 commit comments

Comments
 (0)