-
Notifications
You must be signed in to change notification settings - Fork 15.2k
KAFKA-2693: Ducktape tests for SASL/PLAIN and multiple mechanisms #1282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,7 +75,9 @@ class SecurityConfig(TemplateRenderer): | |
|
|
||
| ssl_stores = Keytool.generate_keystore_truststore('.') | ||
|
|
||
| def __init__(self, security_protocol=None, interbroker_security_protocol=None, sasl_mechanism=SASL_MECHANISM_GSSAPI, zk_sasl=False, template_props=""): | ||
| def __init__(self, security_protocol=None, interbroker_security_protocol=None, | ||
| client_sasl_mechanism=SASL_MECHANISM_GSSAPI, interbroker_sasl_mechanism=SASL_MECHANISM_GSSAPI, | ||
| zk_sasl=False, template_props=""): | ||
| """ | ||
| Initialize the security properties for the node and copy | ||
| keystore and truststore to the remote node if the transport protocol | ||
|
|
@@ -104,13 +106,14 @@ def __init__(self, security_protocol=None, interbroker_security_protocol=None, s | |
| 'ssl.key.password' : SecurityConfig.ssl_stores['ssl.key.password'], | ||
| 'ssl.truststore.location' : SecurityConfig.TRUSTSTORE_PATH, | ||
| 'ssl.truststore.password' : SecurityConfig.ssl_stores['ssl.truststore.password'], | ||
| 'sasl.mechanism' : sasl_mechanism, | ||
| 'sasl.mechanism' : client_sasl_mechanism, | ||
| 'sasl.mechanism.inter.broker.protocol' : interbroker_sasl_mechanism, | ||
| 'sasl.kerberos.service.name' : 'kafka' | ||
| } | ||
|
|
||
|
|
||
| def client_config(self, template_props=""): | ||
| return SecurityConfig(self.security_protocol, sasl_mechanism=self.sasl_mechanism, template_props=template_props) | ||
| return SecurityConfig(self.security_protocol, client_sasl_mechanism=self.client_sasl_mechanism, template_props=template_props) | ||
|
|
||
| def setup_node(self, node): | ||
| if self.has_ssl: | ||
|
|
@@ -120,13 +123,15 @@ def setup_node(self, node): | |
|
|
||
| if self.has_sasl: | ||
| node.account.ssh("mkdir -p %s" % SecurityConfig.CONFIG_DIR, allow_fail=False) | ||
| jaas_conf_file = self.sasl_mechanism.lower() + "_jaas.conf" | ||
| jaas_conf_file = "jaas.conf" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason this changed? I'm not sure its an issue, but it seems like we may have named the file with the SASL mechanism previously to at least aid in debugging.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ewencp Thank you for the review. Since we now support multiple SASL mechanisms in a broker, we need to have a jaas config file that includes all the supported mechanisms. Hence I modified jaas.conf to include sections based on the enabled mechanisms, rather than have one config file per mechanism. I removed the mechanism name from the file since it is no longer associated with a single mechanism.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, that makes sense. |
||
| java_version = node.account.ssh_capture("java -version") | ||
| if any('IBM' in line for line in java_version): | ||
| is_ibm_jdk = True | ||
| else: | ||
| is_ibm_jdk = False | ||
| jaas_conf = self.render(jaas_conf_file, node=node, is_ibm_jdk=is_ibm_jdk) | ||
| jaas_conf = self.render(jaas_conf_file, node=node, is_ibm_jdk=is_ibm_jdk, | ||
| client_sasl_mechanism=self.client_sasl_mechanism, | ||
| enabled_sasl_mechanisms=self.enabled_sasl_mechanisms) | ||
| node.account.create_file(SecurityConfig.JAAS_CONF_PATH, jaas_conf) | ||
| if self.has_sasl_kerberos: | ||
| node.account.scp_to(MiniKdc.LOCAL_KEYTAB_FILE, SecurityConfig.KEYTAB_PATH) | ||
|
|
@@ -159,12 +164,20 @@ def security_protocol(self): | |
| return self.properties['security.protocol'] | ||
|
|
||
| @property | ||
| def sasl_mechanism(self): | ||
| def client_sasl_mechanism(self): | ||
| return self.properties['sasl.mechanism'] | ||
|
|
||
| @property | ||
| def interbroker_sasl_mechanism(self): | ||
| return self.properties['sasl.mechanism.inter.broker.protocol'] | ||
|
|
||
| @property | ||
| def enabled_sasl_mechanisms(self): | ||
| return set([self.client_sasl_mechanism, self.interbroker_sasl_mechanism]) | ||
|
|
||
| @property | ||
| def has_sasl_kerberos(self): | ||
| return self.has_sasl and self.sasl_mechanism == SecurityConfig.SASL_MECHANISM_GSSAPI | ||
| return self.has_sasl and (SecurityConfig.SASL_MECHANISM_GSSAPI in self.enabled_sasl_mechanisms) | ||
|
|
||
| @property | ||
| def kafka_opts(self): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -128,7 +128,10 @@ def min_cluster_size(self): | |
| @matrix(failure_mode=["clean_shutdown", "hard_shutdown", "clean_bounce", "hard_bounce"], | ||
| broker_type=["controller"], | ||
| security_protocol=["PLAINTEXT", "SASL_SSL"]) | ||
| def test_replication_with_broker_failure(self, failure_mode, security_protocol, broker_type): | ||
| @matrix(failure_mode=["hard_bounce"], | ||
| broker_type=["leader"], | ||
| security_protocol=["SASL_SSL"], client_sasl_mechanism=["PLAIN"], interbroker_sasl_mechanism=["PLAIN", "GSSAPI"]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need GSSAPI for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ijuma This tests (client=PLAIN, interbroker=PLAIN) and (client=PLAIN, interbroker=GSSAPI). The first tests a broker with just PLAIN and the second tests a broker with multiple mechanisms.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because these tests take a while to run, maybe we should just have the multiple mechanisms case. What do you think @ewencp?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ijuma The second case (multiple mechanisms) uses GSSAPI for interbroker communication. That leaves no tests with PLAIN for inter-broker (sanity test runs only one broker, so that doesn't test as much as this one).
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rajinisivaram Do we need to cover all the cases here, though? Replication tests are pretty heavyweight. If we just want sanity checks on different protocol settings, we could also try to get coverage via other, cheaper tests? I'm fine with the additional tests if we need them to get coverage, I just want to make sure we don't keep increasing the number of variants of expensive tests.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ewencp I dont actually know the answer. I chose one sanity test with a single broker (consumer test) and the replication tests because they restart brokers making them useful for testing authentication. I chose two types (PLAIN, multi-mechanism) and two types of tests (
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ewencp Reduced to running just |
||
| def test_replication_with_broker_failure(self, failure_mode, security_protocol, broker_type, client_sasl_mechanism="GSSAPI", interbroker_sasl_mechanism="GSSAPI"): | ||
| """Replication tests. | ||
| These tests verify that replication provides simple durability guarantees by checking that data acked by | ||
| brokers is still available for consumption in the face of various failure scenarios. | ||
|
|
@@ -144,6 +147,8 @@ def test_replication_with_broker_failure(self, failure_mode, security_protocol, | |
|
|
||
| self.kafka.security_protocol = security_protocol | ||
| self.kafka.interbroker_security_protocol = security_protocol | ||
| self.kafka.client_sasl_mechanism = client_sasl_mechanism | ||
| self.kafka.interbroker_sasl_mechanism = interbroker_sasl_mechanism | ||
| new_consumer = False if self.kafka.security_protocol == "PLAINTEXT" else True | ||
| self.producer = VerifiableProducer(self.test_context, self.num_producers, self.kafka, self.topic, throughput=self.producer_throughput) | ||
| self.consumer = ConsoleConsumer(self.test_context, self.num_consumers, self.kafka, self.topic, new_consumer=new_consumer, consumer_timeout_ms=60000, message_validator=is_int) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to also update
test_console_producer.py?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijuma I thought it is useful to have one sanity test with SASL/PLAIN that is simple to run, hence added a consumer test. Since the replication tests run both producer and consumer anyway, perhaps this is sufficient?
test_verifiable_producer.pyis currently run only with PLAINTEXT.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds fine to me.