|
| 1 | +from __future__ import absolute_import |
| 2 | + |
1 | 3 | import datetime
|
2 | 4 | import hashlib
|
3 | 5 | import hmac
|
4 | 6 | import json
|
| 7 | +import logging |
5 | 8 | import string
|
6 | 9 |
|
| 10 | +# needed for AWS_MSK_IAM authentication: |
| 11 | +try: |
| 12 | + from botocore.session import Session as BotoSession |
| 13 | +except ImportError: |
| 14 | + # no botocore available, will disable AWS_MSK_IAM mechanism |
| 15 | + BotoSession = None |
| 16 | + |
| 17 | +from kafka.sasl.abc import SaslMechanism |
7 | 18 | from kafka.vendor.six.moves import urllib
|
8 | 19 |
|
9 | 20 |
|
| 21 | +log = logging.getLogger(__name__) |
| 22 | + |
| 23 | + |
| 24 | +class SaslMechanismAwsMskIam(SaslMechanism): |
| 25 | + def __init__(self, **config): |
| 26 | + assert BotoSession is not None, 'AWS_MSK_IAM requires the "botocore" package' |
| 27 | + assert config['security_protocol'] == 'SASL_SSL', 'AWS_MSK_IAM requires SASL_SSL' |
| 28 | + self._is_done = False |
| 29 | + self._is_authenticated = False |
| 30 | + |
| 31 | + def auth_bytes(self): |
| 32 | + session = BotoSession() |
| 33 | + credentials = session.get_credentials().get_frozen_credentials() |
| 34 | + client = AwsMskIamClient( |
| 35 | + host=self.host, |
| 36 | + access_key=credentials.access_key, |
| 37 | + secret_key=credentials.secret_key, |
| 38 | + region=session.get_config_variable('region'), |
| 39 | + token=credentials.token, |
| 40 | + ) |
| 41 | + return client.first_message() |
| 42 | + |
| 43 | + def receive(self, auth_bytes): |
| 44 | + self._is_done = True |
| 45 | + self._is_authenticated = auth_bytes != b'' |
| 46 | + log.info('Authenticated via AWS_MSK_IAM %s', auth_bytes.decode('utf-8')) |
| 47 | + |
| 48 | + def is_done(self): |
| 49 | + return self._is_done |
| 50 | + |
| 51 | + def is_authenticated(self): |
| 52 | + return self._is_authenticated |
| 53 | + |
| 54 | + |
10 | 55 | class AwsMskIamClient:
|
11 | 56 | UNRESERVED_CHARS = string.ascii_letters + string.digits + '-._~'
|
12 | 57 |
|
|
0 commit comments