From 7b9dffbefb23bc398a8ba8e0c4c2ce6eef297fe8 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Tue, 4 Aug 2020 09:45:16 +0000 Subject: [PATCH 01/16] aws_secrets.py: add on_missing and on_denied option --- plugins/lookup/aws_secret.py | 42 +++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 8de2d8103b5..f39df9d36d8 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -37,6 +37,24 @@ - This is useful for overcoming the 4096 character limit imposed by AWS. type: boolean default: false + on_missing: + description: + - action to take if secret is missing + - Error will raise a fatal error + - Skip will just ignore the term + - Warn will skip over it but issue a warning + default: error + type: string + choices: ['error', 'skip', 'warn'] + on_denied: + description: + - action to take if access to secret is denied + - Error will raise a fatal error + - Skip will just ignore the term + - Warn will skip over it but issue a warning + default: error + type: string + choices: ['error', 'skip', 'warn'] ''' EXAMPLES = r""" @@ -51,6 +69,12 @@ password: "{{ lookup('aws_secret', 'DbSecret') }}" tags: Environment: staging + +- name: skip if secret does not exist + debug: msg="{{ lookup('aws_secret', 'secret-not-exist', on_missing='skip')}}" + + - name: skip if access to the secret is denied + debug: msg="{{ lookup('aws_secret', 'secret-denied', on_denied='skip')}}" """ RETURN = r""" @@ -60,6 +84,7 @@ """ from ansible.errors import AnsibleError +from ansible.module_utils.six import string_types try: import boto3 @@ -108,6 +133,14 @@ def _get_credentials(self): def run(self, terms, variables, **kwargs): + missing = kwargs.get('on_missing', 'error').lower() + if not isinstance(missing, string_types) or missing not in ['error', 'warn', 'skip']: + raise AnsibleError('"on_missing" must be a string and one of "error", "warn" or "skip", not %s' % missing) + + denied = kwargs.get('on_denied', 'error').lower() + if not isinstance(denied, string_types) or denied not in ['error', 'warn', 'skip']: + raise AnsibleError('"on_denied" must be a string and one of "error", "warn" or "skip", not %s' % denied) + self.set_options(var_options=variables, direct=kwargs) boto_credentials = self._get_credentials() @@ -130,7 +163,14 @@ def run(self, terms, variables, **kwargs): if 'SecretString' in response: secrets.append(response['SecretString']) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - raise AnsibleError("Failed to retrieve secret: %s" % to_native(e)) + if e.response['Error']['Code'] == 'ResourceNotFoundException' and missing in ['warn', 'skip']: + if missing == 'warn': + self._display.warning('Skipping, did not find secret %s' % term) + elif e.response['Error']['Code'] == 'AccessDeniedException' and denied in ['warn', 'skip']: + if denied == 'warn': + self._display.warning('Skipping, access denied for secret %s' % term) + else: + raise AnsibleError("Failed to retrieve secret: %s" % to_native(e)) if kwargs.get('join'): joined_secret = [] From fe41b31fa3ecffaa2e1d8bc5fd3b19aee03607f6 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Tue, 4 Aug 2020 10:14:47 +0000 Subject: [PATCH 02/16] - add changelog fragment --- .../122-aws_secret-add-on_missing-and-on_denied-option.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml diff --git a/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml b/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml new file mode 100644 index 00000000000..686e6fd7245 --- /dev/null +++ b/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml @@ -0,0 +1,2 @@ +minor_changes: + - aws_secret - add "on_missing" and "on_denied" option From 57905b5d4da84613b9047688d7a9d46d4970ac8f Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Tue, 4 Aug 2020 11:01:49 +0000 Subject: [PATCH 03/16] - fix syntax error in example section --- plugins/lookup/aws_secret.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index f39df9d36d8..e2f19fc9bd4 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -70,7 +70,7 @@ tags: Environment: staging -- name: skip if secret does not exist + - name: skip if secret does not exist debug: msg="{{ lookup('aws_secret', 'secret-not-exist', on_missing='skip')}}" - name: skip if access to the secret is denied From 02eecb30bbd235b0c213f1f27383b9dedc642d59 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Wed, 18 Nov 2020 10:34:06 +0000 Subject: [PATCH 04/16] aws_secrets.py: add unit tests for on_missing and on_denied option --- tests/unit/plugins/lookup/test_aws_secret.py | 57 ++++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/tests/unit/plugins/lookup/test_aws_secret.py b/tests/unit/plugins/lookup/test_aws_secret.py index aa5b02d5520..fcbda4ec115 100644 --- a/tests/unit/plugins/lookup/test_aws_secret.py +++ b/tests/unit/plugins/lookup/test_aws_secret.py @@ -21,6 +21,9 @@ import pytest import datetime +import sys +from cStringIO import StringIO +from copy import copy from ansible.errors import AnsibleError @@ -77,14 +80,58 @@ def test_lookup_variable(mocker, dummy_credentials): aws_secret_access_key="notasecret", aws_session_token=None) -error_response = {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Fake Testing Error'}} +error_response_missing = {'Error': {'Code': 'ResourceNotFoundException', 'Message': 'Fake Not Found Error'}} +error_response_denied = {'Error': {'Code': 'AccessDeniedException', 'Message': 'Fake Denied Error'}} operation_name = 'FakeOperation' +def test_on_missing_option(mocker, dummy_credentials): + boto3_double = mocker.MagicMock() + boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response_missing, operation_name) + + with pytest.raises(AnsibleError, match="ResourceNotFoundException"): + mocker.patch.object(boto3, 'session', boto3_double) + lookup_loader.get('amazon.aws.aws_secret').run(["missing_secret"], None, **dummy_credentials) + + mocker.patch.object(boto3, 'session', boto3_double) + args = copy(dummy_credentials) + args["on_missing"] = 'skip' + retval = lookup_loader.get('amazon.aws.aws_secret').run(["missing_secret"], None, **args) + assert(retval == []) + + mocker.patch.object(boto3, 'session', boto3_double) + args = copy(dummy_credentials) + args["on_missing"] = 'warn' + old_stderr = sys.stderr + redirected_error = sys.stderr = StringIO() + retval = lookup_loader.get('amazon.aws.aws_secret').run(["missing_secret"], None, **args) + error_msg = redirected_error.getvalue() + sys.stderr = old_stderr + assert(retval == []) + assert(error_msg.find("[WARNING]") >= 0) -def test_warn_denied_variable(mocker, dummy_credentials): +def test_on_denied_option(mocker, dummy_credentials): boto3_double = mocker.MagicMock() - boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response, operation_name) + boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response_denied, operation_name) - with pytest.raises(AnsibleError): + with pytest.raises(AnsibleError, match="AccessDeniedException"): mocker.patch.object(boto3, 'session', boto3_double) - lookup_loader.get('amazon.aws.aws_secret').run(["denied_variable"], None, **dummy_credentials) + lookup_loader.get('amazon.aws.aws_secret').run(["denied_secret"], None, **dummy_credentials) + + mocker.patch.object(boto3, 'session', boto3_double) + args = copy(dummy_credentials) + args["on_denied"] = 'skip' + retval = lookup_loader.get('amazon.aws.aws_secret').run(["denied_secret"], None, **args) + assert(retval == []) + + mocker.patch.object(boto3, 'session', boto3_double) + args = copy(dummy_credentials) + args["on_denied"] = 'warn' + old_stderr = sys.stderr + redirected_error = sys.stderr = StringIO() + retval = lookup_loader.get('amazon.aws.aws_secret').run(["denied_secret"], None, **args) + error_msg = redirected_error.getvalue() + sys.stderr = old_stderr + assert(retval == []) + assert(error_msg.find("[WARNING]") >= 0) + + From 64dc36010364b5c65f8e950ba419023cc64699e8 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Wed, 18 Nov 2020 14:48:34 +0000 Subject: [PATCH 05/16] - remove trailing newlines and remove warning string check --- tests/unit/plugins/lookup/test_aws_secret.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tests/unit/plugins/lookup/test_aws_secret.py b/tests/unit/plugins/lookup/test_aws_secret.py index fcbda4ec115..3516b3fa105 100644 --- a/tests/unit/plugins/lookup/test_aws_secret.py +++ b/tests/unit/plugins/lookup/test_aws_secret.py @@ -22,11 +22,9 @@ import pytest import datetime import sys -from cStringIO import StringIO from copy import copy from ansible.errors import AnsibleError - from ansible.plugins.loader import lookup_loader try: @@ -101,13 +99,8 @@ def test_on_missing_option(mocker, dummy_credentials): mocker.patch.object(boto3, 'session', boto3_double) args = copy(dummy_credentials) args["on_missing"] = 'warn' - old_stderr = sys.stderr - redirected_error = sys.stderr = StringIO() retval = lookup_loader.get('amazon.aws.aws_secret').run(["missing_secret"], None, **args) - error_msg = redirected_error.getvalue() - sys.stderr = old_stderr assert(retval == []) - assert(error_msg.find("[WARNING]") >= 0) def test_on_denied_option(mocker, dummy_credentials): boto3_double = mocker.MagicMock() @@ -126,12 +119,5 @@ def test_on_denied_option(mocker, dummy_credentials): mocker.patch.object(boto3, 'session', boto3_double) args = copy(dummy_credentials) args["on_denied"] = 'warn' - old_stderr = sys.stderr - redirected_error = sys.stderr = StringIO() retval = lookup_loader.get('amazon.aws.aws_secret').run(["denied_secret"], None, **args) - error_msg = redirected_error.getvalue() - sys.stderr = old_stderr assert(retval == []) - assert(error_msg.find("[WARNING]") >= 0) - - From 0774560f05b1faa4dc8541ddcebd1807054b4257 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Wed, 18 Nov 2020 15:40:14 +0000 Subject: [PATCH 06/16] - fix 2 pep8 issues --- tests/unit/plugins/lookup/test_aws_secret.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/plugins/lookup/test_aws_secret.py b/tests/unit/plugins/lookup/test_aws_secret.py index 3516b3fa105..07f6ac22d2d 100644 --- a/tests/unit/plugins/lookup/test_aws_secret.py +++ b/tests/unit/plugins/lookup/test_aws_secret.py @@ -82,6 +82,7 @@ def test_lookup_variable(mocker, dummy_credentials): error_response_denied = {'Error': {'Code': 'AccessDeniedException', 'Message': 'Fake Denied Error'}} operation_name = 'FakeOperation' + def test_on_missing_option(mocker, dummy_credentials): boto3_double = mocker.MagicMock() boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response_missing, operation_name) @@ -102,6 +103,7 @@ def test_on_missing_option(mocker, dummy_credentials): retval = lookup_loader.get('amazon.aws.aws_secret').run(["missing_secret"], None, **args) assert(retval == []) + def test_on_denied_option(mocker, dummy_credentials): boto3_double = mocker.MagicMock() boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response_denied, operation_name) From e54ec46a7a1513a363bfdd055f6f462d26f1f650 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:06:48 +0100 Subject: [PATCH 07/16] Update plugins/lookup/aws_secret.py adjust comment Co-authored-by: Mark Chappell --- plugins/lookup/aws_secret.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index e2f19fc9bd4..1876759a997 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -39,7 +39,7 @@ default: false on_missing: description: - - action to take if secret is missing + - Action to take if the secret is missing. - Error will raise a fatal error - Skip will just ignore the term - Warn will skip over it but issue a warning From 1c5d7709ee78d5f5dab88a8668c819b2b2b32f60 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:07:58 +0100 Subject: [PATCH 08/16] Update plugins/lookup/aws_secret.py adjust comment Co-authored-by: Mark Chappell --- plugins/lookup/aws_secret.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 1876759a997..f189bace71c 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -40,7 +40,7 @@ on_missing: description: - Action to take if the secret is missing. - - Error will raise a fatal error + - C(error) will raise a fatal error when the secret is missing. - Skip will just ignore the term - Warn will skip over it but issue a warning default: error From 77b72d4312a7cf1370266cef39211d0a27520fd9 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:08:20 +0100 Subject: [PATCH 09/16] Update plugins/lookup/aws_secret.py adjust comment Co-authored-by: Mark Chappell --- plugins/lookup/aws_secret.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index f189bace71c..7d63a2bc1d9 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -41,7 +41,7 @@ description: - Action to take if the secret is missing. - C(error) will raise a fatal error when the secret is missing. - - Skip will just ignore the term + - C(skip) will silently ignore the missing secret. - Warn will skip over it but issue a warning default: error type: string From 91f78cae294c4e857e35287558fc098f449dcf89 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:08:34 +0100 Subject: [PATCH 10/16] Update plugins/lookup/aws_secret.py adjust comment Co-authored-by: Mark Chappell --- plugins/lookup/aws_secret.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 7d63a2bc1d9..12f9bdc5daa 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -42,7 +42,7 @@ - Action to take if the secret is missing. - C(error) will raise a fatal error when the secret is missing. - C(skip) will silently ignore the missing secret. - - Warn will skip over it but issue a warning + - C(warn) will skip over the missing secret but issue a warning. default: error type: string choices: ['error', 'skip', 'warn'] From e08511c3fd293bf380547d9c5c2f2a90176b2658 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:10:19 +0100 Subject: [PATCH 11/16] Update plugins/lookup/aws_secret.py adjust example Co-authored-by: Mark Chappell --- plugins/lookup/aws_secret.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 12f9bdc5daa..1aeba2d5a2f 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -73,8 +73,8 @@ - name: skip if secret does not exist debug: msg="{{ lookup('aws_secret', 'secret-not-exist', on_missing='skip')}}" - - name: skip if access to the secret is denied - debug: msg="{{ lookup('aws_secret', 'secret-denied', on_denied='skip')}}" + - name: warn if access to the secret is denied + debug: msg="{{ lookup('aws_secret', 'secret-denied', on_denied='warn')}}" """ RETURN = r""" From a5a48d805bd0c0459f75171e4335ad3bf85f54ad Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 12:23:06 +0100 Subject: [PATCH 12/16] Update changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml Co-authored-by: Mark Chappell --- .../122-aws_secret-add-on_missing-and-on_denied-option.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml b/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml index 686e6fd7245..67a6dddbb4a 100644 --- a/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml +++ b/changelogs/fragments/122-aws_secret-add-on_missing-and-on_denied-option.yml @@ -1,2 +1,2 @@ minor_changes: - - aws_secret - add "on_missing" and "on_denied" option + - aws_secret - add "on_missing" and "on_denied" option (https://github.com/ansible-collections/amazon.aws/pull/122). From 5b940d765343fd86b4e5e13bace67fe7790ea67c Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:35:08 +0000 Subject: [PATCH 13/16] - use is_boto3_error_code helper --- plugins/lookup/aws_secret.py | 21 +++++++++++--------- tests/unit/plugins/lookup/test_aws_secret.py | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 1aeba2d5a2f..0a0f0ebf788 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -95,7 +95,7 @@ from ansible.plugins import AnsiblePlugin from ansible.plugins.lookup import LookupBase from ansible.module_utils._text import to_native - +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code def _boto3_conn(region, credentials): boto_profile = credentials.pop('aws_profile', None) @@ -162,15 +162,18 @@ def run(self, terms, variables, **kwargs): secrets.append(response['SecretBinary']) if 'SecretString' in response: secrets.append(response['SecretString']) + except is_boto3_error_code('ResourceNotFoundException'): + if missing == 'error': + raise AnsibleError("Failed to find secret %s (ResourceNotFound)" % term) + elif missing == 'warn': + self._display.warning('Skipping, did not find secret %s' % term) + except is_boto3_error_code('AccessDeniedException'): + if denied == 'error': + raise AnsibleError("Failed to access secret %s (AccessDenied)" % term) + elif denied == 'warn': + self._display.warning('Skipping, access denied for secret %s' % term) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - if e.response['Error']['Code'] == 'ResourceNotFoundException' and missing in ['warn', 'skip']: - if missing == 'warn': - self._display.warning('Skipping, did not find secret %s' % term) - elif e.response['Error']['Code'] == 'AccessDeniedException' and denied in ['warn', 'skip']: - if denied == 'warn': - self._display.warning('Skipping, access denied for secret %s' % term) - else: - raise AnsibleError("Failed to retrieve secret: %s" % to_native(e)) + raise AnsibleError("Failed to retrieve secret: %s" % to_native(e)) if kwargs.get('join'): joined_secret = [] diff --git a/tests/unit/plugins/lookup/test_aws_secret.py b/tests/unit/plugins/lookup/test_aws_secret.py index 07f6ac22d2d..1f3957419ee 100644 --- a/tests/unit/plugins/lookup/test_aws_secret.py +++ b/tests/unit/plugins/lookup/test_aws_secret.py @@ -87,7 +87,7 @@ def test_on_missing_option(mocker, dummy_credentials): boto3_double = mocker.MagicMock() boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response_missing, operation_name) - with pytest.raises(AnsibleError, match="ResourceNotFoundException"): + with pytest.raises(AnsibleError, match="ResourceNotFound"): mocker.patch.object(boto3, 'session', boto3_double) lookup_loader.get('amazon.aws.aws_secret').run(["missing_secret"], None, **dummy_credentials) @@ -108,7 +108,7 @@ def test_on_denied_option(mocker, dummy_credentials): boto3_double = mocker.MagicMock() boto3_double.Session.return_value.client.return_value.get_secret_value.side_effect = ClientError(error_response_denied, operation_name) - with pytest.raises(AnsibleError, match="AccessDeniedException"): + with pytest.raises(AnsibleError, match="AccessDenied"): mocker.patch.object(boto3, 'session', boto3_double) lookup_loader.get('amazon.aws.aws_secret').run(["denied_secret"], None, **dummy_credentials) From 0b1717620090fee17ba8a6fabdb2d04d01eeb1a4 Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 11:46:15 +0000 Subject: [PATCH 14/16] - add requested changes to on_denied info --- plugins/lookup/aws_secret.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 0a0f0ebf788..1f3d5ac0d25 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -48,10 +48,10 @@ choices: ['error', 'skip', 'warn'] on_denied: description: - - action to take if access to secret is denied - - Error will raise a fatal error - - Skip will just ignore the term - - Warn will skip over it but issue a warning + - Action to take if access to the secret is denied. + - C(error) will raise a fatal error when access to the secret is denied. + - C(skip) will silently ignore the denied secret. + - C(warn) will skip over the denied secret but issue a warning. default: error type: string choices: ['error', 'skip', 'warn'] From 703ea347f56f45de1c42fb5553823106460bf4ab Mon Sep 17 00:00:00 2001 From: Rene Schumann Date: Thu, 19 Nov 2020 13:10:44 +0100 Subject: [PATCH 15/16] Update plugins/lookup/aws_secret.py Co-authored-by: Mark Chappell --- plugins/lookup/aws_secret.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index 1f3d5ac0d25..ee37586a805 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -97,6 +97,7 @@ from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code + def _boto3_conn(region, credentials): boto_profile = credentials.pop('aws_profile', None) From 5e517882c09f52b91df83d78fc887cb09e613f58 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 19 Nov 2020 13:42:05 +0100 Subject: [PATCH 16/16] Pylint - ignore "duplicate exception" false positive --- plugins/lookup/aws_secret.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/lookup/aws_secret.py b/plugins/lookup/aws_secret.py index ee37586a805..f8b978fd23f 100644 --- a/plugins/lookup/aws_secret.py +++ b/plugins/lookup/aws_secret.py @@ -168,12 +168,12 @@ def run(self, terms, variables, **kwargs): raise AnsibleError("Failed to find secret %s (ResourceNotFound)" % term) elif missing == 'warn': self._display.warning('Skipping, did not find secret %s' % term) - except is_boto3_error_code('AccessDeniedException'): + except is_boto3_error_code('AccessDeniedException'): # pylint: disable=duplicate-except if denied == 'error': raise AnsibleError("Failed to access secret %s (AccessDenied)" % term) elif denied == 'warn': self._display.warning('Skipping, access denied for secret %s' % term) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except raise AnsibleError("Failed to retrieve secret: %s" % to_native(e)) if kwargs.get('join'):