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

Merge pull request #10896 from zhongwencool/api-keys-hot-conf-update

feat: api_key conf support hot conf
zhongwencool 2 лет назад
Родитель
Сommit
8d8efe449e

+ 0 - 8
apps/emqx_bridge_kafka/test/emqx_bridge_kafka_impl_producer_SUITE.erl

@@ -115,14 +115,6 @@ end_per_testcase(_TestCase, _Config) ->
     delete_all_bridges(),
     ok.
 
-set_special_configs(emqx_management) ->
-    Listeners = #{http => #{port => 8081}},
-    Config = #{
-        listeners => Listeners,
-        applications => [#{id => "admin", secret => "public"}]
-    },
-    emqx_config:put([emqx_management], Config),
-    ok;
 set_special_configs(emqx_dashboard) ->
     emqx_dashboard_api_test_helpers:set_default_config(),
     ok;

+ 2 - 3
apps/emqx_dashboard/src/emqx_dashboard_schema.erl

@@ -62,9 +62,8 @@ fields("dashboard") ->
                 #{
                     desc => ?DESC(bootstrap_users_file),
                     required => false,
-                    importance => ?IMPORTANCE_HIDDEN,
-                    default => <<>>
-                    %% deprecated => {since, "5.1.0"}
+                    default => <<>>,
+                    deprecated => {since, "5.1.0"}
                 }
             )}
     ];

+ 2 - 0
apps/emqx_management/src/emqx_mgmt_app.erl

@@ -31,10 +31,12 @@ start(_Type, _Args) ->
     ok = mria_rlog:wait_for_shards([?MANAGEMENT_SHARD], infinity),
     case emqx_mgmt_auth:init_bootstrap_file() of
         ok ->
+            emqx_conf:add_handler([api_key], emqx_mgmt_auth),
             emqx_mgmt_sup:start_link();
         {error, Reason} ->
             {error, Reason}
     end.
 
 stop(_State) ->
+    emqx_conf:remove_handler([api_key]),
     ok.

+ 14 - 7
apps/emqx_management/src/emqx_mgmt_auth.erl

@@ -20,6 +20,7 @@
 %% API
 -export([mnesia/1]).
 -boot_mnesia({mnesia, [boot]}).
+-behaviour(emqx_config_handler).
 
 -export([
     create/4,
@@ -31,6 +32,7 @@
 ]).
 
 -export([authorize/3]).
+-export([post_config_update/5]).
 
 %% Internal exports (RPC)
 -export([
@@ -65,6 +67,17 @@ mnesia(boot) ->
         {attributes, record_info(fields, ?APP)}
     ]).
 
+post_config_update([api_key], _Req, NewConf, _OldConf, _AppEnvs) ->
+    #{bootstrap_file := File} = NewConf,
+    case init_bootstrap_file(File) of
+        ok ->
+            ?SLOG(debug, #{msg => "init_bootstrap_api_keys_from_file_ok", file => File});
+        {error, Reason} ->
+            Msg = "init_bootstrap_api_keys_from_file_failed",
+            ?SLOG(error, #{msg => Msg, reason => Reason, file => File})
+    end,
+    ok.
+
 -spec init_bootstrap_file() -> ok | {error, _}.
 init_bootstrap_file() ->
     File = bootstrap_file(),
@@ -230,13 +243,7 @@ generate_api_secret() ->
     emqx_base62:encode(Random).
 
 bootstrap_file() ->
-    case emqx:get_config([api_key, bootstrap_file], <<>>) of
-        %% For compatible remove until 5.1.0
-        <<>> ->
-            emqx:get_config([dashboard, bootstrap_users_file], <<>>);
-        File ->
-            File
-    end.
+    emqx:get_config([api_key, bootstrap_file], <<>>).
 
 init_bootstrap_file(<<>>) ->
     ok;

+ 16 - 23
apps/emqx_management/test/emqx_mgmt_api_api_keys_SUITE.erl

@@ -29,19 +29,18 @@ groups() ->
     ].
 
 init_per_suite(Config) ->
-    emqx_mgmt_api_test_util:init_suite([emqx_conf]),
+    emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_management]),
     Config.
 
 end_per_suite(_) ->
-    emqx_mgmt_api_test_util:end_suite([emqx_conf]).
+    emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_management]).
 
 t_bootstrap_file(_) ->
     TestPath = <<"/api/v5/status">>,
     Bin = <<"test-1:secret-1\ntest-2:secret-2">>,
     File = "./bootstrap_api_keys.txt",
     ok = file:write_file(File, Bin),
-    emqx:update_config([api_key, bootstrap_file], File),
-    ok = emqx_mgmt_auth:init_bootstrap_file(),
+    update_file(File),
     ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
     ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
     ?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-1">>)),
@@ -49,39 +48,33 @@ t_bootstrap_file(_) ->
     %% relaunch to check if the table is changed.
     Bin1 = <<"test-1:new-secret-1\ntest-2:new-secret-2">>,
     ok = file:write_file(File, Bin1),
-    ok = emqx_mgmt_auth:init_bootstrap_file(),
+    update_file(File),
     ?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
     ?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
     ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
     ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
 
-    %% Compatibility
-    Bin2 = <<"test-3:new-secret-3\ntest-4:new-secret-4">>,
-    ok = file:write_file(File, Bin2),
-    emqx:update_config([api_key, bootstrap_file], <<>>),
-    emqx:update_config([dashboard, bootstrap_users_file], File),
-    ok = emqx_mgmt_auth:init_bootstrap_file(),
-    ?assertMatch(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
-    ?assertMatch(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
-    ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-3">>, <<"new-secret-3">>)),
-    ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-4">>, <<"new-secret-4">>)),
-
-    %% not found
-    NotFoundFile = "./bootstrap_apps_not_exist.txt",
-    emqx:update_config([api_key, bootstrap_file], NotFoundFile),
-    ?assertMatch({error, "No such file or directory"}, emqx_mgmt_auth:init_bootstrap_file()),
+    %% not error when bootstrap_file is empty
+    update_file(<<>>),
+    update_file("./bootstrap_apps_not_exist.txt"),
+    ?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
+    ?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
+    ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
+    ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
 
     %% bad format
     BadBin = <<"test-1:secret-11\ntest-2 secret-12">>,
     ok = file:write_file(File, BadBin),
-    emqx:update_config([api_key, bootstrap_file], File),
+    update_file(File),
     ?assertMatch({error, #{reason := "invalid_format"}}, emqx_mgmt_auth:init_bootstrap_file()),
     ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-11">>)),
     ?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-12">>)),
-    emqx:update_config([api_key, bootstrap_file], <<>>),
-    emqx:update_config([dashboard, bootstrap_users_file], <<>>),
+    update_file(<<>>),
     ok.
 
+update_file(File) ->
+    ?assertMatch({ok, _}, emqx:update_config([<<"api_key">>], #{<<"bootstrap_file">> => File})).
+
 t_create(_Config) ->
     Name = <<"EMQX-API-KEY-1">>,
     {ok, Create} = create_app(Name),

+ 2 - 11
apps/emqx_management/test/emqx_mgmt_cli_SUITE.erl

@@ -24,20 +24,11 @@ all() ->
     emqx_common_test_helpers:all(?MODULE).
 
 init_per_suite(Config) ->
-    mria:start(),
-    ok = emqx_common_test_helpers:start_apps([emqx_management]),
-    emqx_common_test_helpers:start_apps([] ++ [emqx_dashboard], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_management]),
     Config.
 
 end_per_suite(_) ->
-    emqx_common_test_helpers:stop_apps([emqx_management] ++ [emqx_dashboard]),
-    emqx_config:delete_override_conf_files(),
-    ok.
-
-set_special_configs(emqx_dashboard) ->
-    emqx_dashboard_api_test_helpers:set_default_config();
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite([emqx_management, emqx_conf]).
 
 t_status(_Config) ->
     emqx_ctl:run_command([]),