1
1
package main
2
2
3
3
import (
4
+ "errors"
4
5
"fmt"
5
6
"io/ioutil"
6
7
"log"
@@ -47,8 +48,11 @@ func setupUserInitFlags(flag *pflag.FlagSet) {
47
48
flag .String (IAMRoleFlag , "" , "The IAM role name assigned to the user being setup" )
48
49
flag .String (OutputFlag , "json" , "The AWS CLI output format" )
49
50
51
+ // No MFA Setup
52
+ flag .Bool (NoMFAFlag , false , "When present do not provision an MFA device, assume one exists" )
53
+
50
54
// Verbose
51
- flag .BoolP (VerboseFlag , "v" , false , "log messages at the debug level. " )
55
+ flag .BoolP (VerboseFlag , "v" , false , "log messages at the debug level" )
52
56
53
57
flag .SortFlags = false
54
58
}
@@ -93,6 +97,7 @@ type User struct {
93
97
SecretAccessKey string
94
98
QrTempFile * os.File
95
99
Keyring * keyring.Keyring
100
+ NoMFA bool
96
101
}
97
102
98
103
// Setup orchestrates the tasks to create the user's MFA and rotate access
@@ -108,14 +113,21 @@ func (u *User) Setup(logger *log.Logger) {
108
113
logger .Fatal (err )
109
114
}
110
115
111
- err = u .CreateVirtualMFADevice (logger )
112
- if err != nil {
113
- logger .Fatal (err )
114
- }
116
+ if u .NoMFA {
117
+ err = u .GetMFADevice (logger )
118
+ if err != nil {
119
+ logger .Fatal (err )
120
+ }
121
+ } else {
122
+ err = u .CreateVirtualMFADevice (logger )
123
+ if err != nil {
124
+ logger .Fatal (err )
125
+ }
115
126
116
- err = u .EnableVirtualMFADevice (logger )
117
- if err != nil {
118
- logger .Fatal (err )
127
+ err = u .EnableVirtualMFADevice (logger )
128
+ if err != nil {
129
+ logger .Fatal (err )
130
+ }
119
131
}
120
132
121
133
err = u .UpdateAWSConfigFile (logger )
@@ -200,6 +212,37 @@ func (u *User) newMFASession(logger *log.Logger) (*session.Session, error) {
200
212
return mfaSession , nil
201
213
}
202
214
215
+ // GetMFADevice gets the user's existing virtual MFA device and updates the
216
+ // MFA serial in the profile field.
217
+ func (u * User ) GetMFADevice (logger * log.Logger ) error {
218
+ logger .Println ("Getting the existing MFA device..." )
219
+
220
+ sess , err := u .newSession ()
221
+ if err != nil {
222
+ return fmt .Errorf ("unable to get new session: %w" , err )
223
+ }
224
+ svc := iam .New (sess )
225
+
226
+ mfaDeviceInput := & iam.ListMFADevicesInput {
227
+ UserName : aws .String (u .Name ),
228
+ }
229
+
230
+ mfaDeviceOutput , err := svc .ListMFADevices (mfaDeviceInput )
231
+ if err != nil {
232
+ return fmt .Errorf ("unable to get MFA: %w" , err )
233
+ }
234
+
235
+ if len (mfaDeviceOutput .MFADevices ) == 0 {
236
+ return errors .New ("no MFA devices registered" )
237
+ }
238
+ mfaDevice := mfaDeviceOutput .MFADevices [0 ]
239
+
240
+ u .BaseProfile .MFASerial = * mfaDevice .SerialNumber
241
+ u .RoleProfile .MFASerial = * mfaDevice .SerialNumber
242
+
243
+ return nil
244
+ }
245
+
203
246
// CreateVirtualMFADevice creates the user's virtual MFA device and updates the
204
247
// MFA serial in the profile field.
205
248
func (u * User ) CreateVirtualMFADevice (logger * log.Logger ) error {
@@ -572,6 +615,7 @@ func setupUserFunction(cmd *cobra.Command, args []string) error {
572
615
iamUser := v .GetString (IAMUserFlag )
573
616
iamRole := v .GetString (IAMRoleFlag )
574
617
output := v .GetString (OutputFlag )
618
+ noMFA := v .GetBool (NoMFAFlag )
575
619
576
620
// Validator used to validate input options for MFA
577
621
validate = validator .New ()
@@ -628,6 +672,7 @@ func setupUserFunction(cmd *cobra.Command, args []string) error {
628
672
Config : config ,
629
673
QrTempFile : tempfile ,
630
674
Keyring : keyring ,
675
+ NoMFA : noMFA ,
631
676
}
632
677
err = checkExistingAWSProfile (baseProfile .Name , config , logger )
633
678
if err != nil {
0 commit comments