kafka-python 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kafka/__init__.py +34 -0
- kafka/__main__.py +5 -0
- kafka/admin/__init__.py +29 -0
- kafka/admin/__main__.py +5 -0
- kafka/admin/_acls.py +355 -0
- kafka/admin/_cluster.py +359 -0
- kafka/admin/_configs.py +479 -0
- kafka/admin/_groups.py +754 -0
- kafka/admin/_partitions.py +595 -0
- kafka/admin/_topics.py +281 -0
- kafka/admin/_transactions.py +450 -0
- kafka/admin/_users.py +194 -0
- kafka/admin/client.py +373 -0
- kafka/benchmarks/__init__.py +0 -0
- kafka/benchmarks/consumer_performance.py +138 -0
- kafka/benchmarks/load_example.py +109 -0
- kafka/benchmarks/producer_encode_path.py +201 -0
- kafka/benchmarks/producer_performance.py +161 -0
- kafka/benchmarks/profile_protocol.py +138 -0
- kafka/benchmarks/protocol_old_vs_new.py +447 -0
- kafka/benchmarks/record_batch_compose.py +77 -0
- kafka/benchmarks/record_batch_read.py +82 -0
- kafka/benchmarks/varint_speed.py +426 -0
- kafka/cli/__init__.py +36 -0
- kafka/cli/admin/__init__.py +117 -0
- kafka/cli/admin/acls/__init__.py +9 -0
- kafka/cli/admin/acls/common.py +76 -0
- kafka/cli/admin/acls/create.py +19 -0
- kafka/cli/admin/acls/delete.py +23 -0
- kafka/cli/admin/acls/describe.py +16 -0
- kafka/cli/admin/cluster/__init__.py +14 -0
- kafka/cli/admin/cluster/describe.py +11 -0
- kafka/cli/admin/cluster/describe_quorum.py +11 -0
- kafka/cli/admin/cluster/features.py +52 -0
- kafka/cli/admin/cluster/log_dirs.py +43 -0
- kafka/cli/admin/cluster/versions.py +33 -0
- kafka/cli/admin/configs/__init__.py +10 -0
- kafka/cli/admin/configs/alter.py +43 -0
- kafka/cli/admin/configs/common.py +17 -0
- kafka/cli/admin/configs/describe.py +30 -0
- kafka/cli/admin/configs/list.py +16 -0
- kafka/cli/admin/configs/reset.py +20 -0
- kafka/cli/admin/groups/__init__.py +16 -0
- kafka/cli/admin/groups/alter_offsets.py +30 -0
- kafka/cli/admin/groups/delete.py +11 -0
- kafka/cli/admin/groups/delete_offsets.py +29 -0
- kafka/cli/admin/groups/describe.py +11 -0
- kafka/cli/admin/groups/list.py +28 -0
- kafka/cli/admin/groups/list_offsets.py +29 -0
- kafka/cli/admin/groups/remove_members.py +40 -0
- kafka/cli/admin/groups/reset_offsets.py +139 -0
- kafka/cli/admin/partitions/__init__.py +21 -0
- kafka/cli/admin/partitions/alter_reassignments.py +37 -0
- kafka/cli/admin/partitions/create.py +27 -0
- kafka/cli/admin/partitions/delete_records.py +31 -0
- kafka/cli/admin/partitions/describe.py +36 -0
- kafka/cli/admin/partitions/elect_leaders.py +53 -0
- kafka/cli/admin/partitions/list_offsets.py +88 -0
- kafka/cli/admin/partitions/list_reassignments.py +35 -0
- kafka/cli/admin/topics/__init__.py +10 -0
- kafka/cli/admin/topics/create.py +13 -0
- kafka/cli/admin/topics/delete.py +19 -0
- kafka/cli/admin/topics/describe.py +18 -0
- kafka/cli/admin/topics/list.py +11 -0
- kafka/cli/admin/transactions/__init__.py +17 -0
- kafka/cli/admin/transactions/abort.py +38 -0
- kafka/cli/admin/transactions/describe.py +24 -0
- kafka/cli/admin/transactions/describe_producers.py +29 -0
- kafka/cli/admin/transactions/find_hanging.py +26 -0
- kafka/cli/admin/transactions/list.py +37 -0
- kafka/cli/admin/users/__init__.py +8 -0
- kafka/cli/admin/users/alter_user_scram_credentials.py +34 -0
- kafka/cli/admin/users/describe_user_scram_credentials.py +15 -0
- kafka/cli/common.py +95 -0
- kafka/cli/consumer/__init__.py +63 -0
- kafka/cli/producer/__init__.py +57 -0
- kafka/cluster.py +824 -0
- kafka/codec.py +325 -0
- kafka/consumer/__init__.py +5 -0
- kafka/consumer/__main__.py +5 -0
- kafka/consumer/fetcher.py +2012 -0
- kafka/consumer/group.py +1347 -0
- kafka/consumer/subscription_state.py +897 -0
- kafka/coordinator/__init__.py +0 -0
- kafka/coordinator/assignors/__init__.py +0 -0
- kafka/coordinator/assignors/abstract.py +90 -0
- kafka/coordinator/assignors/cooperative_sticky.py +167 -0
- kafka/coordinator/assignors/range.py +81 -0
- kafka/coordinator/assignors/roundrobin.py +101 -0
- kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +37 -0
- kafka/coordinator/assignors/sticky/__init__.py +0 -0
- kafka/coordinator/assignors/sticky/partition_movements.py +149 -0
- kafka/coordinator/assignors/sticky/sorted_set.py +63 -0
- kafka/coordinator/assignors/sticky/sticky_assignor.py +665 -0
- kafka/coordinator/assignors/sticky/user_data.py +8 -0
- kafka/coordinator/base.py +1215 -0
- kafka/coordinator/consumer.py +1224 -0
- kafka/coordinator/heartbeat.py +82 -0
- kafka/coordinator/subscription.py +34 -0
- kafka/errors.py +1004 -0
- kafka/future.py +166 -0
- kafka/metrics/__init__.py +13 -0
- kafka/metrics/compound_stat.py +33 -0
- kafka/metrics/dict_reporter.py +81 -0
- kafka/metrics/kafka_metric.py +36 -0
- kafka/metrics/measurable.py +27 -0
- kafka/metrics/measurable_stat.py +13 -0
- kafka/metrics/metric_config.py +33 -0
- kafka/metrics/metric_name.py +105 -0
- kafka/metrics/metrics.py +261 -0
- kafka/metrics/metrics_reporter.py +53 -0
- kafka/metrics/quota.py +41 -0
- kafka/metrics/stat.py +19 -0
- kafka/metrics/stats/__init__.py +15 -0
- kafka/metrics/stats/avg.py +24 -0
- kafka/metrics/stats/count.py +17 -0
- kafka/metrics/stats/histogram.py +99 -0
- kafka/metrics/stats/max_stat.py +17 -0
- kafka/metrics/stats/min_stat.py +19 -0
- kafka/metrics/stats/percentile.py +14 -0
- kafka/metrics/stats/percentiles.py +75 -0
- kafka/metrics/stats/rate.py +118 -0
- kafka/metrics/stats/sampled_stat.py +99 -0
- kafka/metrics/stats/sensor.py +136 -0
- kafka/metrics/stats/total.py +15 -0
- kafka/net/__init__.py +19 -0
- kafka/net/compat.py +165 -0
- kafka/net/connection.py +593 -0
- kafka/net/http_connect.py +144 -0
- kafka/net/inet.py +122 -0
- kafka/net/manager.py +451 -0
- kafka/net/metrics.py +149 -0
- kafka/net/sasl/__init__.py +32 -0
- kafka/net/sasl/abc.py +28 -0
- kafka/net/sasl/gssapi.py +95 -0
- kafka/net/sasl/msk.py +245 -0
- kafka/net/sasl/oauth.py +98 -0
- kafka/net/sasl/plain.py +42 -0
- kafka/net/sasl/scram.py +135 -0
- kafka/net/sasl/sspi.py +111 -0
- kafka/net/selector.py +644 -0
- kafka/net/socks5.py +262 -0
- kafka/net/transport.py +415 -0
- kafka/net/wakeup_notifier.py +72 -0
- kafka/partitioner/__init__.py +8 -0
- kafka/partitioner/abc.py +8 -0
- kafka/partitioner/default.py +89 -0
- kafka/partitioner/sticky.py +109 -0
- kafka/producer/__init__.py +5 -0
- kafka/producer/__main__.py +5 -0
- kafka/producer/future.py +101 -0
- kafka/producer/kafka.py +1123 -0
- kafka/producer/producer_batch.py +192 -0
- kafka/producer/record_accumulator.py +647 -0
- kafka/producer/sender.py +884 -0
- kafka/producer/transaction_manager.py +1326 -0
- kafka/protocol/__init__.py +0 -0
- kafka/protocol/admin/__init__.py +29 -0
- kafka/protocol/admin/acl.py +83 -0
- kafka/protocol/admin/acl.pyi +375 -0
- kafka/protocol/admin/client_quotas.py +14 -0
- kafka/protocol/admin/client_quotas.pyi +265 -0
- kafka/protocol/admin/cluster.py +31 -0
- kafka/protocol/admin/cluster.pyi +620 -0
- kafka/protocol/admin/configs.py +22 -0
- kafka/protocol/admin/configs.pyi +437 -0
- kafka/protocol/admin/groups.py +24 -0
- kafka/protocol/admin/groups.pyi +261 -0
- kafka/protocol/admin/topics.py +53 -0
- kafka/protocol/admin/topics.pyi +982 -0
- kafka/protocol/admin/transactions.py +18 -0
- kafka/protocol/admin/transactions.pyi +311 -0
- kafka/protocol/admin/users.py +14 -0
- kafka/protocol/admin/users.pyi +223 -0
- kafka/protocol/api_data.py +125 -0
- kafka/protocol/api_header.py +55 -0
- kafka/protocol/api_key.py +97 -0
- kafka/protocol/api_message.py +277 -0
- kafka/protocol/broker_version_data.py +246 -0
- kafka/protocol/consumer/__init__.py +13 -0
- kafka/protocol/consumer/fetch.py +16 -0
- kafka/protocol/consumer/fetch.pyi +298 -0
- kafka/protocol/consumer/group.py +38 -0
- kafka/protocol/consumer/group.pyi +824 -0
- kafka/protocol/consumer/metadata.py +30 -0
- kafka/protocol/consumer/metadata.pyi +89 -0
- kafka/protocol/consumer/offsets.py +75 -0
- kafka/protocol/consumer/offsets.pyi +288 -0
- kafka/protocol/data_container.py +166 -0
- kafka/protocol/frame.py +30 -0
- kafka/protocol/generate_stubs.py +468 -0
- kafka/protocol/metadata/__init__.py +10 -0
- kafka/protocol/metadata/api_versions.py +41 -0
- kafka/protocol/metadata/api_versions.pyi +128 -0
- kafka/protocol/metadata/find_coordinator.py +19 -0
- kafka/protocol/metadata/find_coordinator.pyi +105 -0
- kafka/protocol/metadata/metadata.py +34 -0
- kafka/protocol/metadata/metadata.pyi +160 -0
- kafka/protocol/old/__init__.py +0 -0
- kafka/protocol/old/abstract.py +17 -0
- kafka/protocol/old/add_offsets_to_txn.py +54 -0
- kafka/protocol/old/add_partitions_to_txn.py +71 -0
- kafka/protocol/old/admin.py +1086 -0
- kafka/protocol/old/api.py +205 -0
- kafka/protocol/old/api_versions.py +133 -0
- kafka/protocol/old/commit.py +355 -0
- kafka/protocol/old/consumer_protocol.py +36 -0
- kafka/protocol/old/end_txn.py +53 -0
- kafka/protocol/old/fetch.py +408 -0
- kafka/protocol/old/find_coordinator.py +72 -0
- kafka/protocol/old/group.py +451 -0
- kafka/protocol/old/init_producer_id.py +42 -0
- kafka/protocol/old/list_offsets.py +186 -0
- kafka/protocol/old/metadata.py +290 -0
- kafka/protocol/old/offset_for_leader_epoch.py +133 -0
- kafka/protocol/old/produce.py +247 -0
- kafka/protocol/old/sasl_authenticate.py +38 -0
- kafka/protocol/old/sasl_handshake.py +39 -0
- kafka/protocol/old/struct.py +87 -0
- kafka/protocol/old/txn_offset_commit.py +73 -0
- kafka/protocol/old/types.py +440 -0
- kafka/protocol/parser.py +191 -0
- kafka/protocol/producer/__init__.py +7 -0
- kafka/protocol/producer/produce.py +17 -0
- kafka/protocol/producer/produce.pyi +197 -0
- kafka/protocol/producer/transaction.py +30 -0
- kafka/protocol/producer/transaction.pyi +663 -0
- kafka/protocol/sasl.py +52 -0
- kafka/protocol/sasl.pyi +126 -0
- kafka/protocol/schemas/__init__.py +7 -0
- kafka/protocol/schemas/fields/__init__.py +7 -0
- kafka/protocol/schemas/fields/array.py +127 -0
- kafka/protocol/schemas/fields/base.py +156 -0
- kafka/protocol/schemas/fields/codecs/__init__.py +12 -0
- kafka/protocol/schemas/fields/codecs/encode_buffer.py +82 -0
- kafka/protocol/schemas/fields/codecs/tagged_fields.py +109 -0
- kafka/protocol/schemas/fields/codecs/types.py +505 -0
- kafka/protocol/schemas/fields/codegen.py +40 -0
- kafka/protocol/schemas/fields/simple.py +127 -0
- kafka/protocol/schemas/fields/struct.py +357 -0
- kafka/protocol/schemas/fields/struct_array.py +142 -0
- kafka/protocol/schemas/load_json.py +42 -0
- kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +40 -0
- kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +35 -0
- kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +65 -0
- kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +60 -0
- kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +47 -0
- kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +41 -0
- kafka/protocol/schemas/resources/AlterConfigsRequest.json +43 -0
- kafka/protocol/schemas/resources/AlterConfigsResponse.json +39 -0
- kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +42 -0
- kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +47 -0
- kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +41 -0
- kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +41 -0
- kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +45 -0
- kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +35 -0
- kafka/protocol/schemas/resources/ApiVersionsRequest.json +34 -0
- kafka/protocol/schemas/resources/ApiVersionsResponse.json +79 -0
- kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +42 -0
- kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +49 -0
- kafka/protocol/schemas/resources/CreateAclsRequest.json +46 -0
- kafka/protocol/schemas/resources/CreateAclsResponse.json +37 -0
- kafka/protocol/schemas/resources/CreatePartitionsRequest.json +47 -0
- kafka/protocol/schemas/resources/CreatePartitionsResponse.json +41 -0
- kafka/protocol/schemas/resources/CreateTopicsRequest.json +65 -0
- kafka/protocol/schemas/resources/CreateTopicsResponse.json +72 -0
- kafka/protocol/schemas/resources/DeleteAclsRequest.json +46 -0
- kafka/protocol/schemas/resources/DeleteAclsResponse.json +59 -0
- kafka/protocol/schemas/resources/DeleteGroupsRequest.json +30 -0
- kafka/protocol/schemas/resources/DeleteGroupsResponse.json +36 -0
- kafka/protocol/schemas/resources/DeleteRecordsRequest.json +42 -0
- kafka/protocol/schemas/resources/DeleteRecordsResponse.json +43 -0
- kafka/protocol/schemas/resources/DeleteTopicsRequest.json +43 -0
- kafka/protocol/schemas/resources/DeleteTopicsResponse.json +52 -0
- kafka/protocol/schemas/resources/DescribeAclsRequest.json +43 -0
- kafka/protocol/schemas/resources/DescribeAclsResponse.json +55 -0
- kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +37 -0
- kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +47 -0
- kafka/protocol/schemas/resources/DescribeClusterRequest.json +35 -0
- kafka/protocol/schemas/resources/DescribeClusterResponse.json +56 -0
- kafka/protocol/schemas/resources/DescribeConfigsRequest.json +42 -0
- kafka/protocol/schemas/resources/DescribeConfigsResponse.json +69 -0
- kafka/protocol/schemas/resources/DescribeGroupsRequest.json +38 -0
- kafka/protocol/schemas/resources/DescribeGroupsResponse.json +74 -0
- kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +38 -0
- kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +65 -0
- kafka/protocol/schemas/resources/DescribeProducersRequest.json +32 -0
- kafka/protocol/schemas/resources/DescribeProducersResponse.json +55 -0
- kafka/protocol/schemas/resources/DescribeQuorumRequest.json +39 -0
- kafka/protocol/schemas/resources/DescribeQuorumResponse.json +82 -0
- kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +40 -0
- kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +66 -0
- kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +27 -0
- kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +52 -0
- kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +30 -0
- kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +45 -0
- kafka/protocol/schemas/resources/ElectLeadersRequest.json +41 -0
- kafka/protocol/schemas/resources/ElectLeadersResponse.json +45 -0
- kafka/protocol/schemas/resources/EndTxnRequest.json +43 -0
- kafka/protocol/schemas/resources/EndTxnResponse.json +41 -0
- kafka/protocol/schemas/resources/FetchRequest.json +125 -0
- kafka/protocol/schemas/resources/FetchResponse.json +124 -0
- kafka/protocol/schemas/resources/FindCoordinatorRequest.json +43 -0
- kafka/protocol/schemas/resources/FindCoordinatorResponse.json +58 -0
- kafka/protocol/schemas/resources/HeartbeatRequest.json +39 -0
- kafka/protocol/schemas/resources/HeartbeatResponse.json +35 -0
- kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +44 -0
- kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +38 -0
- kafka/protocol/schemas/resources/InitProducerIdRequest.json +50 -0
- kafka/protocol/schemas/resources/InitProducerIdResponse.json +47 -0
- kafka/protocol/schemas/resources/JoinGroupRequest.json +63 -0
- kafka/protocol/schemas/resources/JoinGroupResponse.json +69 -0
- kafka/protocol/schemas/resources/LeaveGroupRequest.json +47 -0
- kafka/protocol/schemas/resources/LeaveGroupResponse.json +47 -0
- kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +31 -0
- kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +37 -0
- kafka/protocol/schemas/resources/ListGroupsRequest.json +36 -0
- kafka/protocol/schemas/resources/ListGroupsResponse.json +49 -0
- kafka/protocol/schemas/resources/ListOffsetsRequest.json +72 -0
- kafka/protocol/schemas/resources/ListOffsetsResponse.json +71 -0
- kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +34 -0
- kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +46 -0
- kafka/protocol/schemas/resources/ListTransactionsRequest.json +40 -0
- kafka/protocol/schemas/resources/ListTransactionsResponse.json +42 -0
- kafka/protocol/schemas/resources/MetadataRequest.json +56 -0
- kafka/protocol/schemas/resources/MetadataResponse.json +101 -0
- kafka/protocol/schemas/resources/OffsetCommitRequest.json +76 -0
- kafka/protocol/schemas/resources/OffsetCommitResponse.json +71 -0
- kafka/protocol/schemas/resources/OffsetDeleteRequest.json +39 -0
- kafka/protocol/schemas/resources/OffsetDeleteResponse.json +42 -0
- kafka/protocol/schemas/resources/OffsetFetchRequest.json +76 -0
- kafka/protocol/schemas/resources/OffsetFetchResponse.json +107 -0
- kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +52 -0
- kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +51 -0
- kafka/protocol/schemas/resources/ProduceRequest.json +73 -0
- kafka/protocol/schemas/resources/ProduceResponse.json +96 -0
- kafka/protocol/schemas/resources/RequestHeader.json +44 -0
- kafka/protocol/schemas/resources/ResponseHeader.json +26 -0
- kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +29 -0
- kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +34 -0
- kafka/protocol/schemas/resources/SaslHandshakeRequest.json +31 -0
- kafka/protocol/schemas/resources/SaslHandshakeResponse.json +32 -0
- kafka/protocol/schemas/resources/SyncGroupRequest.json +56 -0
- kafka/protocol/schemas/resources/SyncGroupResponse.json +46 -0
- kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +68 -0
- kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +47 -0
- kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +43 -0
- kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +39 -0
- kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +49 -0
- kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +45 -0
- kafka/protocol/schemas/resources/__init__.py +0 -0
- kafka/record/__init__.py +3 -0
- kafka/record/_crc32c.py +161 -0
- kafka/record/abc.py +144 -0
- kafka/record/default_records.py +782 -0
- kafka/record/legacy_records.py +587 -0
- kafka/record/memory_records.py +255 -0
- kafka/record/util.py +135 -0
- kafka/serializer/__init__.py +4 -0
- kafka/serializer/abstract.py +20 -0
- kafka/serializer/default.py +16 -0
- kafka/serializer/json.py +17 -0
- kafka/serializer/wrapper.py +21 -0
- kafka/structs.py +69 -0
- kafka/util.py +159 -0
- kafka/vendor/__init__.py +0 -0
- kafka/version.py +1 -0
- kafka_python-3.0.0.dist-info/METADATA +319 -0
- kafka_python-3.0.0.dist-info/RECORD +373 -0
- kafka_python-3.0.0.dist-info/WHEEL +5 -0
- kafka_python-3.0.0.dist-info/entry_points.txt +2 -0
- kafka_python-3.0.0.dist-info/licenses/LICENSE +202 -0
- kafka_python-3.0.0.dist-info/top_level.txt +1 -0
kafka/admin/_configs.py
ADDED
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
"""Configuration management mixin for KafkaAdminClient.
|
|
2
|
+
|
|
3
|
+
Also defines ConfigResource and ConfigResourceType data classes.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from collections import defaultdict
|
|
9
|
+
from enum import IntEnum
|
|
10
|
+
import logging
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
import kafka.errors as Errors
|
|
14
|
+
from kafka.protocol.admin import (
|
|
15
|
+
AlterConfigsRequest,
|
|
16
|
+
DescribeConfigsRequest,
|
|
17
|
+
IncrementalAlterConfigsRequest,
|
|
18
|
+
ListConfigResourcesRequest,
|
|
19
|
+
)
|
|
20
|
+
from kafka.util import EnumHelper
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from kafka.net.manager import KafkaConnectionManager
|
|
24
|
+
|
|
25
|
+
log = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConfigAdminMixin:
|
|
29
|
+
"""Mixin providing configuration management methods for KafkaAdminClient."""
|
|
30
|
+
_manager: KafkaConnectionManager
|
|
31
|
+
config: dict
|
|
32
|
+
|
|
33
|
+
def _check_incremental_alter_configs_support(self):
|
|
34
|
+
# Broker Version >= (2, 3) has incremental alter configs
|
|
35
|
+
try:
|
|
36
|
+
self._manager.broker_version_data.api_version(IncrementalAlterConfigsRequest)
|
|
37
|
+
return True
|
|
38
|
+
except Errors.IncompatibleBrokerVersion:
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def _incremental_configs_entries(configs):
|
|
43
|
+
if not configs:
|
|
44
|
+
return []
|
|
45
|
+
if not isinstance(configs, dict):
|
|
46
|
+
raise TypeError('alter_configs requires configs as a dict of '
|
|
47
|
+
'{key: (op, value)} or {key: value} (interpreted as SET)')
|
|
48
|
+
entries = []
|
|
49
|
+
for name, op_value in configs.items():
|
|
50
|
+
if isinstance(op_value, tuple):
|
|
51
|
+
op, value = op_value
|
|
52
|
+
else:
|
|
53
|
+
op, value = AlterConfigOp.SET, op_value
|
|
54
|
+
op_code = AlterConfigOp.value_for(op)
|
|
55
|
+
if op_code == AlterConfigOp.DELETE.value:
|
|
56
|
+
value = None
|
|
57
|
+
entries.append((name, op_code, value))
|
|
58
|
+
return entries
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def _describe_configs_entries(configs):
|
|
62
|
+
return list(configs.keys()) if isinstance(configs, dict) else configs
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _alter_configs_entries(configs):
|
|
66
|
+
if not configs:
|
|
67
|
+
return []
|
|
68
|
+
elif not isinstance(configs, dict):
|
|
69
|
+
raise TypeError(f'configs should be a dict of {{key: value}}, found {type(configs)}')
|
|
70
|
+
entries = []
|
|
71
|
+
for name, op_value in configs.items():
|
|
72
|
+
if isinstance(op_value, tuple):
|
|
73
|
+
op, value = op_value
|
|
74
|
+
else:
|
|
75
|
+
op, value = AlterConfigOp.SET, op_value
|
|
76
|
+
op_code = AlterConfigOp.value_for(op)
|
|
77
|
+
if op_code != AlterConfigOp.SET.value:
|
|
78
|
+
raise ValueError(f'Non-incremental AlterConfigsRequest does not support operation {op} (SET only)')
|
|
79
|
+
entries.append((name, value))
|
|
80
|
+
return entries
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def _group_config_resources(config_resources):
|
|
84
|
+
broker_resources = defaultdict(list)
|
|
85
|
+
other_resources = []
|
|
86
|
+
for config_resource in config_resources:
|
|
87
|
+
if config_resource.resource_type in (ConfigResourceType.BROKER, ConfigResourceType.BROKER_LOGGER):
|
|
88
|
+
try:
|
|
89
|
+
broker_id = int(config_resource.name)
|
|
90
|
+
except ValueError:
|
|
91
|
+
raise ValueError("Broker resource names must be an integer or a string represented integer")
|
|
92
|
+
broker_resources[broker_id].append(config_resource)
|
|
93
|
+
else:
|
|
94
|
+
other_resources.append(config_resource)
|
|
95
|
+
return broker_resources, other_resources
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def _describe_configs_request(cls, config_resources, include_synonyms=False):
|
|
99
|
+
min_version = 1 if include_synonyms else 0
|
|
100
|
+
return DescribeConfigsRequest(
|
|
101
|
+
resources=[(cr.resource_type, cr.name, cls._describe_configs_entries(cr.configs))
|
|
102
|
+
for cr in config_resources],
|
|
103
|
+
include_synonyms=include_synonyms,
|
|
104
|
+
min_version=min_version)
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def _get_config_source(config, resource_type):
|
|
108
|
+
if 'config_source' in config:
|
|
109
|
+
return ConfigSourceType.build_from(config['config_source'])
|
|
110
|
+
elif config['read_only'] and resource_type is ConfigResourceType.BROKER:
|
|
111
|
+
return ConfigSourceType.STATIC_BROKER_CONFIG
|
|
112
|
+
elif config.get('is_default', False):
|
|
113
|
+
return ConfigSourceType.DEFAULT_CONFIG
|
|
114
|
+
else:
|
|
115
|
+
return ConfigSourceType.dynamic_for_resource_type(resource_type)
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def _should_skip_config(cls, config, config_filter, resource_type):
|
|
119
|
+
if config_filter == ConfigFilterType.DYNAMIC and config['read_only']:
|
|
120
|
+
return True
|
|
121
|
+
config_source = cls._get_config_source(config, resource_type)
|
|
122
|
+
if config_filter.should_skip(config_source):
|
|
123
|
+
return True
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
@classmethod
|
|
127
|
+
def _process_config(cls, config, resource_type):
|
|
128
|
+
name = config.pop('name')
|
|
129
|
+
config_source = cls._get_config_source(config, resource_type)
|
|
130
|
+
config['config_source'] = config_source.name
|
|
131
|
+
if 'synonyms' in config:
|
|
132
|
+
for synonym in config['synonyms']:
|
|
133
|
+
synonym['source'] = ConfigSourceType(synonym['source']).name
|
|
134
|
+
if 'config_type' in config:
|
|
135
|
+
config['config_type'] = ConfigType(config['config_type']).name
|
|
136
|
+
return name
|
|
137
|
+
|
|
138
|
+
@classmethod
|
|
139
|
+
def _describe_configs_process_responses(cls, responses, config_filter='modified'):
|
|
140
|
+
config_filter = ConfigFilterType.build_from(config_filter)
|
|
141
|
+
ret = defaultdict(dict)
|
|
142
|
+
for response in responses:
|
|
143
|
+
for result in response.results:
|
|
144
|
+
resource_type = ConfigResourceType(result.resource_type)
|
|
145
|
+
resource_configs = {}
|
|
146
|
+
for config_struct in result.configs:
|
|
147
|
+
config = config_struct.to_dict()
|
|
148
|
+
name = cls._process_config(config, resource_type)
|
|
149
|
+
if not cls._should_skip_config(config, config_filter, resource_type):
|
|
150
|
+
resource_configs[name] = config
|
|
151
|
+
ret[resource_type.name.lower()][result.resource_name] = resource_configs
|
|
152
|
+
return dict(ret)
|
|
153
|
+
|
|
154
|
+
async def _async_describe_configs(self, config_resources, include_synonyms=False, config_filter='modified', flat=False):
|
|
155
|
+
broker_resources, other_resources = self._group_config_resources(config_resources)
|
|
156
|
+
responses = []
|
|
157
|
+
for broker_id, resources in broker_resources.items():
|
|
158
|
+
request = self._describe_configs_request(resources, include_synonyms)
|
|
159
|
+
responses.append(await self._manager.send(request, node_id=broker_id))
|
|
160
|
+
if other_resources:
|
|
161
|
+
request = self._describe_configs_request(other_resources, include_synonyms)
|
|
162
|
+
responses.append(await self._manager.send(request))
|
|
163
|
+
ret = self._describe_configs_process_responses(responses, config_filter)
|
|
164
|
+
if flat:
|
|
165
|
+
return [ret[resource.resource_type.name.lower()][resource.name]
|
|
166
|
+
for resource in config_resources]
|
|
167
|
+
else:
|
|
168
|
+
return ret
|
|
169
|
+
|
|
170
|
+
def describe_configs(self, config_resources, include_synonyms=False, config_filter='modified'):
|
|
171
|
+
"""Fetch configuration parameters for one or more Kafka resources.
|
|
172
|
+
|
|
173
|
+
Arguments:
|
|
174
|
+
config_resources: An list of ConfigResource objects.
|
|
175
|
+
Any keys in ConfigResource.configs dict will be used to filter the
|
|
176
|
+
result. Setting the configs dict to None will get all values. An
|
|
177
|
+
empty dict will get zero values (as per Kafka protocol).
|
|
178
|
+
|
|
179
|
+
Keyword Arguments:
|
|
180
|
+
include_synonyms (bool, optional): If True, return synonyms in response. Not
|
|
181
|
+
supported by all versions. Default: False.
|
|
182
|
+
config_filter (ConfigFilterType or str): Modified returns only keys that have
|
|
183
|
+
non-default values; Dynamic returns all keys that can be modified with
|
|
184
|
+
alter_configs; All returns all available keys. Default: Modified.
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
dict of {resource_type (str): {resource_name (str): {config_key: {config data}}}}
|
|
188
|
+
"""
|
|
189
|
+
return self._manager.run(self._async_describe_configs, config_resources,
|
|
190
|
+
include_synonyms, config_filter)
|
|
191
|
+
|
|
192
|
+
@staticmethod
|
|
193
|
+
def _list_config_resources_process_response(response):
|
|
194
|
+
error_type = Errors.for_code(response.error_code)
|
|
195
|
+
if error_type is not Errors.NoError:
|
|
196
|
+
raise error_type(
|
|
197
|
+
"ListConfigResourcesRequest failed with response '{}'.".format(response))
|
|
198
|
+
ret = defaultdict(list)
|
|
199
|
+
for resource in response.config_resources:
|
|
200
|
+
resource_type = ConfigResourceType(resource.resource_type)
|
|
201
|
+
ret[resource_type.name.lower()].append(resource.resource_name)
|
|
202
|
+
return dict(ret)
|
|
203
|
+
|
|
204
|
+
async def _async_list_config_resources(self, resource_types=None):
|
|
205
|
+
wire_types = []
|
|
206
|
+
for rt in resource_types or []:
|
|
207
|
+
rt = ConfigResourceType.build_from(rt)
|
|
208
|
+
wire_types.append(rt.value)
|
|
209
|
+
request = ListConfigResourcesRequest(resource_types=wire_types)
|
|
210
|
+
response = await self._manager.send(request)
|
|
211
|
+
return self._list_config_resources_process_response(response)
|
|
212
|
+
|
|
213
|
+
def list_config_resources(self, resource_types=None):
|
|
214
|
+
"""List config resources known to the cluster.
|
|
215
|
+
|
|
216
|
+
Useful for discovering resource types that have no separate enumeration
|
|
217
|
+
API (e.g. ``CLIENT_METRICS``, ``GROUP``). For ``TOPIC`` and ``BROKER``
|
|
218
|
+
the data is also available via ``Metadata`` / cluster descriptions.
|
|
219
|
+
|
|
220
|
+
Keyword Arguments:
|
|
221
|
+
resource_types (list, optional): Filter by resource type. Each entry
|
|
222
|
+
may be a :class:`ConfigResourceType` or its name (e.g. ``'TOPIC'``).
|
|
223
|
+
If None or empty, the broker returns all supported types.
|
|
224
|
+
Requires broker >= 4.1 for anything other than ``CLIENT_METRICS``.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
dict of {resource_type (str): [resource_name (str)]}
|
|
228
|
+
"""
|
|
229
|
+
return self._manager.run(self._async_list_config_resources, resource_types)
|
|
230
|
+
|
|
231
|
+
async def _get_missing_modified_configs(self, config_resources):
|
|
232
|
+
resource_lookups = [ConfigResource(resource.resource_type, resource.name) for resource in config_resources]
|
|
233
|
+
dynamic_configs = await self._async_describe_configs(resource_lookups, config_filter='modified', flat=True)
|
|
234
|
+
missing_resource_configs = []
|
|
235
|
+
for resource, describe in zip(config_resources, dynamic_configs):
|
|
236
|
+
missing = {}
|
|
237
|
+
for config_key in describe:
|
|
238
|
+
if config_key not in resource.configs:
|
|
239
|
+
config_value = describe[config_key]['value']
|
|
240
|
+
if config_value is None:
|
|
241
|
+
continue
|
|
242
|
+
missing[config_key] = config_value
|
|
243
|
+
missing_resource_configs.append(missing)
|
|
244
|
+
return missing_resource_configs
|
|
245
|
+
|
|
246
|
+
async def _add_missing_dynamic_configs(self, config_resources):
|
|
247
|
+
# Add missing modified config values to resource list to avoid accidental resets
|
|
248
|
+
missing_resource_configs = await self._get_missing_modified_configs(config_resources)
|
|
249
|
+
for resource, missing in zip(config_resources, missing_resource_configs):
|
|
250
|
+
if not isinstance(missing, dict):
|
|
251
|
+
raise TypeError(f'missing configs: expected dict, found {type(missing)}')
|
|
252
|
+
resource.configs.update(missing)
|
|
253
|
+
|
|
254
|
+
async def _validate_dynamic_configs(self, config_resources):
|
|
255
|
+
resource_lookups = [ConfigResource(resource.resource_type, resource.name) for resource in config_resources]
|
|
256
|
+
dynamic_configs = await self._async_describe_configs(resource_lookups, config_filter='dynamic', flat=True)
|
|
257
|
+
for resource, describe in zip(config_resources, dynamic_configs):
|
|
258
|
+
unknown = set(resource.configs or []) - set(describe)
|
|
259
|
+
if unknown:
|
|
260
|
+
raise ValueError(f'Unrecognized configs: {unknown}')
|
|
261
|
+
|
|
262
|
+
@classmethod
|
|
263
|
+
def _alter_configs_request(cls, config_resources, validate_only=False, incremental=False):
|
|
264
|
+
if incremental:
|
|
265
|
+
return IncrementalAlterConfigsRequest(
|
|
266
|
+
resources=[(cr.resource_type, cr.name, cls._incremental_configs_entries(cr.configs))
|
|
267
|
+
for cr in config_resources],
|
|
268
|
+
validate_only=validate_only)
|
|
269
|
+
else:
|
|
270
|
+
return AlterConfigsRequest(
|
|
271
|
+
resources=[(cr.resource_type, cr.name, cls._alter_configs_entries(cr.configs))
|
|
272
|
+
for cr in config_resources],
|
|
273
|
+
validate_only=validate_only)
|
|
274
|
+
|
|
275
|
+
@staticmethod
|
|
276
|
+
def _alter_configs_process_responses(responses):
|
|
277
|
+
ret = defaultdict(dict)
|
|
278
|
+
for response in responses:
|
|
279
|
+
if response.error_code == 0:
|
|
280
|
+
result = 'OK'
|
|
281
|
+
else:
|
|
282
|
+
result = str(Errors.for_code(response.error_code)(response.error_message))
|
|
283
|
+
result_type = ConfigResourceType(response.resource_type).name.lower()
|
|
284
|
+
ret[result_type][response.resource_name] = result
|
|
285
|
+
return dict(ret)
|
|
286
|
+
|
|
287
|
+
async def _send_alter_configs_requests(self, config_resources, validate_only=False, incremental=False):
|
|
288
|
+
broker_resources, other_resources = self._group_config_resources(config_resources)
|
|
289
|
+
responses = []
|
|
290
|
+
for broker_id, resources in broker_resources.items():
|
|
291
|
+
request = self._alter_configs_request(resources, validate_only, incremental)
|
|
292
|
+
response = await self._manager.send(request, node_id=broker_id)
|
|
293
|
+
responses.extend(response.responses)
|
|
294
|
+
if other_resources:
|
|
295
|
+
request = self._alter_configs_request(other_resources, validate_only, incremental)
|
|
296
|
+
response = await self._manager.send(request)
|
|
297
|
+
responses.extend(response.responses)
|
|
298
|
+
return self._alter_configs_process_responses(responses)
|
|
299
|
+
|
|
300
|
+
async def _async_alter_configs(self, config_resources, validate_only=False, raise_on_unknown=True, incremental=None):
|
|
301
|
+
if raise_on_unknown:
|
|
302
|
+
await self._validate_dynamic_configs(config_resources)
|
|
303
|
+
if incremental is None:
|
|
304
|
+
incremental = self._check_incremental_alter_configs_support()
|
|
305
|
+
if not incremental:
|
|
306
|
+
await self._add_missing_dynamic_configs(config_resources)
|
|
307
|
+
return await self._send_alter_configs_requests(config_resources, validate_only, incremental)
|
|
308
|
+
|
|
309
|
+
def alter_configs(self, config_resources, validate_only=False, raise_on_unknown=True, incremental=None):
|
|
310
|
+
"""Alter configuration parameters of one or more Kafka resources.
|
|
311
|
+
|
|
312
|
+
Arguments:
|
|
313
|
+
config_resources: A list of ConfigResource objects. Each resource's
|
|
314
|
+
``configs`` must be a dict mapping config key to either
|
|
315
|
+
``(op, value)`` (where ``op`` is an :class:`AlterConfigOp`,
|
|
316
|
+
its name, or its int value) or a bare value (interpreted as SET).
|
|
317
|
+
For DELETE operations the value is ignored and sent as null.
|
|
318
|
+
APPEND/SUBTRACT require broker >= 2.3. On older brokers only
|
|
319
|
+
SET is supported; non-SET ops raise ValueError. On older brokers
|
|
320
|
+
the client also fills in all other modified dynamic keys before
|
|
321
|
+
submitting, since AlterConfigsRequest resets any omitted key to
|
|
322
|
+
its default (be aware of the inherent race in that approach).
|
|
323
|
+
validate_only (bool, optional): If True, changes are sent to broker for
|
|
324
|
+
validation only. Changes will not be applied. Default: False
|
|
325
|
+
raise_on_unknown (bool, optional): If True, raises ValueError if any
|
|
326
|
+
config key is not recognized as a dynamic config for the resource.
|
|
327
|
+
incremental (bool, optional): Set to True/False to force use of
|
|
328
|
+
IncrementalAlterConfigs (True) or AlterConfigs (False).
|
|
329
|
+
By Default, the admin client will use IncrementalAlterConfigs
|
|
330
|
+
if supported by the broker, otherwise AlterConfigs.
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
dict of {resource_type (str): {resource_name (str): Error/Result}}
|
|
334
|
+
"""
|
|
335
|
+
return self._manager.run(self._async_alter_configs, config_resources, validate_only, raise_on_unknown, incremental)
|
|
336
|
+
|
|
337
|
+
async def _async_reset_configs(self, config_resources, validate_only=False, raise_on_unknown=True, incremental=None):
|
|
338
|
+
if raise_on_unknown:
|
|
339
|
+
await self._validate_dynamic_configs(config_resources)
|
|
340
|
+
if incremental is None:
|
|
341
|
+
incremental = self._check_incremental_alter_configs_support()
|
|
342
|
+
|
|
343
|
+
if not incremental:
|
|
344
|
+
# if no keys provided (full reset), submit as-is
|
|
345
|
+
# if keys are provided (partial reset), replace with missing
|
|
346
|
+
partial_resets = [resource for resource in config_resources if resource.configs]
|
|
347
|
+
missing_resource_configs = await self._get_missing_modified_configs(partial_resets)
|
|
348
|
+
for resource, missing in zip(partial_resets, missing_resource_configs):
|
|
349
|
+
resource.configs = missing
|
|
350
|
+
else:
|
|
351
|
+
# if no keys provided (full reset): mark all modified keys as DELETE
|
|
352
|
+
full_resets = [resource for resource in config_resources if not resource.configs]
|
|
353
|
+
missing_resource_configs = await self._get_missing_modified_configs(full_resets)
|
|
354
|
+
for resource, missing in zip(full_resets, missing_resource_configs):
|
|
355
|
+
resource.configs = missing
|
|
356
|
+
# Update all configs to DELETE:None
|
|
357
|
+
for resource in config_resources:
|
|
358
|
+
resource.configs = {key: (AlterConfigOp.DELETE, None)
|
|
359
|
+
for key in resource.configs}
|
|
360
|
+
return await self._send_alter_configs_requests(config_resources, validate_only, incremental)
|
|
361
|
+
|
|
362
|
+
def reset_configs(self, config_resources, validate_only=False, raise_on_unknown=True, incremental=None):
|
|
363
|
+
"""Reset configuration parameters of one or more Kafka resources to defaults.
|
|
364
|
+
|
|
365
|
+
On 2.3+ brokers, the client will submit an IncrementalAlterConfigsRequest
|
|
366
|
+
with op DELETE for each resource/key. On older brokers, the client will
|
|
367
|
+
use submit an AlterConfigsRequest and attempt to include all modified
|
|
368
|
+
dynamic config values for each resource except the keys marked for reset.
|
|
369
|
+
(AlterConfigsRequest will reset any missing config key to its default).
|
|
370
|
+
|
|
371
|
+
Arguments:
|
|
372
|
+
config_resources: A list of ConfigResource objects. Each resource's
|
|
373
|
+
``configs`` should be a list or dict of config keys to reset.
|
|
374
|
+
(if dict, the values are ignored).
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
dict of {resource_type (str): {resource_name (str): Error/Result}}
|
|
378
|
+
"""
|
|
379
|
+
return self._manager.run(self._async_reset_configs, config_resources, validate_only, raise_on_unknown, incremental)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class AlterConfigOp(EnumHelper, IntEnum):
|
|
383
|
+
SET = 0
|
|
384
|
+
DELETE = 1
|
|
385
|
+
APPEND = 2
|
|
386
|
+
SUBTRACT = 3
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
class ConfigFilterType(EnumHelper, IntEnum):
|
|
390
|
+
ALL = 0
|
|
391
|
+
DYNAMIC = 1
|
|
392
|
+
MODIFIED = 2
|
|
393
|
+
DEFAULT = 3
|
|
394
|
+
STATIC = 4
|
|
395
|
+
|
|
396
|
+
def should_skip(self, config_source):
|
|
397
|
+
if self is ConfigFilterType.MODIFIED:
|
|
398
|
+
return not config_source.is_modified()
|
|
399
|
+
elif self is ConfigFilterType.DEFAULT:
|
|
400
|
+
return config_source.is_modified()
|
|
401
|
+
elif self is ConfigFilterType.STATIC:
|
|
402
|
+
return config_source is not ConfigSourceType.STATIC_BROKER_CONFIG
|
|
403
|
+
return False
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
class ConfigResourceType(EnumHelper, IntEnum):
|
|
407
|
+
UNKNOWN = 0
|
|
408
|
+
TOPIC = 2
|
|
409
|
+
BROKER = 4
|
|
410
|
+
BROKER_LOGGER = 8
|
|
411
|
+
CLIENT_METRICS = 16
|
|
412
|
+
GROUP = 32
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
class ConfigResource:
|
|
416
|
+
"""A class for specifying config resources.
|
|
417
|
+
|
|
418
|
+
Arguments:
|
|
419
|
+
resource_type (ConfigResourceType): the type of kafka resource
|
|
420
|
+
name (string): The name of the kafka resource
|
|
421
|
+
configs ([key] or {key : value}): config keys (values required to alter)
|
|
422
|
+
"""
|
|
423
|
+
def __init__(self, resource_type, name, configs=None):
|
|
424
|
+
if not isinstance(resource_type, ConfigResourceType):
|
|
425
|
+
resource_type = ConfigResourceType[str(resource_type).upper()] # pylint: disable-msg=unsubscriptable-object
|
|
426
|
+
self.resource_type = resource_type
|
|
427
|
+
self.name = name
|
|
428
|
+
self.configs = configs
|
|
429
|
+
|
|
430
|
+
def __str__(self):
|
|
431
|
+
return f"ConfigResource {self.name}={self.resource_type}"
|
|
432
|
+
|
|
433
|
+
def __repr__(self):
|
|
434
|
+
return f"ConfigResource({self.resource_type}, {self.name}, {self.configs})"
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
class ConfigType(EnumHelper, IntEnum):
|
|
438
|
+
UNKNOWN = 0
|
|
439
|
+
BOOLEAN = 1
|
|
440
|
+
STRING = 2
|
|
441
|
+
INT = 3
|
|
442
|
+
SHORT = 4
|
|
443
|
+
LONG = 5
|
|
444
|
+
DOUBLE = 6
|
|
445
|
+
LIST = 7
|
|
446
|
+
CLASS = 8
|
|
447
|
+
PASSWORD = 9
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
class ConfigSourceType(EnumHelper, IntEnum):
|
|
451
|
+
UNKNOWN = 0
|
|
452
|
+
DYNAMIC_TOPIC_CONFIG = 1
|
|
453
|
+
DYNAMIC_BROKER_CONFIG = 2
|
|
454
|
+
DYNAMIC_DEFAULT_BROKER_CONFIG = 3
|
|
455
|
+
STATIC_BROKER_CONFIG = 4
|
|
456
|
+
DEFAULT_CONFIG = 5
|
|
457
|
+
DYNAMIC_BROKER_LOGGER_CONFIG = 6
|
|
458
|
+
DYNAMIC_CLIENT_METRICS_CONFIG = 7
|
|
459
|
+
DYNAMIC_GROUP_CONFIG = 8
|
|
460
|
+
|
|
461
|
+
def is_modified(self):
|
|
462
|
+
return self.value not in (3, 4, 5)
|
|
463
|
+
|
|
464
|
+
@classmethod
|
|
465
|
+
def dynamic_for_resource_type(cls, resource_type):
|
|
466
|
+
if resource_type is ConfigResourceType.UNKNOWN:
|
|
467
|
+
return ConfigSourceType.UNKNOWN
|
|
468
|
+
elif resource_type is ConfigResourceType.TOPIC:
|
|
469
|
+
return ConfigSourceType.DYNAMIC_TOPIC_CONFIG
|
|
470
|
+
elif resource_type is ConfigResourceType.BROKER:
|
|
471
|
+
return ConfigSourceType.DYNAMIC_BROKER_CONFIG
|
|
472
|
+
elif resource_type is ConfigResourceType.BROKER_LOGGER:
|
|
473
|
+
return ConfigSourceType.DYNAMIC_BROKER_LOGGER_CONFIG
|
|
474
|
+
elif resource_type is ConfigResourceType.CLIENT_METRICS:
|
|
475
|
+
return ConfigSourceType.DYNAMIC_CLIENT_METRICS_CONFIG
|
|
476
|
+
elif resource_type is ConfigResourceType.GROUP:
|
|
477
|
+
return ConfigSourceType.DYNAMIC_GROUP_CONFIG
|
|
478
|
+
else:
|
|
479
|
+
raise RuntimeError(f'Unrecognized resource type {resource_type}')
|