Merge pull request #9474 from zhongwencool/bootstrap-apps
fix: load bootstrap file when no bootstrap user
This commit is contained in:
commit
78ce1ff1b9
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_management,
|
{application, emqx_management,
|
||||||
[{description, "EMQ X Management API and CLI"},
|
[{description, "EMQ X Management API and CLI"},
|
||||||
{vsn, "4.4.10"}, % strict semver, bump manually!
|
{vsn, "4.4.11"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_management_sup]},
|
{registered, [emqx_management_sup]},
|
||||||
{applications, [kernel,stdlib,emqx_plugin_libs,minirest]},
|
{applications, [kernel,stdlib,emqx_plugin_libs,minirest]},
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
, del_app/1
|
, del_app/1
|
||||||
, list_apps/0
|
, list_apps/0
|
||||||
, init_bootstrap_apps/0
|
, init_bootstrap_apps/0
|
||||||
|
, need_bootstrap/0
|
||||||
|
, clear_bootstrap_apps/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% APP Auth/ACL API
|
%% APP Auth/ACL API
|
||||||
|
@ -81,13 +83,33 @@ add_default_app() ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
init_bootstrap_apps() ->
|
init_bootstrap_apps() ->
|
||||||
|
case need_bootstrap() of
|
||||||
|
true ->
|
||||||
Bootstrap = application:get_env(emqx_management, bootstrap_apps_file, undefined),
|
Bootstrap = application:get_env(emqx_management, bootstrap_apps_file, undefined),
|
||||||
Size = mnesia:table_info(mqtt_app, size),
|
init_bootstrap_apps(Bootstrap);
|
||||||
init_bootstrap_apps(Bootstrap, Size).
|
false ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
init_bootstrap_apps(undefined, _) -> ok;
|
need_bootstrap() ->
|
||||||
init_bootstrap_apps(_File, Size)when Size > 0 -> ok;
|
{atomic, Res} = mnesia:transaction(
|
||||||
init_bootstrap_apps(File, 0) ->
|
fun() ->
|
||||||
|
Spec = [{#mqtt_app{id = '$1', desc = ?BOOTSTRAP_TAG, _ = '_'}, [], ['$1']}],
|
||||||
|
mnesia:select(mqtt_app, Spec, 1, read) =:= '$end_of_table'
|
||||||
|
end),
|
||||||
|
Res.
|
||||||
|
|
||||||
|
clear_bootstrap_apps() ->
|
||||||
|
{atomic, ok} =
|
||||||
|
mnesia:transaction(fun() ->
|
||||||
|
All = mnesia:match_object(mqtt_app, #mqtt_app{desc = ?BOOTSTRAP_TAG, _ = '_'}, read),
|
||||||
|
DeleteFun = fun(A) -> mnesia:delete_object(A) end,
|
||||||
|
lists:foreach(DeleteFun, All)
|
||||||
|
end),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
init_bootstrap_apps(undefined) -> ok;
|
||||||
|
init_bootstrap_apps(File) ->
|
||||||
case file:open(File, [read, binary]) of
|
case file:open(File, [read, binary]) of
|
||||||
{ok, Dev} ->
|
{ok, Dev} ->
|
||||||
{ok, MP} = re:compile(<<"(\.+):(\.+$)">>, [ungreedy]),
|
{ok, MP} = re:compile(<<"(\.+):(\.+$)">>, [ungreedy]),
|
||||||
|
@ -95,7 +117,7 @@ init_bootstrap_apps(File, 0) ->
|
||||||
ok -> ok;
|
ok -> ok;
|
||||||
Error ->
|
Error ->
|
||||||
%% if failed add bootstrap users, we should clear all bootstrap apps
|
%% if failed add bootstrap users, we should clear all bootstrap apps
|
||||||
{atomic, ok} = mnesia:clear_table(mqtt_app),
|
clear_bootstrap_apps(),
|
||||||
Error
|
Error
|
||||||
end;
|
end;
|
||||||
{error, Reason} = Error ->
|
{error, Reason} = Error ->
|
||||||
|
|
|
@ -42,7 +42,7 @@ init_per_suite(Config) ->
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(_) ->
|
||||||
ok = application:unset_env(emqx_management, bootstrap_apps_file),
|
ok = application:unset_env(emqx_management, bootstrap_apps_file),
|
||||||
_ = mnesia:clear_table(mqtt_app),
|
emqx_mgmt_auth:clear_bootstrap_apps(),
|
||||||
emqx_ct_helpers:stop_apps([]),
|
emqx_ct_helpers:stop_apps([]),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -55,12 +55,23 @@ t_load_ok(_) ->
|
||||||
Bin = <<"test-1:secret-1\ntest-2:secret-2">>,
|
Bin = <<"test-1:secret-1\ntest-2:secret-2">>,
|
||||||
File = "./bootstrap_apps.txt",
|
File = "./bootstrap_apps.txt",
|
||||||
ok = file:write_file(File, Bin),
|
ok = file:write_file(File, Bin),
|
||||||
_ = mnesia:clear_table(mqtt_app),
|
emqx_mgmt_auth:clear_bootstrap_apps(),
|
||||||
application:set_env(emqx_management, bootstrap_apps_file, File),
|
application:set_env(emqx_management, bootstrap_apps_file, File),
|
||||||
{ok, _} = application:ensure_all_started(emqx_management),
|
{ok, _} = application:ensure_all_started(emqx_management),
|
||||||
?assert(emqx_mgmt_auth:is_authorized(<<"test-1">>, <<"secret-1">>)),
|
?assert(emqx_mgmt_auth:is_authorized(<<"test-1">>, <<"secret-1">>)),
|
||||||
?assert(emqx_mgmt_auth:is_authorized(<<"test-2">>, <<"secret-2">>)),
|
?assert(emqx_mgmt_auth:is_authorized(<<"test-2">>, <<"secret-2">>)),
|
||||||
?assertNot(emqx_mgmt_auth:is_authorized(<<"test-2">>, <<"secret-1">>)),
|
?assertNot(emqx_mgmt_auth:is_authorized(<<"test-2">>, <<"secret-1">>)),
|
||||||
|
|
||||||
|
%% load twice to check if the table is unchanged.
|
||||||
|
application:stop(emqx_management),
|
||||||
|
Bin1 = <<"test-1:new-secret-1\ntest-2:new-secret-2">>,
|
||||||
|
ok = file:write_file(File, Bin1),
|
||||||
|
application:set_env(emqx_management, bootstrap_apps_file, File),
|
||||||
|
{ok, _} = application:ensure_all_started(emqx_management),
|
||||||
|
?assert(emqx_mgmt_auth:is_authorized(<<"test-1">>, <<"secret-1">>)),
|
||||||
|
?assert(emqx_mgmt_auth:is_authorized(<<"test-2">>, <<"secret-2">>)),
|
||||||
|
?assertNot(emqx_mgmt_auth:is_authorized(<<"test-1">>, <<"new-secret-1">>)),
|
||||||
|
?assertNot(emqx_mgmt_auth:is_authorized(<<"test-2">>, <<"new-secret-2">>)),
|
||||||
application:stop(emqx_management).
|
application:stop(emqx_management).
|
||||||
|
|
||||||
t_bootstrap_user_file_not_found(_) ->
|
t_bootstrap_user_file_not_found(_) ->
|
||||||
|
@ -83,9 +94,9 @@ t_load_invalid_format_failed(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
check_load_failed(File) ->
|
check_load_failed(File) ->
|
||||||
_ = mnesia:clear_table(mqtt_app),
|
emqx_mgmt_auth:clear_bootstrap_apps(),
|
||||||
application:stop(emqx_management),
|
application:stop(emqx_management),
|
||||||
application:set_env(emqx_management, bootstrap_apps_file, File),
|
application:set_env(emqx_management, bootstrap_apps_file, File),
|
||||||
?assertMatch({error, _}, application:ensure_all_started(emqx_management)),
|
?assertMatch({error, _}, application:ensure_all_started(emqx_management)),
|
||||||
?assertNot(lists:member(emqx_management, application:which_applications())),
|
?assertNot(lists:member(emqx_management, application:which_applications())),
|
||||||
?assertEqual(0, mnesia:table_info(mqtt_app, size)).
|
?assert(emqx_mgmt_auth:need_bootstrap()).
|
||||||
|
|
|
@ -241,6 +241,7 @@ init_per_testcase(Test, Config)
|
||||||
| Config];
|
| Config];
|
||||||
init_per_testcase(t_rule_api_unicode_ids, Config) ->
|
init_per_testcase(t_rule_api_unicode_ids, Config) ->
|
||||||
ok = emqx_dashboard_admin:mnesia(boot),
|
ok = emqx_dashboard_admin:mnesia(boot),
|
||||||
|
ok = emqx_mgmt_auth:mnesia(boot),
|
||||||
emqx_ct_helpers:start_apps([emqx_management, emqx_dashboard]),
|
emqx_ct_helpers:start_apps([emqx_management, emqx_dashboard]),
|
||||||
Config;
|
Config;
|
||||||
init_per_testcase(_TestCase, Config) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
- Upgrade http client library `ehttpc` from `0.2.1` to `0.4.2` [#9456](https://github.com/emqx/emqx/pull/9456).
|
- Upgrade http client library `ehttpc` from `0.2.1` to `0.4.2` [#9456](https://github.com/emqx/emqx/pull/9456).
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Fixed load bootstrap file when no bootstrap user in `mqtt_app` [#9474](https://github.com/emqx/emqx-enterprise/pull/9474).
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
### 增强
|
### 增强
|
||||||
|
|
||||||
- HTTP 客户端库 `ehttpc` 从 `0.2.1` 升级到 `0.4.2` [#9456](https://github.com/emqx/emqx/pull/9456)。
|
- HTTP 客户端库 `ehttpc` 从 `0.2.1` 升级到 `0.4.2` [#9456](https://github.com/emqx/emqx/pull/9456)。
|
||||||
|
|
||||||
|
|
||||||
|
### 修复
|
||||||
|
|
||||||
|
- 修复 mqtt_app 表内没有 boostrap user 里未导入用户的问题 [#9474](https://github.com/emqx/emqx-enterprise/pull/9474).
|
||||||
|
|
Loading…
Reference in New Issue