feat(clickhouse): accept wrapped secrets as passwords

This commit is contained in:
Andrew Mayorov 2023-11-07 20:53:50 +07:00
parent fc340a276e
commit a69a78d024
No known key found for this signature in database
GPG Key ID: 2837C62ACFBFED5D
3 changed files with 36 additions and 5 deletions

View File

@ -1,6 +1,6 @@
{application, emqx_bridge_clickhouse, [ {application, emqx_bridge_clickhouse, [
{description, "EMQX Enterprise ClickHouse Bridge"}, {description, "EMQX Enterprise ClickHouse Bridge"},
{vsn, "0.2.3"}, {vsn, "0.2.4"},
{registered, []}, {registered, []},
{applications, [ {applications, [
kernel, kernel,

View File

@ -145,7 +145,7 @@ on_start(
Options = [ Options = [
{url, URL}, {url, URL},
{user, maps:get(username, Config, "default")}, {user, maps:get(username, Config, "default")},
{key, emqx_secret:wrap(maps:get(password, Config, "public"))}, {key, maps:get(password, Config, emqx_secret:wrap("public"))},
{database, DB}, {database, DB},
{auto_reconnect, ?AUTO_RECONNECT_INTERVAL}, {auto_reconnect, ?AUTO_RECONNECT_INTERVAL},
{pool_size, PoolSize}, {pool_size, PoolSize},
@ -243,6 +243,7 @@ connect(Options) ->
URL = iolist_to_binary(emqx_http_lib:normalize(proplists:get_value(url, Options))), URL = iolist_to_binary(emqx_http_lib:normalize(proplists:get_value(url, Options))),
User = proplists:get_value(user, Options), User = proplists:get_value(user, Options),
Database = proplists:get_value(database, Options), Database = proplists:get_value(database, Options),
%% TODO: teach `clickhouse` to accept 0-arity closures as passwords.
Key = emqx_secret:unwrap(proplists:get_value(key, Options)), Key = emqx_secret:unwrap(proplists:get_value(key, Options)),
Pool = proplists:get_value(pool, Options), Pool = proplists:get_value(pool, Options),
PoolSize = proplists:get_value(pool_size, Options), PoolSize = proplists:get_value(pool_size, Options),

View File

@ -10,10 +10,12 @@
-include("emqx_connector.hrl"). -include("emqx_connector.hrl").
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-include_lib("stdlib/include/assert.hrl"). -include_lib("stdlib/include/assert.hrl").
-include_lib("common_test/include/ct.hrl").
-define(APP, emqx_bridge_clickhouse). -define(APP, emqx_bridge_clickhouse).
-define(CLICKHOUSE_HOST, "clickhouse"). -define(CLICKHOUSE_HOST, "clickhouse").
-define(CLICKHOUSE_RESOURCE_MOD, emqx_bridge_clickhouse_connector). -define(CLICKHOUSE_RESOURCE_MOD, emqx_bridge_clickhouse_connector).
-define(CLICKHOUSE_PASSWORD, "public").
%% This test SUITE requires a running clickhouse instance. If you don't want to %% This test SUITE requires a running clickhouse instance. If you don't want to
%% bring up the whole CI infrastuctucture with the `scripts/ct/run.sh` script %% bring up the whole CI infrastuctucture with the `scripts/ct/run.sh` script
@ -57,7 +59,7 @@ init_per_suite(Config) ->
clickhouse:start_link([ clickhouse:start_link([
{url, clickhouse_url()}, {url, clickhouse_url()},
{user, <<"default">>}, {user, <<"default">>},
{key, "public"}, {key, ?CLICKHOUSE_PASSWORD},
{pool, tmp_pool} {pool, tmp_pool}
]), ]),
{ok, _, _} = clickhouse:query(Conn, <<"CREATE DATABASE IF NOT EXISTS mqtt">>, #{}), {ok, _, _} = clickhouse:query(Conn, <<"CREATE DATABASE IF NOT EXISTS mqtt">>, #{}),
@ -92,6 +94,31 @@ t_lifecycle(_Config) ->
clickhouse_config() clickhouse_config()
). ).
t_start_passfile(Config) ->
ResourceID = atom_to_binary(?FUNCTION_NAME),
PasswordFilename = filename:join(?config(priv_dir, Config), "passfile"),
ok = file:write_file(PasswordFilename, <<?CLICKHOUSE_PASSWORD>>),
InitialConfig = clickhouse_config(#{
password => iolist_to_binary(["file://", PasswordFilename])
}),
{ok, #{config := ResourceConfig}} =
emqx_resource:check_config(?CLICKHOUSE_RESOURCE_MOD, InitialConfig),
?assertMatch(
{ok, #{status := connected}},
emqx_resource:create_local(
ResourceID,
?CONNECTOR_RESOURCE_GROUP,
?CLICKHOUSE_RESOURCE_MOD,
ResourceConfig,
#{}
)
),
?assertEqual(
ok,
emqx_resource:remove_local(ResourceID)
),
ok.
show(X) -> show(X) ->
erlang:display(X), erlang:display(X),
X. X.
@ -168,12 +195,15 @@ perform_lifecycle_check(ResourceID, InitialConfig) ->
% %%------------------------------------------------------------------------------ % %%------------------------------------------------------------------------------
clickhouse_config() -> clickhouse_config() ->
clickhouse_config(#{}).
clickhouse_config(Overrides) ->
Config = Config =
#{ #{
auto_reconnect => true, auto_reconnect => true,
database => <<"mqtt">>, database => <<"mqtt">>,
username => <<"default">>, username => <<"default">>,
password => <<"public">>, password => <<?CLICKHOUSE_PASSWORD>>,
pool_size => 8, pool_size => 8,
url => iolist_to_binary( url => iolist_to_binary(
io_lib:format( io_lib:format(
@ -186,7 +216,7 @@ clickhouse_config() ->
), ),
connect_timeout => <<"10s">> connect_timeout => <<"10s">>
}, },
#{<<"config">> => Config}. #{<<"config">> => maps:merge(Config, Overrides)}.
test_query_no_params() -> test_query_no_params() ->
{query, <<"SELECT 1">>}. {query, <<"SELECT 1">>}.