Просмотр исходного кода

feat(pgsql): accept wrapped secrets as passwords

That are coming from `emqx_schema_secret`. Also adapt pgsql-related
connectors.
Andrew Mayorov 2 лет назад
Родитель
Сommit
4385b2f020

+ 28 - 18
apps/emqx_bridge_pgsql/test/emqx_bridge_pgsql_SUITE.erl

@@ -183,31 +183,33 @@ pgsql_config(BridgeType, Config) ->
         end,
     QueryMode = ?config(query_mode, Config),
     TlsEnabled = ?config(enable_tls, Config),
+    %% NOTE: supplying password through a file here, to verify that it works.
+    Password = create_passfile(BridgeType, Config),
     ConfigString =
         io_lib:format(
-            "bridges.~s.~s {\n"
-            "  enable = true\n"
-            "  server = ~p\n"
-            "  database = ~p\n"
-            "  username = ~p\n"
-            "  password = ~p\n"
-            "  sql = ~p\n"
-            "  resource_opts = {\n"
-            "    request_ttl = 500ms\n"
-            "    batch_size = ~b\n"
-            "    query_mode = ~s\n"
-            "  }\n"
-            "  ssl = {\n"
-            "    enable = ~w\n"
-            "  }\n"
-            "}",
+            "bridges.~s.~s {"
+            "\n   enable = true"
+            "\n   server = ~p"
+            "\n   database = ~p"
+            "\n   username = ~p"
+            "\n   password = ~p"
+            "\n   sql = ~p"
+            "\n   resource_opts = {"
+            "\n     request_ttl = 500ms"
+            "\n     batch_size = ~b"
+            "\n     query_mode = ~s"
+            "\n   }"
+            "\n   ssl = {"
+            "\n     enable = ~w"
+            "\n   }"
+            "\n }",
             [
                 BridgeType,
                 Name,
                 Server,
                 ?PGSQL_DATABASE,
                 ?PGSQL_USERNAME,
-                ?PGSQL_PASSWORD,
+                Password,
                 ?SQL_BRIDGE,
                 BatchSize,
                 QueryMode,
@@ -216,6 +218,12 @@ pgsql_config(BridgeType, Config) ->
         ),
     {Name, parse_and_check(ConfigString, BridgeType, Name)}.
 
+create_passfile(BridgeType, Config) ->
+    Filename = binary_to_list(BridgeType) ++ ".passfile",
+    Filepath = filename:join(?config(priv_dir, Config), Filename),
+    ok = file:write_file(Filepath, ?PGSQL_PASSWORD),
+    "file://" ++ Filepath.
+
 parse_and_check(ConfigString, BridgeType, Name) ->
     {ok, RawConf} = hocon:binary(ConfigString, #{format => map}),
     hocon_tconf:check_plain(emqx_bridge_schema, RawConf, #{required => false, atom_key => false}),
@@ -379,7 +387,9 @@ t_setup_via_http_api_and_publish(Config) ->
     QueryMode = ?config(query_mode, Config),
     PgsqlConfig = PgsqlConfig0#{
         <<"name">> => Name,
-        <<"type">> => BridgeType
+        <<"type">> => BridgeType,
+        %% NOTE: using literal passwords with HTTP API requests.
+        <<"password">> => <<?PGSQL_PASSWORD>>
     },
     ?assertMatch(
         {ok, _},

+ 1 - 1
apps/emqx_bridge_tdengine/src/emqx_bridge_tdengine.app.src

@@ -1,6 +1,6 @@
 {application, emqx_bridge_tdengine, [
     {description, "EMQX Enterprise TDEngine Bridge"},
-    {vsn, "0.1.5"},
+    {vsn, "0.1.6"},
     {registered, []},
     {applications, [
         kernel,

+ 6 - 10
apps/emqx_bridge_tdengine/src/emqx_bridge_tdengine_connector.erl

@@ -6,7 +6,6 @@
 
 -behaviour(emqx_resource).
 
--include_lib("emqx_resource/include/emqx_resource.hrl").
 -include_lib("typerefl/include/types.hrl").
 -include_lib("emqx/include/logger.hrl").
 -include_lib("snabbkaffe/include/snabbkaffe.hrl").
@@ -48,8 +47,8 @@ adjust_fields(Fields) ->
         fun
             ({username, OrigUsernameFn}) ->
                 {username, add_default_fn(OrigUsernameFn, <<"root">>)};
-            ({password, OrigPasswordFn}) ->
-                {password, make_required_fn(OrigPasswordFn)};
+            ({password, _}) ->
+                {password, emqx_connector_schema_lib:password_field(#{required => true})};
             (Field) ->
                 Field
         end,
@@ -62,12 +61,6 @@ add_default_fn(OrigFn, Default) ->
         (Field) -> OrigFn(Field)
     end.
 
-make_required_fn(OrigFn) ->
-    fun
-        (required) -> true;
-        (Field) -> OrigFn(Field)
-    end.
-
 server() ->
     Meta = #{desc => ?DESC("server")},
     emqx_schema:servers_sc(Meta, ?TD_HOST_OPTIONS).
@@ -223,7 +216,10 @@ aggregate_query(BatchTks, BatchReqs, Acc) ->
     ).
 
 connect(Opts) ->
-    tdengine:start_link(Opts).
+    %% TODO: teach `tdengine` to accept 0-arity closures as passwords.
+    {value, {password, Secret}, OptsRest} = lists:keytake(password, 1, Opts),
+    NOpts = [{password, emqx_secret:unwrap(Secret)} | OptsRest],
+    tdengine:start_link(NOpts).
 
 query_opts(#{database := Database} = _Opts) ->
     [{db_name, Database}].

+ 2 - 1
apps/emqx_postgresql/src/emqx_postgresql.erl

@@ -131,7 +131,7 @@ on_start(
         {host, Host},
         {port, Port},
         {username, User},
-        {password, emqx_secret:wrap(maps:get(password, Config, ""))},
+        {password, maps:get(password, Config, "")},
         {database, DB},
         {auto_reconnect, ?AUTO_RECONNECT_INTERVAL},
         {pool_size, PoolSize}
@@ -357,6 +357,7 @@ validate_table_existence([], _SQL) ->
 connect(Opts) ->
     Host = proplists:get_value(host, Opts),
     Username = proplists:get_value(username, Opts),
+    %% TODO: teach `epgsql` to accept 0-arity closures as passwords.
     Password = emqx_secret:unwrap(proplists:get_value(password, Opts)),
     case epgsql:connect(Host, Username, Password, conn_opts(Opts)) of
         {ok, _Conn} = Ok ->