Skip to content

Commit 2e47044

Browse files
author
Chris Gilmer
committed
Use a struct to capture inherited code
1 parent e582a1d commit 2e47044

File tree

5 files changed

+114
-160
lines changed

5 files changed

+114
-160
lines changed

cmd/add_profile.go

Lines changed: 24 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/spf13/cobra"
1313
"github.com/spf13/pflag"
1414
"github.com/spf13/viper"
15-
"gopkg.in/go-playground/validator.v9"
1615
"gopkg.in/ini.v1"
1716
)
1817

@@ -57,54 +56,20 @@ func AddProfileCheckConfig(v *viper.Viper) error {
5756
return nil
5857
}
5958

60-
// AddProfileConfig holds information for the AWS user being configured by this script
59+
// AddProfileConfig holds information for the AWS profile configured by this script
6160
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-
}
61+
DefaultConfig
7662

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-
}
63+
BaseProfileName string
64+
AWSProfileName string
65+
}
9266

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-
}
67+
// Run orchestrates the tasks to add a new profile
68+
func (apc *AddProfileConfig) Run() error {
69+
if err := apc.AddProfile(); err != nil {
70+
return err
9971
}
10072

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-
}
10873
return nil
10974
}
11075

@@ -212,9 +177,6 @@ func addProfileFunction(cmd *cobra.Command, args []string) error {
212177
iamRole := v.GetString(IAMRoleFlag)
213178
output := v.GetString(OutputFlag)
214179

215-
// Validator used to validate input options for MFA
216-
validate = validator.New()
217-
218180
// initialize things
219181
partition, err := getPartition(awsRegion)
220182
if err != nil {
@@ -226,23 +188,24 @@ func addProfileFunction(cmd *cobra.Command, args []string) error {
226188
logger.Fatal(err)
227189
}
228190

229-
addProfileConfig := AddProfileConfig{
230-
// Config
231-
Logger: logger,
232-
Config: config,
191+
// Setup new config
192+
addProfileConfig := AddProfileConfig{}
233193

234-
// Profile Inputs
235-
IAMRole: iamRole,
236-
Region: awsRegion,
237-
Partition: partition,
238-
Output: output,
194+
// Config
195+
addProfileConfig.Logger = logger
196+
addProfileConfig.Config = config
239197

240-
// Profiles
241-
AWSProfileAccounts: awsProfileAccount,
242-
AWSProfileName: awsProfile,
243-
}
198+
// Profile Inputs
199+
addProfileConfig.IAMRole = iamRole
200+
addProfileConfig.Region = awsRegion
201+
addProfileConfig.Partition = partition
202+
addProfileConfig.Output = output
203+
204+
// Profiles
205+
addProfileConfig.AWSProfileAccounts = awsProfileAccount
206+
addProfileConfig.AWSProfileName = awsProfile
244207

245-
if err := addProfileConfig.AddProfile(); err != nil {
208+
if err := addProfileConfig.Run(); err != nil {
246209
logger.Fatal(err)
247210
}
248211

cmd/add_profile_test.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,25 @@ output=json
6262

6363
mfaSerial := "arn:aws:iam::111111111111:mfa/test-user"
6464
addProfileConfig := AddProfileConfig{
65-
// Config
66-
Logger: suite.logger,
67-
Config: config,
68-
69-
// Profile Inputs
70-
IAMRole: "test-role",
71-
Region: "us-west-2",
72-
Partition: "aws",
73-
Output: "json",
74-
75-
// Profiles
76-
AWSProfileAccounts: []string{"test-id-new:123456789012"},
77-
AWSProfileName: "test-id",
65+
AWSProfileName: "test-id",
7866
}
67+
68+
// Config
69+
addProfileConfig.Logger = suite.logger
70+
addProfileConfig.Config = config
71+
72+
// Profile Inputs
73+
addProfileConfig.IAMUser = ""
74+
addProfileConfig.IAMRole = "test-role"
75+
addProfileConfig.Region = "us-west-2"
76+
addProfileConfig.Partition = "aws"
77+
addProfileConfig.Output = "json"
78+
79+
// Profiles
80+
addProfileConfig.AWSProfileAccounts = []string{"test-id-new:123456789012"}
81+
addProfileConfig.MFASerial = mfaSerial
82+
83+
// Add the profile
7984
err = addProfileConfig.AddProfile()
8085
suite.NoError(err)
8186

cmd/common.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"gopkg.in/ini.v1"
1515
)
1616

17+
const maxMFATokenPromptAttempts = 5
18+
1719
func promptMFAtoken(messagePrefix string, logger *log.Logger) string {
1820
var token string
1921
for attempts := maxMFATokenPromptAttempts; token == "" && attempts > 0; attempts-- {
@@ -53,9 +55,25 @@ func getMFATokenPair(logger *log.Logger) MFATokenPair {
5355
return mfaTokenPair
5456
}
5557

58+
// DefaultConfig is the standard config struct for managing subcommand input
59+
type DefaultConfig struct {
60+
Logger *log.Logger
61+
Config *vault.ConfigFile
62+
63+
IAMUser string
64+
IAMRole string
65+
Partition string
66+
Region string
67+
Output string
68+
69+
AWSProfileAccounts []string
70+
AWSProfiles []vault.ProfileSection
71+
MFASerial string
72+
}
73+
5674
// UpdateAWSProfile updates or creates a single AWS profile to the AWS config file
57-
func UpdateAWSProfile(iniFile *ini.File, profile *vault.ProfileSection, sourceProfile *string, output string, logger *log.Logger) error {
58-
logger.Printf("Adding the profile %q to the AWS config file", profile.Name)
75+
func (dc *DefaultConfig) UpdateAWSProfile(iniFile *ini.File, profile *vault.ProfileSection, sourceProfile *string) error {
76+
dc.Logger.Printf("Adding the profile %q to the AWS config file", profile.Name)
5977

6078
sectionName := fmt.Sprintf("profile %s", profile.Name)
6179

@@ -81,7 +99,7 @@ func UpdateAWSProfile(iniFile *ini.File, profile *vault.ProfileSection, sourcePr
8199
if err = section.ReflectFrom(&profile); err != nil {
82100
return fmt.Errorf("error mapping profile to ini file: %w", err)
83101
}
84-
_, err = section.NewKey("output", output)
102+
_, err = section.NewKey("output", dc.Output)
85103
if err != nil {
86104
return fmt.Errorf("unable to add output key: %w", err)
87105
}

cmd/setup.go

Lines changed: 33 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
)
2626

2727
const maxNumAccessKeys = 2
28-
const maxMFATokenPromptAttempts = 5
2928

3029
var validate *validator.Validate
3130

@@ -88,73 +87,64 @@ func SetupUserCheckConfig(v *viper.Viper) error {
8887

8988
// SetupConfig holds information for the AWS user being configured by this script
9089
type SetupConfig struct {
91-
Logger *log.Logger
92-
Config *vault.ConfigFile
90+
DefaultConfig
91+
9392
QrTempFile *os.File
9493
Keyring *keyring.Keyring
9594
NoMFA bool
9695

97-
IAMUser string
98-
IAMRole string
99-
Partition string
100-
Region string
101-
Output string
102-
103-
BaseProfileName string
104-
BaseProfile *vault.ProfileSection
105-
AWSProfileAccounts []string
106-
AWSProfiles []vault.ProfileSection
107-
MFASerial string
96+
BaseProfileName string
97+
BaseProfile *vault.ProfileSection
10898

10999
AccessKeyID string
110100
SecretAccessKey string
111101
}
112102

113-
// Setup orchestrates the tasks to create the user's MFA and rotate access
114-
// keys.
115-
func (sc *SetupConfig) Setup() {
103+
// Run orchestrates the tasks to create the user's MFA and rotate access keys.
104+
func (sc *SetupConfig) Run() error {
116105
err := sc.PromptAccessCredentials()
117106
if err != nil {
118-
sc.Logger.Fatal(err)
107+
return err
119108
}
120109

121110
err = sc.AddVaultProfile()
122111
if err != nil {
123-
sc.Logger.Fatal(err)
112+
return err
124113
}
125114

126115
if sc.NoMFA {
127116
err = sc.GetMFADevice()
128117
if err != nil {
129-
sc.Logger.Fatal(err)
118+
return err
130119
}
131120
} else {
132121
err = sc.CreateVirtualMFADevice()
133122
if err != nil {
134-
sc.Logger.Fatal(err)
123+
return err
135124
}
136125

137126
err = sc.EnableVirtualMFADevice()
138127
if err != nil {
139-
sc.Logger.Fatal(err)
128+
return err
140129
}
141130
}
142131

143132
err = sc.UpdateAWSConfigFile()
144133
if err != nil {
145-
sc.Logger.Fatal(err)
134+
return err
146135
}
147136

148137
err = sc.RemoveVaultSession()
149138
if err != nil {
150-
sc.Logger.Fatal(err)
139+
return err
151140
}
152141

153142
err = sc.RotateAccessKeys()
154143
if err != nil {
155-
sc.Logger.Fatal(err)
144+
return err
156145
}
157146

147+
return nil
158148
}
159149

160150
// PromptAccessCredentials prompts the user for their AWS access key ID and
@@ -401,40 +391,6 @@ func (sc *SetupConfig) AddVaultProfile() error {
401391
return nil
402392
}
403393

404-
// UpdateAWSProfile updates or creates a single AWS profile to the AWS config file
405-
func (sc *SetupConfig) UpdateAWSProfile(iniFile *ini.File, profile *vault.ProfileSection, sourceProfile *string) error {
406-
sc.Logger.Printf("Adding the profile %q to the AWS config file", profile.Name)
407-
sectionName := fmt.Sprintf("profile %s", profile.Name)
408-
409-
// Get or create section before updating
410-
var err error
411-
var section *ini.Section
412-
section = iniFile.Section(sectionName)
413-
if section == nil {
414-
section, err = iniFile.NewSection(sectionName)
415-
if err != nil {
416-
return fmt.Errorf("error creating section %q: %w", profile.Name, err)
417-
}
418-
}
419-
420-
// Add the source profile when provided
421-
if sourceProfile != nil {
422-
_, err = section.NewKey("source_profile", *sourceProfile)
423-
if err != nil {
424-
return fmt.Errorf("unable to add source profile: %w", err)
425-
}
426-
}
427-
428-
if err = section.ReflectFrom(&profile); err != nil {
429-
return fmt.Errorf("error mapping profile to ini file: %w", err)
430-
}
431-
_, err = section.NewKey("output", sc.Output)
432-
if err != nil {
433-
return fmt.Errorf("unable to add output key: %w", err)
434-
}
435-
return nil
436-
}
437-
438394
// UpdateAWSConfigFile adds the user's AWS profile to the AWS config file
439395
func (sc *SetupConfig) UpdateAWSConfigFile() error {
440396
sc.Logger.Printf("Updating the AWS config file: %s", sc.Config.Path)
@@ -588,25 +544,31 @@ func setupUserFunction(cmd *cobra.Command, args []string) error {
588544

589545
setupConfig := SetupConfig{
590546
// Config
591-
Logger: logger,
592-
Config: config,
593547
QrTempFile: tempfile,
594548
Keyring: keyring,
595549
NoMFA: noMFA,
596550

597-
// Profile Inputs
598-
IAMUser: iamUser,
599-
IAMRole: iamRole,
600-
Region: awsRegion,
601-
Partition: partition,
602-
Output: output,
603-
604551
// Profiles
605-
BaseProfileName: baseProfileName,
606-
AWSProfileAccounts: awsProfileAccount,
552+
BaseProfileName: baseProfileName,
607553
}
608554

609-
setupConfig.Setup()
555+
// Config
556+
setupConfig.Logger = logger
557+
setupConfig.Config = config
558+
559+
// Profile Inputs
560+
setupConfig.IAMUser = iamUser
561+
setupConfig.IAMRole = iamRole
562+
setupConfig.Region = awsRegion
563+
setupConfig.Partition = partition
564+
setupConfig.Output = output
565+
566+
// Profiles
567+
setupConfig.AWSProfileAccounts = awsProfileAccount
568+
569+
if err := setupConfig.Run(); err != nil {
570+
logger.Fatal(err)
571+
}
610572

611573
// If we got this far, we win
612574
logger.Println("Victory!")

0 commit comments

Comments
 (0)