Skip to content

Commit 39bc952

Browse files
author
Joshua Williams
committed
Proxying all calls to a KMS client
This is needed to remove the client from the regional client cache if a error is detected that indicates the client has been misconfigured. and running black on the file
1 parent 1dedaca commit 39bc952

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

src/aws_encryption_sdk/key_providers/kms.py

+33-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
1313
"""Master Key Providers for use with AWS KMS"""
14+
import functools
1415
import logging
1516

1617
import attr
@@ -128,15 +129,44 @@ def _process_config(self):
128129
if self.config.key_ids:
129130
self.add_master_keys_from_list(self.config.key_ids)
130131

132+
def _wrap_client(self, region_name, method, *args, **kwargs):
133+
"""Proxies all calls to a kms clients methods and removes misbehaving clients
134+
135+
:param str region_name: AWS Region ID (ex: us-east-1)
136+
:param callable method: a method on the KMS client to proxy
137+
:param tuple args: list of arguments to pass to the provided ``method``
138+
:param dict kwargs: dictonary of keyword arguments to pass to the provided ``method``
139+
"""
140+
try:
141+
return method(*args, **kwargs)
142+
except botocore.exceptions.BotoCoreError:
143+
self._regional_clients.pop(region_name)
144+
_LOGGER.error(
145+
'Removing regional client "%s" from cache due to BotoCoreError on %s call', region_name, method.__name__
146+
)
147+
raise
148+
149+
def _register_client(self, client, region_name):
150+
"""Uses functools.partial to wrap all methods on a client with the self._wrap_client method
151+
152+
:param botocore.client.BaseClient client: the client to proxy
153+
:param str region_name: AWS Region ID (ex: us-east-1)
154+
"""
155+
for item in client.meta.method_to_api_mapping:
156+
method = getattr(client, item)
157+
wrapped_method = functools.partial(self._wrap_client, region_name, method)
158+
setattr(client, item, wrapped_method)
159+
131160
def add_regional_client(self, region_name):
132161
"""Adds a regional client for the specified region if it does not already exist.
133162
134163
:param str region_name: AWS Region ID (ex: us-east-1)
135164
"""
136165
if region_name not in self._regional_clients:
137-
self._regional_clients[region_name] = boto3.session.Session(
138-
region_name=region_name, botocore_session=self.config.botocore_session
139-
).client("kms", config=self._user_agent_adding_config)
166+
session = boto3.session.Session(region_name=region_name, botocore_session=self.config.botocore_session)
167+
client = session.client("kms", config=self._user_agent_adding_config)
168+
self._register_client(client, region_name)
169+
self._regional_clients[region_name] = client
140170

141171
def add_regional_clients_from_list(self, region_names):
142172
"""Adds multiple regional clients for the specified regions if they do not already exist.

test/integration/test_i_aws_encrytion_sdk_client.py

+10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ def test_encrypt_verify_user_agent_kms_master_key(caplog):
5858
assert USER_AGENT_SUFFIX in caplog.text
5959

6060

61+
def test_remove_bad_client():
62+
test = KMSMasterKeyProvider()
63+
test.add_regional_client("us-fakey-12")
64+
65+
with pytest.raises(BotoCoreError):
66+
test._regional_clients["us-fakey-12"].list_keys()
67+
68+
assert not test._regional_clients
69+
70+
6171
class TestKMSThickClientIntegration(unittest.TestCase):
6272
def setUp(self):
6373
self.kms_master_key_provider = setup_kms_master_key_provider()

test/unit/test_providers_kms_master_key_provider.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import botocore.client
1717
import pytest
1818
import six
19+
from botocore.exceptions import BotoCoreError
1920
from mock import ANY, MagicMock, call, patch, sentinel
2021

2122
from aws_encryption_sdk.exceptions import UnknownRegionError

0 commit comments

Comments
 (0)