@@ -19,11 +19,9 @@ import (
19
19
// AddProfileInitFlags sets up the CLI flags for the 'add-profile' subcommand
20
20
func AddProfileInitFlags (flag * pflag.FlagSet ) {
21
21
22
- flag .String (VaultAWSKeychainNameFlag , VaultAWSKeychainNameDefault , "The aws-vault keychain name" )
23
22
flag .StringSlice (AWSProfileAccountFlag , []string {}, "A comma separated list of AWS profiles and account IDs 'PROFILE1:ACCOUNTID1,PROFILE2:ACCOUNTID2,...'" )
24
- flag .String (AWSBaseProfileFlag , "" , fmt . Sprintf ( "The AWS base profile. If none provided will use first profile name from %q flag" , AWSProfileAccountFlag ) )
23
+ flag .String (AWSProfileFlag , "" , "The AWS profile used to get the source_profile and mfa_serial attributes" )
25
24
flag .String (AWSRegionFlag , endpoints .UsWest2RegionID , "The AWS region" )
26
- flag .String (IAMUserFlag , "" , "The IAM user name to setup" )
27
25
flag .String (IAMRoleFlag , "" , "The IAM role name assigned to the user being setup" )
28
26
flag .String (OutputFlag , "json" , "The AWS CLI output format" )
29
27
@@ -48,10 +46,6 @@ func AddProfileCheckConfig(v *viper.Viper) error {
48
46
return fmt .Errorf ("AWS Profile and Account ID check failed: %w" , err )
49
47
}
50
48
51
- if err := checkIAMUser (v ); err != nil {
52
- return fmt .Errorf ("IAM User check failed: %w" , err )
53
- }
54
-
55
49
if err := checkIAMRole (v ); err != nil {
56
50
return fmt .Errorf ("IAM Role check failed: %w" , err )
57
51
}
@@ -63,19 +57,110 @@ func AddProfileCheckConfig(v *viper.Viper) error {
63
57
return nil
64
58
}
65
59
60
+ // AddProfileConfig holds information for the AWS user being configured by this script
61
+ type AddProfileConfig struct {
62
+ Logger * log.Logger
63
+ Config * vault.ConfigFile
64
+
65
+ IAMRole string
66
+ Partition string
67
+ Region string
68
+ Output string
69
+
70
+ BaseProfileName string
71
+ AWSProfileName string
72
+ AWSProfileAccounts []string
73
+ AWSProfiles []vault.ProfileSection
74
+ MFASerial string
75
+ }
76
+
77
+ // UpdateAWSProfile updates or creates a single AWS profile to the AWS config file
78
+ func (apc * AddProfileConfig ) UpdateAWSProfile (iniFile * ini.File , profile * vault.ProfileSection , sourceProfile * string ) error {
79
+ apc .Logger .Printf ("Adding the profile %q to the AWS config file" , profile .Name )
80
+ sectionName := fmt .Sprintf ("profile %s" , profile .Name )
81
+
82
+ // Get or create section before updating
83
+ var err error
84
+ var section * ini.Section
85
+ section = iniFile .Section (sectionName )
86
+ if section == nil {
87
+ section , err = iniFile .NewSection (sectionName )
88
+ if err != nil {
89
+ return fmt .Errorf ("error creating section %q: %w" , profile .Name , err )
90
+ }
91
+ }
92
+
93
+ // Add the source profile when provided
94
+ if sourceProfile != nil {
95
+ _ , err = section .NewKey ("source_profile" , * sourceProfile )
96
+ if err != nil {
97
+ return fmt .Errorf ("unable to add source profile: %w" , err )
98
+ }
99
+ }
100
+
101
+ if err = section .ReflectFrom (& profile ); err != nil {
102
+ return fmt .Errorf ("error mapping profile to ini file: %w" , err )
103
+ }
104
+ _ , err = section .NewKey ("output" , apc .Output )
105
+ if err != nil {
106
+ return fmt .Errorf ("unable to add output key: %w" , err )
107
+ }
108
+ return nil
109
+ }
110
+
66
111
// AddProfile adds a new profile to the AWS config file
67
- func (sc * SetupConfig ) AddProfile () error {
112
+ func (apc * AddProfileConfig ) AddProfile () error {
68
113
69
- sc .Logger .Printf ("Adding new profiles to the AWS config file: %s" , sc .Config .Path )
114
+ apc .Logger .Printf ("Adding new profiles to the AWS config file: %s" , apc .Config .Path )
70
115
71
116
// load the ini file
72
- iniFile , err := ini .Load (sc .Config .Path )
117
+ iniFile , err := ini .Load (apc .Config .Path )
73
118
if err != nil {
74
119
return fmt .Errorf ("unable to load aws config file: %w" , err )
75
120
}
76
121
122
+ roleProfileSection := iniFile .Section (fmt .Sprintf ("profile %s" , apc .AWSProfileName ))
123
+ // Get the source profile
124
+ sourceProfileKey , err := roleProfileSection .GetKey ("source_profile" )
125
+ if err != nil {
126
+ return fmt .Errorf ("Unable to get source profile from %q: %w" , apc .AWSProfileName , err )
127
+ }
128
+ apc .BaseProfileName = sourceProfileKey .String ()
129
+
130
+ // Get the MFA Serial
131
+ mfaSerialKey , err := roleProfileSection .GetKey ("mfa_serial" )
132
+ if err != nil {
133
+ return err
134
+ }
135
+ apc .MFASerial = mfaSerialKey .String ()
136
+
137
+ // Add each of the remaining profiles
138
+ for _ , profileAccount := range apc .AWSProfileAccounts {
139
+ profileAccountParts := strings .Split (profileAccount , ":" )
140
+ profileName := profileAccountParts [0 ]
141
+ accountID := profileAccountParts [1 ]
142
+
143
+ roleProfile := vault.ProfileSection {
144
+ Name : profileName ,
145
+ Region : apc .Region ,
146
+ MfaSerial : apc .MFASerial ,
147
+
148
+ // Each account assumes a role that is added to the config profile
149
+ RoleARN : fmt .Sprintf ("arn:%s:iam::%s:role/%s" ,
150
+ apc .Partition ,
151
+ accountID ,
152
+ apc .IAMRole ),
153
+ }
154
+ apc .AWSProfiles = append (apc .AWSProfiles , roleProfile )
155
+
156
+ // Add the role profile with base as the source profile
157
+ if err := apc .UpdateAWSProfile (iniFile , & roleProfile , & apc .BaseProfileName ); err != nil {
158
+ return err
159
+ }
160
+ }
161
+
77
162
// save it back to the aws config path
78
- return iniFile .SaveTo (sc .Config .Path )
163
+ return iniFile .SaveTo (apc .Config .Path )
79
164
}
80
165
81
166
func addProfileFunction (cmd * cobra.Command , args []string ) error {
@@ -122,9 +207,8 @@ func addProfileFunction(cmd *cobra.Command, args []string) error {
122
207
123
208
// Get command line flag values
124
209
awsRegion := v .GetString (AWSRegionFlag )
125
- awsVaultKeychainName := v .GetString (VaultAWSKeychainNameFlag )
126
- // awsProfileAccount := v.GetStringSlice(AWSProfileAccountFlag)
127
- iamUser := v .GetString (IAMUserFlag )
210
+ awsProfileAccount := v .GetStringSlice (AWSProfileAccountFlag )
211
+ awsProfile := v .GetString (AWSProfileFlag )
128
212
iamRole := v .GetString (IAMRoleFlag )
129
213
output := v .GetString (OutputFlag )
130
214
@@ -142,29 +226,23 @@ func addProfileFunction(cmd *cobra.Command, args []string) error {
142
226
logger .Fatal (err )
143
227
}
144
228
145
- keyring , err := getKeyring (awsVaultKeychainName )
146
- if err != nil {
147
- logger .Fatal (err )
148
- }
149
-
150
- setupConfig := SetupConfig {
229
+ addProfileConfig := AddProfileConfig {
151
230
// Config
152
- Logger : logger ,
153
- Config : config ,
154
- Keyring : keyring ,
231
+ Logger : logger ,
232
+ Config : config ,
155
233
156
234
// Profile Inputs
157
- IAMUser : iamUser ,
158
235
IAMRole : iamRole ,
159
236
Region : awsRegion ,
160
237
Partition : partition ,
161
238
Output : output ,
162
239
163
- // RoleProfileName: &awsVaultProfileAccount[0],
164
- // NewProfiles: awsVaultProfileAccount[1:],
240
+ // Profiles
241
+ AWSProfileAccounts : awsProfileAccount ,
242
+ AWSProfileName : awsProfile ,
165
243
}
166
244
167
- if err := setupConfig .AddProfile (); err != nil {
245
+ if err := addProfileConfig .AddProfile (); err != nil {
168
246
logger .Fatal (err )
169
247
}
170
248
0 commit comments