mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 02:21:59 +00:00
Merge pull request #45715 from azat/client-connections-credentials
Add ability to override connection settings based on connection names
This commit is contained in:
commit
c4a95f62ef
@ -127,6 +127,69 @@ void Client::showWarnings()
|
||||
}
|
||||
}
|
||||
|
||||
void Client::parseConnectionsCredentials()
|
||||
{
|
||||
/// It is not possible to correctly handle multiple --host --port options.
|
||||
if (hosts_and_ports.size() >= 2)
|
||||
return;
|
||||
|
||||
String host;
|
||||
std::optional<UInt16> port;
|
||||
if (hosts_and_ports.empty())
|
||||
{
|
||||
host = config().getString("host", "localhost");
|
||||
if (config().has("port"))
|
||||
port = config().getInt("port");
|
||||
}
|
||||
else
|
||||
{
|
||||
host = hosts_and_ports.front().host;
|
||||
port = hosts_and_ports.front().port;
|
||||
}
|
||||
|
||||
Strings keys;
|
||||
config().keys("connections_credentials", keys);
|
||||
for (const auto & connection : keys)
|
||||
{
|
||||
const String & prefix = "connections_credentials." + connection;
|
||||
|
||||
const String & connection_name = config().getString(prefix + ".name", "");
|
||||
if (connection_name != host)
|
||||
continue;
|
||||
|
||||
String connection_hostname;
|
||||
if (config().has(prefix + ".hostname"))
|
||||
connection_hostname = config().getString(prefix + ".hostname");
|
||||
else
|
||||
connection_hostname = connection_name;
|
||||
|
||||
/// Set "host" unconditionally (since it is used as a "name"), while
|
||||
/// other options only if they are not set yet (config.xml/cli
|
||||
/// options).
|
||||
config().setString("host", connection_hostname);
|
||||
if (!hosts_and_ports.empty())
|
||||
hosts_and_ports.front().host = connection_hostname;
|
||||
|
||||
if (config().has(prefix + ".port") && !port.has_value())
|
||||
config().setInt("port", config().getInt(prefix + ".port"));
|
||||
if (config().has(prefix + ".secure") && !config().has("secure"))
|
||||
config().setBool("secure", config().getBool(prefix + ".secure"));
|
||||
if (config().has(prefix + ".user") && !config().has("user"))
|
||||
config().setString("user", config().getString(prefix + ".user"));
|
||||
if (config().has(prefix + ".password") && !config().has("password"))
|
||||
config().setString("password", config().getString(prefix + ".password"));
|
||||
if (config().has(prefix + ".database") && !config().has("database"))
|
||||
config().setString("database", config().getString(prefix + ".database"));
|
||||
if (config().has(prefix + ".history_file") && !config().has("history_file"))
|
||||
{
|
||||
String history_file = config().getString(prefix + ".history_file");
|
||||
if (history_file.starts_with("~") && !home_path.empty())
|
||||
history_file = home_path + "/" + history_file.substr(1);
|
||||
config().setString("history_file", history_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Make query to get all server warnings
|
||||
std::vector<String> Client::loadWarningMessages()
|
||||
{
|
||||
@ -216,6 +279,8 @@ void Client::initialize(Poco::Util::Application & self)
|
||||
if (env_password)
|
||||
config().setString("password", env_password);
|
||||
|
||||
parseConnectionsCredentials();
|
||||
|
||||
// global_context->setApplicationType(Context::ApplicationType::CLIENT);
|
||||
global_context->setQueryParameters(query_parameters);
|
||||
|
||||
|
@ -47,6 +47,7 @@ protected:
|
||||
private:
|
||||
void printChangedSettings() const;
|
||||
void showWarnings();
|
||||
void parseConnectionsCredentials();
|
||||
std::vector<String> loadWarningMessages();
|
||||
};
|
||||
}
|
||||
|
@ -57,4 +57,28 @@
|
||||
|
||||
The same can be done on user-level configuration, just create & adjust: ~/.clickhouse-client/config.xml
|
||||
-->
|
||||
|
||||
|
||||
<!-- Analog of .netrc -->
|
||||
<![CDATA[
|
||||
<connections_credentials>
|
||||
<connection>
|
||||
<!-- Name of the connection, host option for the client.
|
||||
"host" is not the same as "hostname" since you may want to have different settings for one host,
|
||||
and in this case you can add "prod" and "prod_readonly".
|
||||
|
||||
Default: "hostname" will be used. -->
|
||||
<name>default</name>
|
||||
<!-- Host that will be used for connection. -->
|
||||
<hostname>127.0.0.1</hostname>
|
||||
<port>9000</port>
|
||||
<secure>1</secure>
|
||||
<user>default</user>
|
||||
<password></password>
|
||||
<database></database>
|
||||
<!-- '~' is expanded to HOME, like in any shell -->
|
||||
<history_file></history_file>
|
||||
</connection>
|
||||
</connections_credentials>
|
||||
]]>
|
||||
</config>
|
||||
|
@ -0,0 +1,17 @@
|
||||
hostname
|
||||
Not found address of host: MySQL.
|
||||
port
|
||||
Connection refused (localhost:0).
|
||||
9000
|
||||
secure
|
||||
1
|
||||
database
|
||||
system
|
||||
user
|
||||
MySQL: Authentication failed
|
||||
default
|
||||
password
|
||||
default: Authentication failed: password is incorrect, or there is no user with such name.
|
||||
default
|
||||
history_file
|
||||
Cannot create file: /no/such/dir/.history
|
86
tests/queries/0_stateless/02550_client_connections_credentials.sh
Executable file
86
tests/queries/0_stateless/02550_client_connections_credentials.sh
Executable file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
|
||||
# Overrides
|
||||
TEST_DATABASE=$CLICKHOUSE_DATABASE
|
||||
TEST_HOST=${CLICKHOUSE_HOST:-"localhost"}
|
||||
TEST_PORT=${CLICKHOUSE_PORT_TCP:-9000}
|
||||
CLICKHOUSE_DATABASE="system"
|
||||
CLICKHOUSE_HOST=""
|
||||
CLICKHOUSE_PORT_TCP=""
|
||||
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
CONFIG=$CLICKHOUSE_TMP/client.xml
|
||||
cat > $CONFIG <<EOL
|
||||
<clickhouse>
|
||||
<host>$TEST_HOST</host>
|
||||
<port>$TEST_PORT</port>
|
||||
<database>$TEST_DATABASE</database>
|
||||
|
||||
<connections_credentials>
|
||||
<connection>
|
||||
<name>test_hostname</name>
|
||||
<hostname>MySQL</hostname>
|
||||
</connection>
|
||||
|
||||
<connection>
|
||||
<name>test_port</name>
|
||||
<hostname>$TEST_HOST</hostname>
|
||||
<port>0</port>
|
||||
</connection>
|
||||
|
||||
<connection>
|
||||
<name>test_secure</name>
|
||||
<hostname>$TEST_HOST</hostname>
|
||||
<secure>1</secure>
|
||||
</connection>
|
||||
|
||||
<connection>
|
||||
<name>test_database</name>
|
||||
<hostname>$TEST_HOST</hostname>
|
||||
<database>$CLICKHOUSE_DATABASE</database>
|
||||
</connection>
|
||||
|
||||
<connection>
|
||||
<name>test_user</name>
|
||||
<hostname>$TEST_HOST</hostname>
|
||||
<user>MySQL</user>
|
||||
</connection>
|
||||
|
||||
<connection>
|
||||
<name>test_password</name>
|
||||
<hostname>$TEST_HOST</hostname>
|
||||
<password>MySQL</password>
|
||||
</connection>
|
||||
|
||||
<connection>
|
||||
<name>test_history_file</name>
|
||||
<hostname>$TEST_HOST</hostname>
|
||||
<history_file>/no/such/dir/.history</history_file>
|
||||
</connection>
|
||||
</connections_credentials>
|
||||
</clickhouse>
|
||||
EOL
|
||||
|
||||
echo 'hostname'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_hostname -q 'select 1' |& grep -F -o 'Not found address of host: MySQL.'
|
||||
echo 'port'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_port -q 'select tcpPort()' |& grep -F -o 'Connection refused (localhost:0).'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_port --port $TEST_PORT -q 'select tcpPort()'
|
||||
echo 'secure'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_secure -q 'select tcpPort()' |& grep -c -F -o -e OPENSSL_internal:WRONG_VERSION_NUMBER -e 'tcp_secure protocol is disabled because poco library was built without NetSSL support.'
|
||||
echo 'database'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_database -q 'select currentDatabase()'
|
||||
echo 'user'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_user -q 'select currentUser()' |& grep -F -o 'MySQL: Authentication failed'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_user --user default -q 'select currentUser()'
|
||||
echo 'password'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_password -q 'select currentUser()' |& grep -F -o 'default: Authentication failed: password is incorrect, or there is no user with such name.'
|
||||
$CLICKHOUSE_CLIENT --config $CONFIG --host test_password --password "" -q 'select currentUser()'
|
||||
echo 'history_file'
|
||||
$CLICKHOUSE_CLIENT --progress off --interactive --config $CONFIG --host test_history_file -q 'select 1' </dev/null |& grep -F -o 'Cannot create file: /no/such/dir/.history'
|
||||
|
||||
rm -f "${CONFIG:?}"
|
Loading…
Reference in New Issue
Block a user