Skip to content

Commit c5300d2

Browse files
committed
Add tests for registry-creds up
1 parent 9667b09 commit c5300d2

File tree

4 files changed

+328
-77
lines changed

4 files changed

+328
-77
lines changed

ecs-cli/modules/cli/regcreds/regcreds_app.go

Lines changed: 50 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ import (
2727
"github.com/urfave/cli"
2828
)
2929

30+
const (
31+
// EcsCliResourcePrefix is prepended to the names of resources created through the ecs-cli
32+
// TODO: move to more generic package for use in other parts of the ecs-cli
33+
EcsCliResourcePrefix = "amazon-ecs-cli-setup-"
34+
)
35+
3036
// CredsOutputEntry contains the credential ARN and associated container names
3137
// TODO: use & move to output_reader once implemented?
3238
type CredsOutputEntry struct {
@@ -53,60 +59,49 @@ func Up(c *cli.Context) {
5359
}
5460

5561
commandConfig := getNewCommandConfig(c)
62+
updateAllowed := c.Bool(flags.UpdateExistingSecretsFlag)
63+
64+
smClient := secretsClient.NewSecretsManagerClient(commandConfig)
5665

57-
_, err = getOrCreateRegistryCredentials(credsInput.RegistryCredentials, commandConfig, c)
66+
_, err = getOrCreateRegistryCredentials(credsInput.RegistryCredentials, smClient, updateAllowed)
5867
if err != nil {
5968
log.Fatal("Error executing 'up': ", err)
6069
}
6170

62-
//TODO: create role, produce output
71+
//TODO: use getOrCreate...() result to create role, produce output
6372
}
6473

65-
func getOrCreateRegistryCredentials(entryMap readers.RegistryCreds, cmdConfig *config.CommandConfig, c *cli.Context) (*map[string]CredsOutputEntry, error) {
74+
func getOrCreateRegistryCredentials(entryMap readers.RegistryCreds, smClient secretsClient.SMClient, updateAllowed bool) (map[string]CredsOutputEntry, error) {
6675
registryResults := make(map[string]CredsOutputEntry)
67-
updateAllowed := c.Bool(flags.UpdateExistingSecretsFlag)
68-
69-
smClient := secretsClient.NewSecretsManagerClient(cmdConfig)
7076

7177
for registryName, credentialEntry := range entryMap {
72-
hasCredPair := hasCredPair(credentialEntry)
73-
hasSecretARN := false
74-
if credentialEntry.SecretManagerARN != "" {
75-
hasSecretARN = true
76-
}
77-
7878
log.Infof("Processing credentials for registry %s...", registryName)
7979

80-
if hasCredPair && hasSecretARN {
81-
arn, err := updateOrWarnForExistingSecret(credentialEntry, updateAllowed, smClient)
80+
arn := credentialEntry.SecretManagerARN
81+
if arn == "" {
82+
newSecretArn, err := findOrCreateRegistrySecret(registryName, credentialEntry, smClient)
8283
if err != nil {
8384
return nil, err
8485
}
85-
registryResults[registryName] = buildOutputEntry(arn, credentialEntry.ContainerNames)
86-
87-
} else if hasSecretARN {
88-
registryResults[registryName] = buildOutputEntry(credentialEntry.SecretManagerARN, credentialEntry.ContainerNames)
89-
log.Infof("Using existing secret %s.", registryName)
90-
91-
} else {
92-
arn, err := createNewRegistrySecret(registryName, credentialEntry, smClient)
93-
if err != nil {
86+
arn = newSecretArn
87+
} else if credentialEntry.HasCredPair() {
88+
if err := updateOrWarnForExistingSecret(credentialEntry, updateAllowed, smClient); err != nil {
9489
return nil, err
9590
}
96-
registryResults[registryName] = buildOutputEntry(arn, credentialEntry.ContainerNames)
91+
} else {
92+
log.Infof("Using existing secret %s.", arn)
9793
}
94+
registryResults[registryName] = buildOutputEntry(arn, credentialEntry.ContainerNames)
9895
}
9996

100-
log.Infof("\n up results: %v", registryResults)
101-
102-
return &registryResults, nil
97+
return registryResults, nil
10398
}
10499

105-
func createNewRegistrySecret(registryName string, credEntry readers.RegistryCredEntry, smClient secretsClient.SMClient) (string, error) {
100+
func findOrCreateRegistrySecret(registryName string, credEntry readers.RegistryCredEntry, smClient secretsClient.SMClient) (string, error) {
106101

107102
secretName := generateSecretName(registryName)
108103

109-
existingSecret, _ := smClient.DescribeSecret(secretName)
104+
existingSecret, _ := smClient.DescribeSecret(*secretName)
110105
if existingSecret != nil {
111106
log.Infof("Existing credential secret found, using %s", *existingSecret.ARN)
112107

@@ -116,9 +111,9 @@ func createNewRegistrySecret(registryName string, credEntry readers.RegistryCred
116111
secretString := generateSecretString(credEntry.Username, credEntry.Password)
117112

118113
createSecretRequest := secretsmanager.CreateSecretInput{
119-
Name: aws.String(secretName),
120-
SecretString: aws.String(secretString),
121-
Description: aws.String(fmt.Sprintf("Created with the ECS CLI for use with registry %s", registryName)),
114+
Name: secretName,
115+
SecretString: secretString,
116+
Description: generateSecretDescription(registryName),
122117
}
123118
if credEntry.KmsKeyID != "" {
124119
createSecretRequest.SetKmsKeyId(credEntry.KmsKeyID)
@@ -133,28 +128,27 @@ func createNewRegistrySecret(registryName string, credEntry readers.RegistryCred
133128
return *output.ARN, nil
134129
}
135130

136-
func updateOrWarnForExistingSecret(credEntry readers.RegistryCredEntry, updateAllowed bool, smClient secretsClient.SMClient) (string, error) {
131+
func updateOrWarnForExistingSecret(credEntry readers.RegistryCredEntry, updateAllowed bool, smClient secretsClient.SMClient) error {
137132
secretArn := credEntry.SecretManagerARN
138133

139134
if updateAllowed {
140135
updatedSecretString := generateSecretString(credEntry.Username, credEntry.Password)
141136
putSecretValueRequest := secretsmanager.PutSecretValueInput{
142137
SecretId: aws.String(secretArn),
143-
SecretString: aws.String(updatedSecretString),
138+
SecretString: updatedSecretString,
144139
}
145140

146141
_, err := smClient.PutSecretValue(putSecretValueRequest)
147142
if err != nil {
148-
return "", err
143+
return err
149144
}
150145

151146
log.Infof("Updated existing secret %s with new value", secretArn)
152147

153148
} else {
154149
log.Warnf("'username' and 'password' found but ignored for existing secret %s. To update existing secrets with new values, use '--update-existing-secrets' flag.", secretArn)
155150
}
156-
157-
return secretArn, nil
151+
return nil
158152
}
159153

160154
func validateCredsInput(input readers.ECSRegCredsInput) error {
@@ -166,28 +160,24 @@ func validateCredsInput(input readers.ECSRegCredsInput) error {
166160
return errors.New("provided credentials must contain at least one registry")
167161
}
168162

163+
namedContainers := make(map[string]bool)
164+
169165
for registryName, credentialEntry := range inputRegCreds {
170-
if !hasRequiredFields(credentialEntry) {
166+
if !credentialEntry.HasRequiredFields() {
171167
return fmt.Errorf("missing required field(s) for registry %s; registry credentials should contain existing secret ARN or username + password", registryName)
172168
}
169+
if len(credentialEntry.ContainerNames) > 0 {
170+
for _, container := range credentialEntry.ContainerNames {
171+
if namedContainers[container] {
172+
return fmt.Errorf("container '%s' appears in more than one registry; container names must be unique across a set of registry credentials", container)
173+
}
174+
namedContainers[container] = true
175+
}
176+
}
173177
}
174178
return nil
175179
}
176180

177-
func hasRequiredFields(entry readers.RegistryCredEntry) bool {
178-
if (entry.SecretManagerARN != "") || hasCredPair(entry) {
179-
return true
180-
}
181-
return false
182-
}
183-
184-
func hasCredPair(entry readers.RegistryCredEntry) bool {
185-
if entry.Username != "" && entry.Password != "" {
186-
return true
187-
}
188-
return false
189-
}
190-
191181
func getNewCommandConfig(c *cli.Context) *config.CommandConfig {
192182
rdwr, err := config.NewReadWriter()
193183
if err != nil {
@@ -201,12 +191,16 @@ func getNewCommandConfig(c *cli.Context) *config.CommandConfig {
201191
return commandConfig
202192
}
203193

204-
func generateSecretName(regName string) string {
205-
return "amazon-ecs-cli-setup-" + regName
194+
func generateSecretName(regName string) *string {
195+
return aws.String(EcsCliResourcePrefix + regName)
196+
}
197+
198+
func generateSecretString(username, password string) *string {
199+
return aws.String(`{"username":"` + username + `"},{"password":"` + password + `"}`)
206200
}
207201

208-
func generateSecretString(username, password string) string {
209-
return `{"username":"` + username + `"},{"password":"` + password + `"}`
202+
func generateSecretDescription(regName string) *string {
203+
return aws.String(fmt.Sprintf("Created with the ECS CLI for use with registry %s", regName))
210204
}
211205

212206
func buildOutputEntry(arn string, containers []string) CredsOutputEntry {

0 commit comments

Comments
 (0)