-
-
Notifications
You must be signed in to change notification settings - Fork 62
fix(clickhouse): honor verify=false in the Rust HTTP writer #8419
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
base: master
Are you sure you want to change the base?
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 |
|---|---|---|
|
|
@@ -305,7 +305,7 @@ def __init__( | |
| database: str, | ||
| secure: bool, | ||
| ca_certs: str | None, | ||
| verify: bool | None, | ||
| verify: bool | str | None, | ||
|
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. why do we need this to also be a |
||
| storage_sets: set[str], | ||
| single_node: bool, | ||
| # The cluster name and distributed cluster name only apply if single_node is set to False | ||
|
|
@@ -371,7 +371,7 @@ def get_node_connection( | |
| self.__database, | ||
| self.__secure, | ||
| self.__ca_certs, | ||
| self.__verify, | ||
| self.get_verify(), | ||
| ) | ||
|
|
||
| def get_deleter(self) -> Reader: | ||
|
|
@@ -418,7 +418,7 @@ def get_batch_writer( | |
| password=self.__password, | ||
| secure=self.__secure, | ||
| ca_certs=self.__ca_certs, | ||
| verify=self.__verify, | ||
| verify=self.get_verify(), | ||
| metrics=metrics, | ||
| statement=insert_statement.with_database(self.__database), | ||
| encoding=encoding, | ||
|
|
@@ -504,7 +504,12 @@ def get_ca_certs(self) -> str | None: | |
| return self.__ca_certs | ||
|
|
||
| def get_verify(self) -> bool | None: | ||
| return self.__verify | ||
| # CLICKHOUSE_VERIFY arrives as a raw env string; coerce once here so | ||
| # every client sees the same value. Unset (None) stays None. | ||
| verify = self.__verify | ||
| if isinstance(verify, str): | ||
| return verify.strip().lower() not in ("false", "0") | ||
| return verify | ||
|
Comment on lines
+510
to
+512
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 really would MUCH prefer if
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. Yeah, this is better. Coerce once in |
||
|
|
||
|
|
||
| CLUSTERS = [ | ||
|
|
@@ -517,7 +522,7 @@ def get_verify(self) -> bool | None: | |
| database=cluster.get("database", "default"), | ||
| secure=cluster.get("secure", False), | ||
| ca_certs=cluster.get("ca_certs", None), | ||
| verify=cluster.get("verify", False), | ||
| verify=cluster.get("verify"), | ||
|
pbhandari marked this conversation as resolved.
|
||
| storage_sets=cluster["storage_sets"], | ||
| single_node=cluster["single_node"], | ||
| cluster_name=cluster.get("cluster_name", None), | ||
|
|
@@ -558,7 +563,7 @@ def _build_sliced_cluster(cluster: Mapping[str, Any]) -> ClickhouseCluster: | |
| database=cluster.get("database", "default"), | ||
| secure=cluster.get("secure", False), | ||
| ca_certs=cluster.get("ca_certs", None), | ||
| verify=cluster.get("verify", False), | ||
| verify=cluster.get("verify"), | ||
|
pbhandari marked this conversation as resolved.
|
||
| storage_sets={storage_tuple[0] for storage_tuple in cluster["storage_set_slices"]}, | ||
| single_node=cluster["single_node"], | ||
| cluster_name=cluster.get("cluster_name", None), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import pytest | ||
|
|
||
| from snuba.clusters.cluster import ClickhouseCluster | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "raw,expected", | ||
| [ | ||
| (None, None), | ||
| (True, True), | ||
| (False, False), | ||
| ("true", True), | ||
| ("1", True), | ||
| ("false", False), | ||
| ("FALSE", False), | ||
| ("0", False), | ||
| (" false ", False), | ||
| ("", True), | ||
| ("yes", True), | ||
| ("garbage", True), | ||
| ], | ||
| ) | ||
| def test_get_verify_coercion(raw: bool | str | None, expected: bool | None) -> None: | ||
| cluster = ClickhouseCluster( | ||
| "127.0.0.1", | ||
| 8001, | ||
| "default", | ||
| "", | ||
| "default", | ||
| True, | ||
| None, | ||
| raw, | ||
| {"events"}, | ||
| True, | ||
| ) | ||
|
|
||
| assert cluster.get_verify() == expected |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| import dataclasses | ||
|
|
||
| import pytest | ||
|
|
||
| from snuba.consumers.consumer_config import resolve_consumer_config | ||
| from snuba.consumers.consumer_config import resolve_consumer_config, resolve_storage_config | ||
| from snuba.datasets.storages.factory import get_writable_storage | ||
| from snuba.datasets.storages.storage_key import StorageKey | ||
|
|
||
|
|
||
| def test_consumer_config() -> None: | ||
|
|
@@ -19,6 +23,7 @@ def test_consumer_config() -> None: | |
|
|
||
| assert len(resolved.storages) == 1 | ||
| assert resolved.storages[0].clickhouse_table_name in ("errors_local", "errors_dist") | ||
| assert resolved.storages[0].clickhouse_cluster.verify is None | ||
|
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. This is just the default. Doesn't show that an explicit
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. Added |
||
| assert resolved.raw_topic.broker_config["bootstrap.servers"] == "some_server:9092" | ||
| assert resolved.raw_topic.physical_topic_name == "new-events" | ||
| assert resolved.raw_topic.logical_topic_name == "events" | ||
|
|
@@ -48,6 +53,18 @@ def test_consumer_config() -> None: | |
| ) | ||
|
|
||
|
|
||
| def test_resolve_storage_config_propagates_verify_false( | ||
| monkeypatch: pytest.MonkeyPatch, | ||
| ) -> None: | ||
| storage = get_writable_storage(StorageKey.ERRORS) | ||
| monkeypatch.setattr(storage.get_cluster(), "get_verify", lambda: False) | ||
|
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. This feels needlessly brittle. Is it possible to test this without monkeypatching? |
||
|
|
||
| resolved = resolve_storage_config("errors", storage) | ||
|
|
||
| assert resolved.clickhouse_cluster.verify is False | ||
| assert dataclasses.asdict(resolved)["clickhouse_cluster"]["verify"] is False | ||
|
Comment on lines
+64
to
+65
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. why do we need both these asserts?
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. The |
||
|
|
||
|
|
||
| def test_group_instance_id_in_broker_config() -> None: | ||
| """Static membership: --group-instance-id lands in librdkafka broker config.""" | ||
| resolved = resolve_consumer_config( | ||
|
|
||
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.
This is the bit that actually matters and it isn't tested — the config.rs tests only check serde.
tls_danger_accept_invalid_hostnamesis also a bigger hammer than "accept my private CA". It matches Python'sCERT_NONE, so I'm not asking you to drop it, but the comment should say we disable hostname checks too, not just an untrusted issuer.A warn log here would be good.
Uh oh!
There was an error while loading. Please reload this page.
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.
Done. The condition is now a
tls_verification_disabledhelper with a matrix test covering all foursecure/verifycombinations, the comment calls out that hostname checks are disabled too, and there's atracing::warnwhen verification is off.