Skip to content

Commit 9d78bf5

Browse files
akerl-unprivakerl
andauthored
update xargs results (#41)
* update xargs results * update account passing Co-authored-by: Les Aker <[email protected]>
1 parent be8e490 commit 9d78bf5

18 files changed

+95
-59
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 3.0.0 / 2020-07-17
2+
3+
* [ENHANCEMENT] Multi processing now supports configurable KeyFunc and passes through tags, to enable downstream libraries to better customize xargs results
4+
15
# 2.10.4 / 2020-06-05
26

37
* [ENHANCEMENT] Update deps

cmd/profiles.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package cmd
22

33
import (
4-
"github.com/akerl/voyager/v2/cartogram"
4+
"github.com/akerl/voyager/v3/cartogram"
55

66
"github.com/spf13/cobra"
77
)

cmd/profiles_add.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package cmd
33
import (
44
"fmt"
55

6-
"github.com/akerl/voyager/v2/profiles"
6+
"github.com/akerl/voyager/v3/profiles"
77

88
"github.com/akerl/input/list"
99
"github.com/spf13/cobra"

cmd/profiles_delete.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package cmd
33
import (
44
"fmt"
55

6-
"github.com/akerl/voyager/v2/profiles"
7-
"github.com/akerl/voyager/v2/utils"
6+
"github.com/akerl/voyager/v3/profiles"
7+
"github.com/akerl/voyager/v3/utils"
88

99
"github.com/spf13/cobra"
1010
)

cmd/profiles_list.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"fmt"
55
"sort"
66

7-
"github.com/akerl/voyager/v2/profiles"
7+
"github.com/akerl/voyager/v3/profiles"
88

99
"github.com/spf13/cobra"
1010
)

cmd/profiles_rotate.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package cmd
22

33
import (
4-
"github.com/akerl/voyager/v2/rotate"
5-
"github.com/akerl/voyager/v2/yubikey"
4+
"github.com/akerl/voyager/v3/rotate"
5+
"github.com/akerl/voyager/v3/yubikey"
66

77
"github.com/akerl/speculate/v2/creds"
88
"github.com/spf13/cobra"

cmd/profiles_show.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package cmd
33
import (
44
"fmt"
55

6-
"github.com/akerl/voyager/v2/profiles"
6+
"github.com/akerl/voyager/v3/profiles"
77

88
"github.com/spf13/cobra"
99
)

cmd/travel.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package cmd
33
import (
44
"fmt"
55

6-
"github.com/akerl/voyager/v2/cartogram"
7-
"github.com/akerl/voyager/v2/travel"
8-
"github.com/akerl/voyager/v2/yubikey"
6+
"github.com/akerl/voyager/v3/cartogram"
7+
"github.com/akerl/voyager/v3/travel"
8+
"github.com/akerl/voyager/v3/yubikey"
99

1010
"github.com/akerl/input/list"
1111
"github.com/akerl/speculate/v2/creds"

cmd/version.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55

66
"github.com/spf13/cobra"
77

8-
"github.com/akerl/voyager/v2/version"
8+
"github.com/akerl/voyager/v3/version"
99
)
1010

1111
var versionCmd = &cobra.Command{

cmd/xargs.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import (
44
"encoding/json"
55
"fmt"
66

7-
"github.com/akerl/voyager/v2/cartogram"
8-
"github.com/akerl/voyager/v2/multi"
9-
"github.com/akerl/voyager/v2/travel"
10-
"github.com/akerl/voyager/v2/yubikey"
7+
"github.com/akerl/voyager/v3/cartogram"
8+
"github.com/akerl/voyager/v3/multi"
9+
"github.com/akerl/voyager/v3/travel"
10+
"github.com/akerl/voyager/v3/yubikey"
1111

1212
"github.com/akerl/input/list"
1313
"github.com/akerl/speculate/v2/creds"

go.mod

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/akerl/voyager/v2
1+
module github.com/akerl/voyager/v3
22

33
go 1.14
44

@@ -12,9 +12,9 @@ require (
1212
github.com/99designs/keyring v0.0.0-00010101000000-000000000000
1313
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
1414
github.com/akerl/input v0.0.13
15-
github.com/akerl/speculate/v2 v2.5.4
15+
github.com/akerl/speculate/v2 v2.5.5
1616
github.com/akerl/timber/v2 v2.0.1
17-
github.com/aws/aws-sdk-go v1.31.12
17+
github.com/aws/aws-sdk-go v1.33.6
1818
github.com/mdp/qrterminal/v3 v3.0.0
1919
github.com/pquerna/otp v1.2.0
2020
github.com/spf13/cobra v1.0.0

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ github.com/akerl/input v0.0.13 h1:pg/9xphhUiN6Vch1s/KTHkqkrtAmGVt1/0FTY0nk6Vg=
1313
github.com/akerl/input v0.0.13/go.mod h1:5AaWoVuZjlTiAcSz69C9xVIQ1SYRC9c6fBgn1jsWnWs=
1414
github.com/akerl/keyring v0.0.0-20200219084108-1f409e548abc h1:rgr2nWwLQ++doaXhUFx3ttJLPtWZGLCKzL8YnLFR5dw=
1515
github.com/akerl/keyring v0.0.0-20200219084108-1f409e548abc/go.mod h1:7Jt2k9tnyY3YKoQgGSxYkwBXKNZFZas/DwB1RhNoG1o=
16-
github.com/akerl/speculate/v2 v2.5.4 h1:2+8n1uHBLQft0juDl/CkYFhMfnTZDug0WZydS7jgA8k=
17-
github.com/akerl/speculate/v2 v2.5.4/go.mod h1:js10Uj+OHLseRukWKOGaC/DSfIMfSfVWR6ig5i4TzN4=
16+
github.com/akerl/speculate/v2 v2.5.5 h1:oKyX44vxQ/XPqQw3CGSBrLkRmtDtXuVPMMvtJ7kVIj4=
17+
github.com/akerl/speculate/v2 v2.5.5/go.mod h1:rDf7gUb/C3KFXqFzT/E2wFxW9u5e3mKJpkAL783wctg=
1818
github.com/akerl/timber/v2 v2.0.1 h1:hY4VCOJns7KsxwxP/ifSt3Rz9GZCfKewapaimObnA2E=
1919
github.com/akerl/timber/v2 v2.0.1/go.mod h1:jBjRGI2CWuvbZlrZkp1JO/X51pMlbg72NFy+Vnd59oI=
2020
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
2121
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
2222
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
23-
github.com/aws/aws-sdk-go v1.31.12 h1:SxRRGyhlCagI0DYkhOg+FgdXGXzRTE3vEX/gsgFaiKQ=
24-
github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
23+
github.com/aws/aws-sdk-go v1.33.6 h1:YLoUeMSx05kHwhS+HLDSpdYYpPzJMyp6hn1cWsJ6a+U=
24+
github.com/aws/aws-sdk-go v1.33.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
2525
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
2626
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
2727
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"os"
55

6-
"github.com/akerl/voyager/v2/cmd"
6+
"github.com/akerl/voyager/v3/cmd"
77

88
"github.com/akerl/speculate/v2/helpers"
99
)

multi/main.go

+52-19
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import (
77
"strings"
88
"time"
99

10-
"github.com/akerl/voyager/v2/travel"
10+
"github.com/akerl/voyager/v3/cartogram"
11+
"github.com/akerl/voyager/v3/travel"
1112

1213
"github.com/akerl/speculate/v2/creds"
1314
"github.com/akerl/timber/v2/log"
@@ -25,28 +26,38 @@ type Processor struct {
2526
RoleNames []string
2627
ProfileNames []string
2728
SkipConfirm bool
29+
KeyFunc func(cartogram.Account) (string, cartogram.Tags)
30+
}
31+
32+
// ExecResult is based on creds.ExecResult but adds account tags
33+
type ExecResult struct {
34+
Tags cartogram.Tags `json:"tags"`
35+
Error error `json:"error"`
36+
ExitCode int `json:"exitcode"`
37+
StdOut string `json:"stdout"`
38+
StdErr string `json:"stderr"`
2839
}
2940

3041
// ExecString runs a command string against a set of accounts
31-
func (p Processor) ExecString(cmd string) (map[string]creds.ExecResult, error) {
42+
func (p Processor) ExecString(cmd string) (map[string]ExecResult, error) {
3243
args, err := creds.StringToCommand(cmd)
3344
if err != nil {
34-
return map[string]creds.ExecResult{}, err
45+
return map[string]ExecResult{}, err
3546
}
3647
return p.Exec(args)
3748
}
3849

3950
// Exec runs a command against a set of accounts
40-
func (p Processor) Exec(cmd []string) (map[string]creds.ExecResult, error) {
51+
func (p Processor) Exec(cmd []string) (map[string]ExecResult, error) {
4152
logger.InfoMsgf("processing command: %v", cmd)
4253

4354
paths, err := p.Grapher.ResolveAll(p.Args, p.RoleNames, p.ProfileNames)
4455
if err != nil {
45-
return map[string]creds.ExecResult{}, err
56+
return map[string]ExecResult{}, err
4657
}
4758

4859
if !p.confirm(paths) {
49-
return map[string]creds.ExecResult{}, fmt.Errorf("aborted by user")
60+
return map[string]ExecResult{}, fmt.Errorf("aborted by user")
5061
}
5162

5263
inputCh := make(chan workerInput, len(paths))
@@ -58,10 +69,15 @@ func (p Processor) Exec(cmd []string) (map[string]creds.ExecResult, error) {
5869
}
5970

6071
for _, item := range paths {
72+
account := item[len(item)-1]
73+
key, tags := p.ParseKey(account.Account)
74+
6175
inputCh <- workerInput{
6276
Path: item,
6377
Options: p.Options,
6478
Command: cmd,
79+
Key: key,
80+
Tags: tags,
6581
}
6682
}
6783
close(inputCh)
@@ -80,10 +96,10 @@ func (p Processor) Exec(cmd []string) (map[string]creds.ExecResult, error) {
8096
),
8197
)
8298

83-
output := map[string]creds.ExecResult{}
99+
output := map[string]ExecResult{}
84100
for i := 1; i <= len(paths); i++ {
85101
result := <-outputCh
86-
output[result.AccountID] = result.ExecResult
102+
output[result.Key] = result.ExecResult
87103
bar.Increment()
88104
refreshCh <- time.Now()
89105
}
@@ -92,13 +108,26 @@ func (p Processor) Exec(cmd []string) (map[string]creds.ExecResult, error) {
92108
return output, nil
93109
}
94110

111+
// ParseKey derives an output key from an account
112+
func (p Processor) ParseKey(account cartogram.Account) (string, cartogram.Tags) {
113+
if p.KeyFunc == nil {
114+
return DefaultKeyFunc(account)
115+
}
116+
return p.KeyFunc(account)
117+
}
118+
119+
// DefaultKeyFunc uses the account's ID as the key, and passes through its tags
120+
func DefaultKeyFunc(account cartogram.Account) (string, cartogram.Tags) {
121+
return account.Account, account.Tags
122+
}
123+
95124
func (p Processor) confirm(paths []travel.Path) bool {
96125
if p.SkipConfirm {
97126
return true
98127
}
99128
fmt.Fprintln(os.Stderr, "Will run on the following accounts:")
100129
for _, item := range paths {
101-
accountID := item[len(item)-1].Account
130+
accountID := item[len(item)-1].Account.Account
102131
ok, account := p.Grapher.Pack.Lookup(accountID)
103132
if !ok {
104133
fmt.Fprintf(os.Stderr, "Failed account lookup: %s\n", accountID)
@@ -124,28 +153,32 @@ type workerInput struct {
124153
Path travel.Path
125154
Options travel.TraverseOptions
126155
Command []string
156+
Key string
157+
Tags cartogram.Tags
127158
}
128159

129160
type workerOutput struct {
130-
AccountID string
131-
ExecResult creds.ExecResult
161+
Key string
162+
ExecResult ExecResult
132163
}
133164

134165
func execWorker(inputCh <-chan workerInput, outputCh chan<- workerOutput) {
135166
for item := range inputCh {
136167
c, err := item.Path.TraverseWithOptions(item.Options)
137168
if err != nil {
138-
outputCh <- workerOutput{ExecResult: creds.ExecResult{Error: err}}
139-
continue
140-
}
141-
accountID, err := c.AccountID()
142-
if err != nil {
143-
outputCh <- workerOutput{ExecResult: creds.ExecResult{Error: err}}
169+
outputCh <- workerOutput{ExecResult: ExecResult{Error: err}}
144170
continue
145171
}
172+
result := c.Exec(item.Command)
146173
outputCh <- workerOutput{
147-
AccountID: accountID,
148-
ExecResult: c.Exec(item.Command),
174+
Key: item.Key,
175+
ExecResult: ExecResult{
176+
Tags: item.Tags,
177+
Error: result.Error,
178+
ExitCode: result.ExitCode,
179+
StdOut: result.StdOut,
180+
StdErr: result.StdErr,
181+
},
149182
}
150183
}
151184
}

rotate/main.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import (
66
"strings"
77
"time"
88

9-
"github.com/akerl/voyager/v2/cartogram"
10-
"github.com/akerl/voyager/v2/profiles"
11-
"github.com/akerl/voyager/v2/travel"
12-
"github.com/akerl/voyager/v2/utils"
13-
"github.com/akerl/voyager/v2/version"
9+
"github.com/akerl/voyager/v3/cartogram"
10+
"github.com/akerl/voyager/v3/profiles"
11+
"github.com/akerl/voyager/v3/travel"
12+
"github.com/akerl/voyager/v3/utils"
13+
"github.com/akerl/voyager/v3/version"
1414

1515
"github.com/akerl/input/list"
1616
"github.com/akerl/speculate/v2/creds"

travel/cache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,5 @@ func (mc *MapCache) hopToKey(h Hop) string {
8787
if h.Profile != "" {
8888
return fmt.Sprintf("profile--%s", h.Profile)
8989
}
90-
return fmt.Sprintf("%s-%s-%t", h.Account, h.Role, h.Mfa)
90+
return fmt.Sprintf("%s-%s-%t", h.Account.Account, h.Role, h.Mfa)
9191
}

travel/grapher.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package travel
22

33
import (
4-
"github.com/akerl/voyager/v2/cartogram"
4+
"github.com/akerl/voyager/v3/cartogram"
55

66
"github.com/akerl/input/list"
77
)
@@ -137,9 +137,8 @@ func (g *Grapher) findPathToRole(account cartogram.Account, role cartogram.Role)
137137

138138
myHop := Hop{
139139
Role: role.Name,
140-
Account: account.Account,
140+
Account: account,
141141
Mfa: role.Mfa,
142-
Region: account.Region,
143142
}
144143

145144
for i := range allPaths {

travel/path.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package travel
33
import (
44
"fmt"
55

6-
"github.com/akerl/voyager/v2/profiles"
7-
"github.com/akerl/voyager/v2/version"
6+
"github.com/akerl/voyager/v3/cartogram"
7+
"github.com/akerl/voyager/v3/profiles"
8+
"github.com/akerl/voyager/v3/version"
89

910
"github.com/BurntSushi/locker"
1011
"github.com/akerl/speculate/v2/creds"
@@ -23,10 +24,9 @@ type Path []Hop
2324
// to the target role
2425
type Hop struct {
2526
Profile string
26-
Account string
27+
Account cartogram.Account
2728
Role string
2829
Mfa bool
29-
Region string
3030
}
3131

3232
// TraverseOptions defines the parameters for traversing a path
@@ -106,7 +106,7 @@ func (h Hop) Traverse(c creds.Creds, opts TraverseOptions) (creds.Creds, error)
106106
logger.InfoMsgf("Executing hop: %+v", h)
107107
a := creds.AssumeRoleOptions{
108108
RoleName: h.Role,
109-
AccountID: h.Account,
109+
AccountID: h.Account.Account,
110110
SessionName: opts.SessionName,
111111
Lifetime: opts.Lifetime,
112112
}
@@ -117,7 +117,7 @@ func (h Hop) Traverse(c creds.Creds, opts TraverseOptions) (creds.Creds, error)
117117
a.MfaPrompt = opts.MfaPrompt
118118
}
119119

120-
c.Region = h.Region
120+
c.Region = h.Account.Region
121121
newCreds, err := c.AssumeRole(a)
122122
if err != nil {
123123
return creds.Creds{}, err
@@ -130,5 +130,5 @@ func (h *Hop) toKey() string {
130130
if h.Profile != "" {
131131
return fmt.Sprintf("profile--%s", h.Profile)
132132
}
133-
return fmt.Sprintf("%s-%s-%t", h.Account, h.Role, h.Mfa)
133+
return fmt.Sprintf("%s-%s-%t", h.Account.Account, h.Role, h.Mfa)
134134
}

0 commit comments

Comments
 (0)