1
1
package multi
2
2
3
3
import (
4
+ "bufio"
5
+ "fmt"
4
6
"os"
5
7
"strings"
6
8
"time"
@@ -22,6 +24,7 @@ type Processor struct {
22
24
Args []string
23
25
RoleNames []string
24
26
ProfileNames []string
27
+ SkipConfirm bool
25
28
}
26
29
27
30
// ExecString runs a command string against a set of accounts
@@ -39,6 +42,10 @@ func (p Processor) Exec(cmd []string) (map[string]creds.ExecResult, error) {
39
42
return map [string ]creds.ExecResult {}, err
40
43
}
41
44
45
+ if ! p .confirm (paths ) {
46
+ return map [string ]creds.ExecResult {}, fmt .Errorf ("aborted by user" )
47
+ }
48
+
42
49
inputCh := make (chan workerInput , len (paths ))
43
50
outputCh := make (chan workerOutput , len (paths ))
44
51
refreshCh := make (chan time.Time )
@@ -82,6 +89,34 @@ func (p Processor) Exec(cmd []string) (map[string]creds.ExecResult, error) {
82
89
return output , nil
83
90
}
84
91
92
+ func (p Processor ) confirm (paths []travel.Path ) bool {
93
+ if p .SkipConfirm {
94
+ return true
95
+ }
96
+ fmt .Fprintln (os .Stderr , "Will run on the following accounts:" )
97
+ for _ , item := range paths {
98
+ accountID := item [len (item )- 1 ].Account
99
+ ok , account := p .Grapher .Pack .Lookup (accountID )
100
+ if ! ok {
101
+ fmt .Fprintf (os .Stderr , "Failed account lookup: %s\n " , accountID )
102
+ return false
103
+ }
104
+ fmt .Fprintf (os .Stderr , " %s -- %s\n " , account .Account , account .Tags )
105
+ }
106
+ fmt .Fprintln (os .Stderr , "Type 'yes' to confirm" )
107
+ confirmReader := bufio .NewReader (os .Stdin )
108
+ confirmInput , err := confirmReader .ReadString ('\n' )
109
+ if err != nil {
110
+ fmt .Fprintf (os .Stderr , "Error reading prompt: %s" , err )
111
+ return false
112
+ }
113
+ cleanedInput := strings .TrimSpace (confirmInput )
114
+ if cleanedInput != "yes" {
115
+ return false
116
+ }
117
+ return true
118
+ }
119
+
85
120
type workerInput struct {
86
121
Path travel.Path
87
122
Options travel.TraverseOptions
0 commit comments