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

Adds the ability to use bypath to aws_secrets lookup #192

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix up some linting format
  • Loading branch information
dlundgren committed Dec 19, 2020
commit 4069fce542fbea0b8e06e6e99236e89ea1a8f374
43 changes: 25 additions & 18 deletions plugins/lookup/aws_secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,25 @@ def _boto3_conn(region, credentials):
class LookupModule(LookupBase):
def run(self, terms, variables=None, boto_profile=None, aws_profile=None,
aws_secret_key=None, aws_access_key=None, aws_security_token=None, region=None,
bypath=False, join=False,version_stage=None, version_id=None, on_missing=None,
bypath=False, join=False, version_stage=None, version_id=None, on_missing=None,
on_denied=None):
'''
:arg terms: a list of lookups to run.
e.g. ['parameter_name', 'parameter_name_too' ]
:kwarg variables: ansible variables active at the time of the lookup
:kwarg aws_secret_key: identity of the AWS key to use
:kwarg aws_access_key: AWS secret key (matching identity)
:kwarg aws_security_token: AWS session key if using STS
:kwarg decrypt: Set to True to get decrypted parameters
:kwarg region: AWS region in which to do the lookup
:kwarg bypath: Set to True to do a lookup of variables under a path
:kwarg recursive: Set to True to recurse below the path (requires bypath=True)
:returns: A list of parameter values or a list of dictionaries if bypath=True.
'''

:arg terms: a list of lookups to run.
e.g. ['parameter_name', 'parameter_name_too' ]
:kwarg variables: ansible variables active at the time of the lookup
:kwarg aws_secret_key: identity of the AWS key to use
:kwarg aws_access_key: AWS secret key (matching identity)
:kwarg aws_security_token: AWS session key if using STS
:kwarg decrypt: Set to True to get decrypted parameters
:kwarg region: AWS region in which to do the lookup
:kwarg bypath: Set to True to do a lookup of variables under a path
:kwarg join: Join two or more entries to form an extended secret
:kwarg version_stage: Stage of the secret version
:kwarg version_id: Version of the secret(s)
:kwarg on_missing: Action to take if the secret is missing
:kwarg on_denied: Action to take if access to the secret is denied
:returns: A list of parameter values or a list of dictionaries if bypath=True.
'''
if not HAS_BOTO3:
raise AnsibleError('botocore and boto3 are required for aws_ssm lookup.')

Expand Down Expand Up @@ -177,18 +180,22 @@ def run(self, terms, variables=None, boto_profile=None, aws_profile=None,
secrets = {}
for term in terms:
try:
response = client.list_secrets(Filters=[{'Key': 'name','Values': [term]}])
response = client.list_secrets(Filters=[{'Key': 'name', 'Values': [term]}])

if 'SecretList' in response:
for secret in response['SecretList']:
secrets.update({secret['Name'] : self.get_secret_value(secret['Name'], client)})
secrets.update({secret['Name']: self.get_secret_value(secret['Name'], client,
on_missing=on_missing,
on_denied=on_denied)})
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
raise AnsibleError("Failed to retrieve secret: %s" % to_native(e))
secrets = [secrets]
else:
secrets = []
for term in terms:
value = self.get_secret_value(term, client, version_stage=version_stage, version_id=version_id)
value = self.get_secret_value(term, client,
version_stage=version_stage, version_id=version_id,
on_missing=on_missing, on_denied=on_denied)
if value:
secrets.append(value)
if join:
Expand All @@ -198,7 +205,7 @@ def run(self, terms, variables=None, boto_profile=None, aws_profile=None,

return secrets

def get_secret_value(self, term, client, version_stage=None, version_id=None):
def get_secret_value(self, term, client, version_stage=None, version_id=None, on_missing=None, on_denied=None):
params = {}
params['SecretId'] = term
if version_id:
Expand Down
17 changes: 10 additions & 7 deletions tests/unit/plugins/lookup/test_aws_secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)

__metaclass__ = type

import pytest
Expand Down Expand Up @@ -45,6 +46,7 @@ def dummy_credentials():
dummy_credentials['region'] = 'eu-west-1'
return dummy_credentials


simple_variable_success_response = {
'Name': 'secret',
'VersionId': 'cafe8168-e6ce-4e59-8830-5b143faf6c52',
Expand All @@ -64,16 +66,18 @@ def dummy_credentials():
}
}


def test_lookup_variable(mocker, dummy_credentials):
dateutil_tz = pytest.importorskip("dateutil.tz")
lookup = lookup_loader.get('amazon.aws.aws_secret')
boto3_double = mocker.MagicMock()
boto3_double.Session.return_value.client.return_value.get_secret_value.return_value = copy(simple_variable_success_response)
boto3_double.Session.return_value.client.return_value.get_secret_value.return_value = copy(
simple_variable_success_response)
boto3_client_double = boto3_double.Session.return_value.client

mocker.patch.object(boto3, 'session', boto3_double)
retval = lookup.run(["simple_variable"], None, **dummy_credentials)
assert(retval[0] == '{"secret":"simplesecret"}')
assert (retval[0] == '{"secret":"simplesecret"}')
boto3_client_double.assert_called_with('secretsmanager', 'eu-west-1', aws_access_key_id='notakey',
aws_secret_access_key="notasecret", aws_session_token=None)

Expand Down Expand Up @@ -132,7 +136,7 @@ def test_path_lookup_variable(mocker, dummy_credentials):
path_list_secrets_success_response = {
'SecretList': [
{
'Name' : '/testpath/too',
'Name': '/testpath/too',
},
{
'Name': '/testpath/won',
Expand Down Expand Up @@ -173,9 +177,8 @@ def test_path_lookup_variable(mocker, dummy_credentials):
dummy_credentials["boto_profile"] = 'test'
dummy_credentials["aws_profile"] = 'test'
retval = lookup.run(["/testpath"], {}, **dummy_credentials)
print(retval[0])
assert(retval[0]["/testpath/won"] == "simple_value_won")
assert(retval[0]["/testpath/too"] == "simple_value_too")
assert (retval[0]["/testpath/won"] == "simple_value_won")
assert (retval[0]["/testpath/too"] == "simple_value_too")
boto3_client_double.assert_called_with('secretsmanager', 'eu-west-1', aws_access_key_id='notakey',
aws_secret_access_key="notasecret", aws_session_token=None)
list_secrets_fn.assert_called_with(Filters=[{'Key': 'name','Values': ['/testpath']}])
list_secrets_fn.assert_called_with(Filters=[{'Key': 'name', 'Values': ['/testpath']}])