Add prefix option to AWS SSM Parameter Store secret store component (#2043)
Signed-off-by: Oliver Streek <ostreek@rosske.co.uk> Signed-off-by: Oliver Streek <ostreek@rosske.co.uk>
This commit is contained in:
parent
19341e5a0f
commit
b18e73d028
|
|
@ -41,10 +41,12 @@ type parameterStoreMetaData struct {
|
|||
AccessKey string `json:"accessKey"`
|
||||
SecretKey string `json:"secretKey"`
|
||||
SessionToken string `json:"sessionToken"`
|
||||
Prefix string `json:"prefix"`
|
||||
}
|
||||
|
||||
type ssmSecretStore struct {
|
||||
client ssmiface.SSMAPI
|
||||
prefix string
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +62,7 @@ func (s *ssmSecretStore) Init(metadata secretstores.Metadata) error {
|
|||
return err
|
||||
}
|
||||
s.client = client
|
||||
s.prefix = meta.Prefix
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -75,7 +78,7 @@ func (s *ssmSecretStore) GetSecret(req secretstores.GetSecretRequest) (secretsto
|
|||
}
|
||||
|
||||
output, err := s.client.GetParameter(&ssm.GetParameterInput{
|
||||
Name: aws.String(name),
|
||||
Name: aws.String(s.prefix + name),
|
||||
WithDecryption: aws.Bool(true),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -86,7 +89,8 @@ func (s *ssmSecretStore) GetSecret(req secretstores.GetSecretRequest) (secretsto
|
|||
Data: map[string]string{},
|
||||
}
|
||||
if output.Parameter.Name != nil && output.Parameter.Value != nil {
|
||||
resp.Data[*output.Parameter.Name] = *output.Parameter.Value
|
||||
secretName := (*output.Parameter.Name)[len(s.prefix):]
|
||||
resp.Data[secretName] = *output.Parameter.Value
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
|
|
@ -101,10 +105,22 @@ func (s *ssmSecretStore) BulkGetSecret(req secretstores.BulkGetSecretRequest) (s
|
|||
search := true
|
||||
var nextToken *string = nil
|
||||
|
||||
var filters []*ssm.ParameterStringFilter
|
||||
if s.prefix != "" {
|
||||
filters = []*ssm.ParameterStringFilter{
|
||||
{
|
||||
Key: aws.String(ssm.ParametersFilterKeyName),
|
||||
Option: aws.String("BeginsWith"),
|
||||
Values: aws.StringSlice([]string{s.prefix}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for search {
|
||||
output, err := s.client.DescribeParameters(&ssm.DescribeParametersInput{
|
||||
MaxResults: nil,
|
||||
NextToken: nextToken,
|
||||
MaxResults: nil,
|
||||
NextToken: nextToken,
|
||||
ParameterFilters: filters,
|
||||
})
|
||||
if err != nil {
|
||||
return secretstores.BulkGetSecretResponse{Data: nil}, fmt.Errorf("couldn't list secrets: %s", err)
|
||||
|
|
@ -120,7 +136,8 @@ func (s *ssmSecretStore) BulkGetSecret(req secretstores.BulkGetSecretRequest) (s
|
|||
}
|
||||
|
||||
if entry.Name != nil && params.Parameter.Value != nil {
|
||||
resp.Data[*entry.Name] = map[string]string{*entry.Name: *params.Parameter.Value}
|
||||
secretName := (*entry.Name)[len(s.prefix):]
|
||||
resp.Data[secretName] = map[string]string{secretName: *params.Parameter.Value}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,33 @@ func TestGetSecret(t *testing.T) {
|
|||
assert.Nil(t, e)
|
||||
assert.Equal(t, secretValue, output.Data[req.Name])
|
||||
})
|
||||
|
||||
t.Run("with prefix", func(t *testing.T) {
|
||||
s := ssmSecretStore{
|
||||
client: &mockedSSM{
|
||||
GetParameterFn: func(input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
|
||||
assert.Equal(t, "/prefix/aws/dev/secret", *input.Name)
|
||||
secret := secretValue
|
||||
|
||||
return &ssm.GetParameterOutput{
|
||||
Parameter: &ssm.Parameter{
|
||||
Name: input.Name,
|
||||
Value: &secret,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
prefix: "/prefix",
|
||||
}
|
||||
|
||||
req := secretstores.GetSecretRequest{
|
||||
Name: "/aws/dev/secret",
|
||||
Metadata: map[string]string{},
|
||||
}
|
||||
output, e := s.GetSecret(req)
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, "secret", output.Data[req.Name])
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("unsuccessfully retrieve secret", func(t *testing.T) {
|
||||
|
|
@ -172,6 +199,42 @@ func TestGetBulkSecrets(t *testing.T) {
|
|||
assert.Contains(t, output.Data, "/aws/dev/secret2")
|
||||
})
|
||||
|
||||
t.Run("successfully retrieve bulk secrets with prefix", func(t *testing.T) {
|
||||
s := ssmSecretStore{
|
||||
client: &mockedSSM{
|
||||
DescribeParametersFn: func(*ssm.DescribeParametersInput) (*ssm.DescribeParametersOutput, error) {
|
||||
return &ssm.DescribeParametersOutput{NextToken: nil, Parameters: []*ssm.ParameterMetadata{
|
||||
{
|
||||
Name: aws.String("/prefix/aws/dev/secret1"),
|
||||
},
|
||||
{
|
||||
Name: aws.String("/prefix/aws/dev/secret2"),
|
||||
},
|
||||
}}, nil
|
||||
},
|
||||
GetParameterFn: func(input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
|
||||
secret := fmt.Sprintf("%s-%s", *input.Name, secretValue)
|
||||
|
||||
return &ssm.GetParameterOutput{
|
||||
Parameter: &ssm.Parameter{
|
||||
Name: input.Name,
|
||||
Value: &secret,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
prefix: "/prefix",
|
||||
}
|
||||
|
||||
req := secretstores.BulkGetSecretRequest{
|
||||
Metadata: map[string]string{},
|
||||
}
|
||||
output, e := s.BulkGetSecret(req)
|
||||
assert.Nil(t, e)
|
||||
assert.Equal(t, "map[/aws/dev/secret1:/prefix/aws/dev/secret1-secret]", fmt.Sprint(output.Data["/aws/dev/secret1"]))
|
||||
assert.Equal(t, "map[/aws/dev/secret2:/prefix/aws/dev/secret2-secret]", fmt.Sprint(output.Data["/aws/dev/secret2"]))
|
||||
})
|
||||
|
||||
t.Run("unsuccessfully retrieve bulk secrets on get parameter", func(t *testing.T) {
|
||||
s := ssmSecretStore{
|
||||
client: &mockedSSM{
|
||||
|
|
|
|||
Loading…
Reference in New Issue