|
6 | 6 | from confluent_kafka import Consumer, ConsumerGroupTopicPartitions, KafkaException, TopicPartition |
7 | 7 | from confluent_kafka.admin import AdminClient |
8 | 8 |
|
| 9 | +# AWS MSK IAM authentication support |
| 10 | +try: |
| 11 | + import boto3 |
| 12 | + from aws_msk_iam_sasl_signer import MSKAuthTokenProvider |
| 13 | + |
| 14 | + AWS_MSK_IAM_AVAILABLE = True |
| 15 | +except ImportError: |
| 16 | + AWS_MSK_IAM_AVAILABLE = False |
| 17 | + |
9 | 18 |
|
10 | 19 | class KafkaClient: |
11 | 20 | def __init__(self, config, log) -> None: |
@@ -71,16 +80,55 @@ def __get_authentication_config(self): |
71 | 80 | } |
72 | 81 |
|
73 | 82 | if self.config._sasl_mechanism == "OAUTHBEARER": |
74 | | - extras_parameters['sasl.oauthbearer.method'] = "oidc" |
75 | | - extras_parameters["sasl.oauthbearer.client.id"] = self.config._sasl_oauth_token_provider.get("client_id") |
76 | | - extras_parameters["sasl.oauthbearer.token.endpoint.url"] = self.config._sasl_oauth_token_provider.get("url") |
77 | | - extras_parameters["sasl.oauthbearer.client.secret"] = self.config._sasl_oauth_token_provider.get( |
78 | | - "client_secret" |
79 | | - ) |
80 | | - extras_parameters["sasl.oauthbearer.scope"] = self.config._sasl_oauth_token_provider.get("scope") |
81 | | - extras_parameters["sasl.oauthbearer.extensions"] = self.config._sasl_oauth_token_provider.get("extensions") |
82 | | - if self.config._sasl_oauth_tls_ca_cert: |
83 | | - extras_parameters["https.ca.location"] = self.config._sasl_oauth_tls_ca_cert |
| 83 | + # Default to 'oidc' for backwards compatibility with existing configs |
| 84 | + method = self.config._sasl_oauth_token_provider.get("method", "oidc") |
| 85 | + |
| 86 | + if method == "aws_msk_iam": |
| 87 | + if not AWS_MSK_IAM_AVAILABLE: |
| 88 | + raise Exception( |
| 89 | + "AWS MSK IAM authentication requires 'aws-msk-iam-sasl-signer-python' library. " |
| 90 | + "Install it with: pip install aws-msk-iam-sasl-signer-python" |
| 91 | + ) |
| 92 | + |
| 93 | + def _aws_msk_iam_oauth_cb(oauth_config): |
| 94 | + """OAuth callback that generates AWS MSK IAM authentication tokens.""" |
| 95 | + try: |
| 96 | + region = self.config._sasl_oauth_token_provider.get("aws_region") |
| 97 | + if not region: |
| 98 | + region = boto3.session.Session().region_name |
| 99 | + |
| 100 | + if not region: |
| 101 | + raise Exception( |
| 102 | + "AWS region could not be determined. Please specify 'aws_region' in " |
| 103 | + "sasl_oauth_token_provider configuration." |
| 104 | + ) |
| 105 | + |
| 106 | + auth_token, expiry_ms = MSKAuthTokenProvider.generate_auth_token(region) |
| 107 | + self.log.debug("Generated AWS MSK IAM token for region %s, expires in %s ms", region, expiry_ms) |
| 108 | + return auth_token, expiry_ms / 1000 # Convert to seconds |
| 109 | + except Exception as e: |
| 110 | + self.log.error("Failed to generate AWS MSK IAM token: %s", e) |
| 111 | + raise |
| 112 | + |
| 113 | + extras_parameters['oauth_cb'] = _aws_msk_iam_oauth_cb |
| 114 | + |
| 115 | + elif method == "oidc": |
| 116 | + extras_parameters['sasl.oauthbearer.method'] = "oidc" |
| 117 | + extras_parameters["sasl.oauthbearer.client.id"] = self.config._sasl_oauth_token_provider.get( |
| 118 | + "client_id" |
| 119 | + ) |
| 120 | + extras_parameters["sasl.oauthbearer.token.endpoint.url"] = self.config._sasl_oauth_token_provider.get( |
| 121 | + "url" |
| 122 | + ) |
| 123 | + extras_parameters["sasl.oauthbearer.client.secret"] = self.config._sasl_oauth_token_provider.get( |
| 124 | + "client_secret" |
| 125 | + ) |
| 126 | + extras_parameters["sasl.oauthbearer.scope"] = self.config._sasl_oauth_token_provider.get("scope") |
| 127 | + extras_parameters["sasl.oauthbearer.extensions"] = self.config._sasl_oauth_token_provider.get( |
| 128 | + "extensions" |
| 129 | + ) |
| 130 | + if self.config._sasl_oauth_tls_ca_cert: |
| 131 | + extras_parameters["https.ca.location"] = self.config._sasl_oauth_tls_ca_cert |
84 | 132 |
|
85 | 133 | for key, value in extras_parameters.items(): |
86 | 134 | # Do not add the value if it's not specified |
|
0 commit comments