Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli): Fix incorrect parsing of ARNs w/ nested param names #1012

Merged
merged 4 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions ecs-cli/modules/cli/local/secrets/clients/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import (
"github.com/pkg/errors"
)

// ssmSeparator is used to check if ssm parameter names are fully qualified paths
const ssmSeparator = "/"

const splitAllStrings = -1

// region represents an AWS region.
type region string

Expand Down Expand Up @@ -59,8 +64,12 @@ func (d *SSMDecrypter) DecryptSecret(arnOrName string) (string, error) {

// If the value is an ARN we need to retrieve the parameter name and update the region of the client.
paramName := arnOrName
if parsedARN, err := arnParser.Parse(arnOrName); err == nil {
paramName = parsedARN.Resource[len("parameter/"):] // Resource is formatted as parameter/{paramName}.
if arnParser.IsARN(arnOrName) {
parsedARN, err := arnParser.Parse(arnOrName)
if err != nil {
return "", errors.Wrapf(err, "failed to parse resource identifier %s due to %v", arnOrName, err)
}
paramName = parsedARN.Resource[len("parameter"):] // Resource is formatted as parameter/{paramName}.
d.SSMAPI = d.getClient(region(parsedARN.Region))
}

Expand Down
35 changes: 33 additions & 2 deletions ecs-cli/modules/cli/local/secrets/clients/clients_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestSSMDecrypter_DecryptSecret(t *testing.T) {

gomock.InOrder(
defaultClient.EXPECT().GetParameter(&ssm.GetParameterInput{
Name: aws.String("TEST_DB_PASSWORD"),
Name: aws.String("/TEST_DB_PASSWORD"),
WithDecryption: aws.Bool(true),
}).Return(&ssm.GetParameterOutput{
Parameter: &ssm.Parameter{
Expand Down Expand Up @@ -74,7 +74,7 @@ func TestSSMDecrypter_DecryptSecret(t *testing.T) {

gomock.InOrder(
pdxClient.EXPECT().GetParameter(&ssm.GetParameterInput{
Name: aws.String("TEST_DB_PASSWORD"),
Name: aws.String("/TEST_DB_PASSWORD"),
WithDecryption: aws.Bool(true),
}).Return(&ssm.GetParameterOutput{
Parameter: &ssm.Parameter{
Expand All @@ -91,6 +91,37 @@ func TestSSMDecrypter_DecryptSecret(t *testing.T) {
}
},
},
"with ARN and forward slashes": {
input: "arn:aws:ssm:us-west-2:11111111111:parameter/TEST/DB/PASSWORD",
wantedSecret: "ponies",
setupDecrypter: func(ctrl *gomock.Controller) *SSMDecrypter {
iadClient := mock_ssmiface.NewMockSSMAPI(ctrl)
pdxClient := mock_ssmiface.NewMockSSMAPI(ctrl)

m := make(map[region]ssmiface.SSMAPI)
m["default"] = iadClient
m["us-east-1"] = iadClient
m["us-west-2"] = pdxClient

gomock.InOrder(
pdxClient.EXPECT().GetParameter(&ssm.GetParameterInput{
Name: aws.String("/TEST/DB/PASSWORD"),
WithDecryption: aws.Bool(true),
}).Return(&ssm.GetParameterOutput{
Parameter: &ssm.Parameter{
Value: aws.String("ponies"),
},
}, nil),

iadClient.EXPECT().GetParameter(gomock.Any()).Times(0), // Should not have called IAD
)

return &SSMDecrypter{
SSMAPI: iadClient,
clients: m,
}
},
},
"without ARN": {
input: "TEST_DB_PASSWORD",
wantedSecret: "hello",
Expand Down
4 changes: 4 additions & 0 deletions ecs-cli/modules/cli/local/secrets/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func TestName(t *testing.T) {
input: NewContainerSecret("mongodb", "DB_PASSWORD", "arn:aws:secretsmanager:us-east-1:11111111111:secret:alpha/efe/local"),
wanted: "mongodb_DB_PASSWORD",
},
"complex": {
input: NewContainerSecret("mongodb", "DB_PASSWORD", "arn:aws:secretsmanager:us-east-1:11111111111:secret:alpha/efe/local/mongo/aws"),
wanted: "mongodb_DB_PASSWORD",
},
}

for name, tc := range testCases {
Expand Down