feat(emqx_management): Import content of the HTTP request

Fixes: #4063
This commit is contained in:
k32 2021-05-30 17:28:06 +02:00
parent 3a89b1f00b
commit 7dde77bb8a
3 changed files with 45 additions and 12 deletions

View File

@ -1,23 +1,26 @@
%% -*-: erlang -*- %% -*- mode: erlang -*-
{VSN, {VSN,
[ {"4.3.2", [ {"4.3.2",
[ {load_module, emqx_mgmt, brutal_purge, soft_purge, []} [ {load_module, emqx_mgmt, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []}
]}, ]},
{<<"4.3.[0-1]">>, {<<"4.3.[0-1]">>,
[ {load_module, emqx_mgmt_data_backup, brutal_purge, soft_purge, []} [ {load_module, emqx_mgmt_data_backup, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt_cli, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_cli, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []}
]}, ]},
{<<".*">>, []} {<<".*">>, []}
], ],
[ [ {"4.3.2",
{"4.3.2",
[ {load_module, emqx_mgmt, brutal_purge, soft_purge, []} [ {load_module, emqx_mgmt, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []}
]}, ]},
{<<"4.3.[0-1]">>, {<<"4.3.[0-1]">>,
[ {load_module, emqx_mgmt_data_backup, brutal_purge, soft_purge, []} [ {load_module, emqx_mgmt_data_backup, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt_cli, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_cli, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt, brutal_purge, soft_purge, []}
, {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []}
]}, ]},
{<<".*">>, []} {<<".*">>, []}
] ]

View File

@ -110,7 +110,8 @@ get_list_exported() ->
import(_Bindings, Params) -> import(_Bindings, Params) ->
case proplists:get_value(<<"filename">>, Params) of case proplists:get_value(<<"filename">>, Params) of
undefined -> undefined ->
minirest:return({error, missing_required_params}); Result = import_content(Params),
minirest:return(Result);
Filename -> Filename ->
case proplists:get_value(<<"node">>, Params) of case proplists:get_value(<<"node">>, Params) of
undefined -> undefined ->
@ -127,11 +128,11 @@ import(_Bindings, Params) ->
end. end.
do_import(Filename) -> do_import(Filename) ->
FullFilename = filename:join([emqx:get_env(data_dir), Filename]), FullFilename = fullname(Filename),
emqx_mgmt_data_backup:import(FullFilename, "{}"). emqx_mgmt_data_backup:import(FullFilename, "{}").
download(#{filename := Filename}, _Params) -> download(#{filename := Filename}, _Params) ->
FullFilename = filename:join([emqx:get_env(data_dir), Filename]), FullFilename = fullname(Filename),
case file:read_file(FullFilename) of case file:read_file(FullFilename) of
{ok, Bin} -> {ok, Bin} ->
{ok, #{filename => list_to_binary(Filename), {ok, #{filename => list_to_binary(Filename),
@ -145,7 +146,7 @@ upload(Bindings, Params) ->
do_upload(_Bindings, #{<<"filename">> := Filename, do_upload(_Bindings, #{<<"filename">> := Filename,
<<"file">> := Bin}) -> <<"file">> := Bin}) ->
FullFilename = filename:join([emqx:get_env(data_dir), Filename]), FullFilename = fullname(Filename),
case file:write_file(FullFilename, Bin) of case file:write_file(FullFilename, Bin) of
ok -> ok ->
minirest:return({ok, [{node, node()}]}); minirest:return({ok, [{node, node()}]});
@ -153,18 +154,33 @@ do_upload(_Bindings, #{<<"filename">> := Filename,
minirest:return({error, Reason}) minirest:return({error, Reason})
end; end;
do_upload(Bindings, Params = #{<<"file">> := _}) -> do_upload(Bindings, Params = #{<<"file">> := _}) ->
Seconds = erlang:system_time(second), do_upload(Bindings, Params#{<<"filename">> => tmp_filename()});
{{Y, M, D}, {H, MM, S}} = emqx_mgmt_util:datetime(Seconds),
Filename = io_lib:format("emqx-export-~p-~p-~p-~p-~p-~p.json", [Y, M, D, H, MM, S]),
do_upload(Bindings, Params#{<<"filename">> => Filename});
do_upload(_Bindings, _Params) -> do_upload(_Bindings, _Params) ->
minirest:return({error, missing_required_params}). minirest:return({error, missing_required_params}).
delete(#{filename := Filename}, _Params) -> delete(#{filename := Filename}, _Params) ->
FullFilename = filename:join([emqx:get_env(data_dir), Filename]), FullFilename = fullname(Filename),
case file:delete(FullFilename) of case file:delete(FullFilename) of
ok -> ok ->
minirest:return(); minirest:return();
{error, Reason} -> {error, Reason} ->
minirest:return({error, Reason}) minirest:return({error, Reason})
end. end.
import_content(Content) ->
File = dump_to_tmp_file(Content),
do_import(File).
dump_to_tmp_file(Content) ->
Bin = emqx_json:encode(Content),
Filename = tmp_filename(),
ok = file:write_file(fullname(Filename), Bin),
Filename.
fullname(Name) ->
filename:join(emqx:get_env(data_dir), Name).
tmp_filename() ->
Seconds = erlang:system_time(second),
{{Y, M, D}, {H, MM, S}} = emqx_mgmt_util:datetime(Seconds),
io_lib:format("emqx-export-~p-~p-~p-~p-~p-~p.json", [Y, M, D, H, MM, S]).

View File

@ -553,6 +553,20 @@ t_data(_) ->
application:stop(emqx_dahboard), application:stop(emqx_dahboard),
ok. ok.
t_data_import_content(_) ->
ok = emqx_rule_registry:mnesia(boot),
ok = emqx_dashboard_admin:mnesia(boot),
application:ensure_all_started(emqx_rule_engine),
application:ensure_all_started(emqx_dashboard),
{ok, Data} = request_api(post, api_path(["data","export"]), [], auth_header_(), [#{}]),
#{<<"filename">> := Filename} = emqx_ct_http:get_http_data(Data),
Dir = emqx:get_env(data_dir),
{ok, Bin} = file:read_file(filename:join(Dir, Filename)),
Content = emqx_json:decode(Bin),
?assertMatch({ok, "{\"code\":0}"}, request_api(post, api_path(["data","import"]), [], auth_header_(), Content)),
application:stop(emqx_rule_engine),
application:stop(emqx_dahboard).
request_api(Method, Url, Auth) -> request_api(Method, Url, Auth) ->
request_api(Method, Url, [], Auth, []). request_api(Method, Url, [], Auth, []).