diff --git a/programs/server/config.xml b/programs/server/config.xml
index f55ab02d903..fb2f9be6e24 100644
--- a/programs/server/config.xml
+++ b/programs/server/config.xml
@@ -37,7 +37,7 @@
true
-
+
true
true
sslv2,sslv3
diff --git a/src/Common/ZooKeeper/CMakeLists.txt b/src/Common/ZooKeeper/CMakeLists.txt
index aa6efcd3ca1..4dbf999419e 100644
--- a/src/Common/ZooKeeper/CMakeLists.txt
+++ b/src/Common/ZooKeeper/CMakeLists.txt
@@ -7,6 +7,10 @@ add_library(clickhouse_common_zookeeper ${clickhouse_common_zookeeper_headers} $
target_link_libraries (clickhouse_common_zookeeper PUBLIC clickhouse_common_io common PRIVATE string_utils PUBLIC ${Poco_Util_LIBRARY})
target_include_directories(clickhouse_common_zookeeper PUBLIC ${DBMS_INCLUDE_DIR})
+if (USE_POCO_NETSSL)
+ target_link_libraries (clickhouse_common_zookeeper PRIVATE ${Poco_NetSSL_LIBRARY} ${Poco_Crypto_LIBRARY})
+endif()
+
if (ENABLE_TESTS)
add_subdirectory (tests)
endif ()
diff --git a/src/Common/ZooKeeper/ZooKeeper.cpp b/src/Common/ZooKeeper/ZooKeeper.cpp
index 99c3f115021..f2442f3f5c5 100644
--- a/src/Common/ZooKeeper/ZooKeeper.cpp
+++ b/src/Common/ZooKeeper/ZooKeeper.cpp
@@ -59,30 +59,36 @@ void ZooKeeper::init(const std::string & implementation_, const std::string & ho
if (implementation == "zookeeper")
{
if (hosts.empty())
- throw KeeperException("No addresses passed to ZooKeeper constructor.", Coordination::ZBADARGUMENTS);
+ throw KeeperException("No hosts passed to ZooKeeper constructor.", Coordination::ZBADARGUMENTS);
- std::vector addresses_strings;
- splitInto<','>(addresses_strings, hosts);
- Coordination::ZooKeeper::Addresses addresses;
- addresses.reserve(addresses_strings.size());
+ std::vector hosts_strings;
+ splitInto<','>(hosts_strings, hosts);
+ Coordination::ZooKeeper::Nodes nodes;
+ nodes.reserve(hosts_strings.size());
- for (const auto & address_string : addresses_strings)
+ for (auto & host_string : hosts_strings)
{
try
{
- addresses.emplace_back(address_string);
+ bool secure = bool(startsWith(host_string, "secure://"));
+
+ if (secure) {
+ host_string.erase(0, strlen("secure://"));
+ }
+
+ nodes.emplace_back(Coordination::ZooKeeper::Node{Poco::Net::SocketAddress{host_string}, secure});
}
catch (const Poco::Net::DNSException & e)
{
- LOG_ERROR(log, "Cannot use ZooKeeper address " << address_string << ", reason: " << e.displayText());
+ LOG_ERROR(log, "Cannot use ZooKeeper host " << host_string << ", reason: " << e.displayText());
}
}
- if (addresses.empty())
- throw KeeperException("Cannot use any of provided ZooKeeper addresses", Coordination::ZBADARGUMENTS);
+ if (nodes.empty())
+ throw KeeperException("Cannot use any of provided ZooKeeper nodes", Coordination::ZBADARGUMENTS);
impl = std::make_unique(
- addresses,
+ nodes,
chroot,
identity_.empty() ? "" : "digest",
identity_,
@@ -130,6 +136,7 @@ struct ZooKeeperArgs
if (startsWith(key, "node"))
{
hosts_strings.push_back(
+ (config.getBool(config_name + "." + key + ".secure", false) ? "secure://" : "") +
config.getString(config_name + "." + key + ".host") + ":"
+ config.getString(config_name + "." + key + ".port", "2181")
);
diff --git a/src/Common/ZooKeeper/ZooKeeper.h b/src/Common/ZooKeeper/ZooKeeper.h
index 2d4d449b1a6..db166314a07 100644
--- a/src/Common/ZooKeeper/ZooKeeper.h
+++ b/src/Common/ZooKeeper/ZooKeeper.h
@@ -63,10 +63,14 @@ public:
example1
2181
+
+ 1
example2
2181
+
+ 1
30000
10000
diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.cpp b/src/Common/ZooKeeper/ZooKeeperImpl.cpp
index b8700a93e35..2fba10b20e9 100644
--- a/src/Common/ZooKeeper/ZooKeeperImpl.cpp
+++ b/src/Common/ZooKeeper/ZooKeeperImpl.cpp
@@ -11,6 +11,11 @@
#include
#include
+#include
+#if USE_POCO_NETSSL
+#include
+#endif
+
#include
@@ -44,6 +49,13 @@ namespace CurrentMetrics
extern const Metric ZooKeeperWatch;
}
+namespace DB
+{
+ namespace ErrorCodes
+ {
+ extern const int SUPPORT_IS_DISABLED;
+ }
+}
/** ZooKeeper wire protocol.
@@ -817,7 +829,7 @@ ZooKeeper::~ZooKeeper()
ZooKeeper::ZooKeeper(
- const Addresses & addresses,
+ const Nodes & nodes,
const String & root_path_,
const String & auth_scheme,
const String & auth_data,
@@ -851,7 +863,7 @@ ZooKeeper::ZooKeeper(
default_acls.emplace_back(std::move(acl));
}
- connect(addresses, connection_timeout);
+ connect(nodes, connection_timeout);
if (!auth_scheme.empty())
sendAuth(auth_scheme, auth_data);
@@ -864,11 +876,11 @@ ZooKeeper::ZooKeeper(
void ZooKeeper::connect(
- const Addresses & addresses,
+ const Nodes & nodes,
Poco::Timespan connection_timeout)
{
- if (addresses.empty())
- throw Exception("No addresses passed to ZooKeeper constructor", ZBADARGUMENTS);
+ if (nodes.empty())
+ throw Exception("No nodes passed to ZooKeeper constructor", ZBADARGUMENTS);
static constexpr size_t num_tries = 3;
bool connected = false;
@@ -876,12 +888,25 @@ void ZooKeeper::connect(
WriteBufferFromOwnString fail_reasons;
for (size_t try_no = 0; try_no < num_tries; ++try_no)
{
- for (const auto & address : addresses)
+ for (const auto & node : nodes)
{
try
{
- socket = Poco::Net::StreamSocket(); /// Reset the state of previous attempt.
- socket.connect(address, connection_timeout);
+ /// Reset the state of previous attempt.
+ if (node.secure)
+ {
+#if USE_POCO_NETSSL
+ socket = Poco::Net::SecureStreamSocket();
+#else
+ throw Exception{"Communication with ZooKeeper over SSL is disabled because poco library was built without NetSSL support.", ErrorCodes::SUPPORT_IS_DISABLED};
+#endif
+ }
+ else
+ {
+ socket = Poco::Net::StreamSocket();
+ }
+
+ socket.connect(node.address, connection_timeout);
socket.setReceiveTimeout(operation_timeout);
socket.setSendTimeout(operation_timeout);
@@ -915,7 +940,7 @@ void ZooKeeper::connect(
}
catch (...)
{
- fail_reasons << "\n" << getCurrentExceptionMessage(false) << ", " << address.toString();
+ fail_reasons << "\n" << getCurrentExceptionMessage(false) << ", " << node.address.toString();
}
}
@@ -926,15 +951,19 @@ void ZooKeeper::connect(
if (!connected)
{
WriteBufferFromOwnString message;
- message << "All connection tries failed while connecting to ZooKeeper. Addresses: ";
+ message << "All connection tries failed while connecting to ZooKeeper. nodes: ";
bool first = true;
- for (const auto & address : addresses)
+ for (const auto & node : nodes)
{
if (first)
first = false;
else
message << ", ";
- message << address.toString();
+
+ if (node.secure)
+ message << "secure://";
+
+ message << node.address.toString();
}
message << fail_reasons.str() << "\n";
diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.h b/src/Common/ZooKeeper/ZooKeeperImpl.h
index 88e949dbd45..069df723d43 100644
--- a/src/Common/ZooKeeper/ZooKeeperImpl.h
+++ b/src/Common/ZooKeeper/ZooKeeperImpl.h
@@ -93,17 +93,22 @@ struct ZooKeeperRequest;
class ZooKeeper : public IKeeper
{
public:
- using Addresses = std::vector;
+ struct Node {
+ Poco::Net::SocketAddress address;
+ bool secure;
+ };
+
+ using Nodes = std::vector;
using XID = int32_t;
using OpNum = int32_t;
- /** Connection to addresses is performed in order. If you want, shuffle them manually.
+ /** Connection to nodes is performed in order. If you want, shuffle them manually.
* Operation timeout couldn't be greater than session timeout.
* Operation timeout applies independently for network read, network write, waiting for events and synchronization.
*/
ZooKeeper(
- const Addresses & addresses,
+ const Nodes & nodes,
const String & root_path,
const String & auth_scheme,
const String & auth_data,
@@ -213,7 +218,7 @@ private:
ThreadFromGlobalPool receive_thread;
void connect(
- const Addresses & addresses,
+ const Nodes & node,
Poco::Timespan connection_timeout);
void sendHandshake();
diff --git a/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp b/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp
index aa348163adf..0bca8e0f561 100644
--- a/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp
+++ b/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -23,15 +24,23 @@ try
Poco::Logger::root().setChannel(channel);
Poco::Logger::root().setLevel("trace");
- std::string addresses_arg = argv[1];
- std::vector addresses_strings;
- splitInto<','>(addresses_strings, addresses_arg);
- ZooKeeper::Addresses addresses;
- addresses.reserve(addresses_strings.size());
- for (const auto & address_string : addresses_strings)
- addresses.emplace_back(address_string);
+ std::string hosts_arg = argv[1];
+ std::vector hosts_strings;
+ splitInto<','>(hosts_strings, hosts_arg);
+ ZooKeeper::Nodes nodes;
+ nodes.reserve(hosts_strings.size());
+ for (auto & host_string : hosts_strings) {
+ bool secure = bool(startsWith(host_string, "secure://"));
- ZooKeeper zk(addresses, {}, {}, {}, {5, 0}, {0, 50000}, {0, 50000});
+ if (secure) {
+ host_string.erase(0, strlen("secure://"));
+ }
+
+ nodes.emplace_back(ZooKeeper::Node{Poco::Net::SocketAddress{host_string},secure});
+ }
+
+
+ ZooKeeper zk(nodes, {}, {}, {}, {5, 0}, {0, 50000}, {0, 50000});
Poco::Event event(true);
diff --git a/src/Common/ZooKeeper/tests/zookeeper_impl.cpp b/src/Common/ZooKeeper/tests/zookeeper_impl.cpp
index da609a7bc72..74ba63514f2 100644
--- a/src/Common/ZooKeeper/tests/zookeeper_impl.cpp
+++ b/src/Common/ZooKeeper/tests/zookeeper_impl.cpp
@@ -5,7 +5,7 @@
int main()
try
{
- Coordination::ZooKeeper zookeeper({Poco::Net::SocketAddress{"localhost:2181"}}, "", "", "", {30, 0}, {0, 50000}, {0, 50000});
+ Coordination::ZooKeeper zookeeper({Coordination::ZooKeeper::Node{Poco::Net::SocketAddress{"localhost:2181"}, false}}, "", "", "", {30, 0}, {0, 50000}, {0, 50000});
zookeeper.create("/test", "hello", false, false, {}, [](const Coordination::CreateResponse & response)
{
diff --git a/tests/integration/test_config_corresponding_root/configs/config.xml b/tests/integration/test_config_corresponding_root/configs/config.xml
index 154ebf6c35e..4e130afa84d 100644
--- a/tests/integration/test_config_corresponding_root/configs/config.xml
+++ b/tests/integration/test_config_corresponding_root/configs/config.xml
@@ -37,7 +37,7 @@
true
-
+
true
true
sslv2,sslv3
diff --git a/tests/server-test.xml b/tests/server-test.xml
index c2356ec1ba0..7f792479065 100644
--- a/tests/server-test.xml
+++ b/tests/server-test.xml
@@ -31,7 +31,7 @@
true
-
+
true
true
sslv2,sslv3