REST API add modify_config/config_list
This commit is contained in:
parent
d50ce9f6c0
commit
9e6c63b91b
|
@ -72,4 +72,5 @@
|
|||
-define(ERROR10, 110). %% Plugin has been loaded
|
||||
-define(ERROR11, 111). %% Plugin has been loaded
|
||||
-define(ERROR12, 112). %% Client not online
|
||||
-define(ERROR13, 113). %% Modify config fail
|
||||
|
||||
|
|
|
@ -16,7 +16,13 @@
|
|||
|
||||
-module (emqttd_cli_config).
|
||||
|
||||
-export ([register_config_cli/0, register_config/0, run/1]).
|
||||
-export ([register_config_cli/0,
|
||||
register_config/0,
|
||||
run/1,
|
||||
set_usage/0,
|
||||
all_cfgs/0,
|
||||
get_cfg/2,
|
||||
get_cfg/3]).
|
||||
|
||||
-define(APP, emqttd).
|
||||
|
||||
|
@ -46,6 +52,54 @@ register_config_cli() ->
|
|||
register_broker_config(),
|
||||
register_lager_config().
|
||||
|
||||
set_usage() ->
|
||||
io:format("~-40s# ~-20s# ~-20s ~p~n", ["key", "value", "datatype", "app"]),
|
||||
io:format("------------------------------------------------------------------------------------------------~n"),
|
||||
lists:foreach(fun({Key, Val, Datatype, App}) ->
|
||||
io:format("~-40s# ~-20s# ~-20s ~p~n", [Key, Val, Datatype, App])
|
||||
end, all_cfgs()),
|
||||
io:format("------------------------------------------------------------------------------------------------~n"),
|
||||
io:format("Usage: set key=value --app=appname~n").
|
||||
|
||||
all_cfgs() ->
|
||||
{Mappings, Mappings1} = lists:foldl(
|
||||
fun({Key, {_, Map, _}}, {Acc, Acc1}) ->
|
||||
Map1 = lists:map(fun(M) -> {cuttlefish_mapping:variable(M), Key} end, Map),
|
||||
{Acc ++ Map, Acc1 ++ Map1}
|
||||
end, {[], []}, ets:tab2list(clique_schema)),
|
||||
lists:foldl(fun({Key, _}, Acc) ->
|
||||
case lists:keyfind(cuttlefish_variable:tokenize(Key), 2, Mappings) of
|
||||
false -> Acc;
|
||||
Map ->
|
||||
Datatype = format_datatype(cuttlefish_mapping:datatype(Map)),
|
||||
App = proplists:get_value(cuttlefish_variable:tokenize(Key), Mappings1),
|
||||
[{_, [Val0]}] = clique_config:show([Key], [{app, App}]),
|
||||
Val = any_to_string(proplists:get_value(Key, Val0)),
|
||||
[{Key, Val, Datatype, App} | Acc]
|
||||
end
|
||||
end, [],lists:sort(ets:tab2list(clique_config))).
|
||||
|
||||
get_cfg(App, Key) ->
|
||||
get_cfg(App, Key, undefined).
|
||||
|
||||
get_cfg(App, Key, Def) ->
|
||||
[{_, [Val0]}] = clique_config:show([Key], [{app, App}]),
|
||||
proplists:get_value(Key, Val0, Def).
|
||||
|
||||
format_datatype(Value) ->
|
||||
format_datatype(Value, "").
|
||||
|
||||
format_datatype([Head], Acc) when is_tuple(Head) ->
|
||||
[Head1 | _] = erlang:tuple_to_list(Head),
|
||||
lists:concat([Acc, Head1]);
|
||||
format_datatype([Head], Acc) ->
|
||||
lists:concat([Acc, Head]);
|
||||
format_datatype([Head | Tail], Acc) when is_tuple(Head)->
|
||||
[Head1 | _] = erlang:tuple_to_list(Head),
|
||||
format_datatype(Tail, Acc ++ lists:concat([Head1, ", "]));
|
||||
format_datatype([Head | Tail], Acc) ->
|
||||
format_datatype(Tail, Acc ++ lists:concat([Head, ", "])).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Auth/Acl
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -72,6 +126,8 @@ register_protocol_formatter() ->
|
|||
"keepalive_backoff"],
|
||||
[clique:register_formatter(["mqtt", Key], fun protocol_formatter_callback/2) || Key <- ConfigKeys].
|
||||
|
||||
protocol_formatter_callback([_, "websocket_protocol_header"], Params) ->
|
||||
Params;
|
||||
protocol_formatter_callback([_, Key], Params) ->
|
||||
proplists:get_value(l2a(Key), Params).
|
||||
|
||||
|
@ -85,7 +141,7 @@ register_protocol_config() ->
|
|||
|
||||
protocol_config_callback([_AppStr, KeyStr], Value) ->
|
||||
protocol_config_callback(protocol, l2a(KeyStr), Value).
|
||||
protocol_config_callback(App, websocket_protocol_header, Value) ->
|
||||
protocol_config_callback(_App, websocket_protocol_header, Value) ->
|
||||
application:set_env(?APP, websocket_protocol_header, Value),
|
||||
" successfully\n";
|
||||
protocol_config_callback(App, Key, Value) ->
|
||||
|
@ -271,3 +327,18 @@ lager_config_callback(_, Value) ->
|
|||
register_config_whitelist(ConfigKeys) ->
|
||||
clique:register_config_whitelist(ConfigKeys, ?APP).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Inner Function
|
||||
%%--------------------------------------------------------------------
|
||||
any_to_string(I) when is_integer(I) ->
|
||||
integer_to_list(I);
|
||||
any_to_string(F) when is_float(F)->
|
||||
float_to_list(F,[{decimals, 4}]);
|
||||
any_to_string(A) when is_atom(A) ->
|
||||
atom_to_list(A);
|
||||
any_to_string(B) when is_binary(B) ->
|
||||
binary_to_list(B);
|
||||
any_to_string(L) when is_list(L) ->
|
||||
L.
|
||||
|
||||
|
||||
|
|
|
@ -52,15 +52,21 @@ dump(_App, _Terms) ->
|
|||
%% TODO
|
||||
ok.
|
||||
|
||||
-spec(set(atom(), atom(), term()) -> ok).
|
||||
-spec(set(atom(), list(), list()) -> ok).
|
||||
set(App, Par, Val) ->
|
||||
application:set_env(App, Par, Val).
|
||||
emqttd_cli_config:run(["config",
|
||||
"set",
|
||||
lists:concat([Par, "=", Val]),
|
||||
lists:concat(["--app=", App])]).
|
||||
|
||||
-spec(get(atom(), atom()) -> undefined | {ok, term()}).
|
||||
-spec(get(atom(), list()) -> undefined | {ok, term()}).
|
||||
get(App, Par) ->
|
||||
application:get_env(App, Par).
|
||||
case emqttd_cli_config:get_cfg(App, Par) of
|
||||
undefined -> undefined;
|
||||
Val -> {ok, Val}
|
||||
end.
|
||||
|
||||
-spec(get(atom(), atom(), atom()) -> term()).
|
||||
-spec(get(atom(), list(), atom()) -> term()).
|
||||
get(App, Par, Def) ->
|
||||
application:get_env(App, Par, Def).
|
||||
emqttd_cli_config:get_cfg(App, Par, Def).
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ run([]) -> usage(), ok;
|
|||
|
||||
run(["help"]) -> usage(), ok;
|
||||
|
||||
run(["set"] = CmdS) when length(CmdS) =:= 1 ->
|
||||
emqttd_cli_config:set_usage(), ok;
|
||||
|
||||
run(["set" | _] = CmdS) ->
|
||||
emqttd_cli_config:run(["config" | CmdS]), ok;
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
-export([kick_client/1, clean_acl_cache/2]).
|
||||
|
||||
-export([modify_config/3, modify_config/4, get_configs/0, get_config/1]).
|
||||
|
||||
-define(KB, 1024).
|
||||
-define(MB, (1024*1024)).
|
||||
-define(GB, (1024*1024*1024)).
|
||||
|
@ -312,6 +314,26 @@ clean_acl_cache(Node, ClientId, Topic) when Node =:= node() ->
|
|||
clean_acl_cache(Node, ClientId, Topic) ->
|
||||
rpc_call(Node, clean_acl_cache, [Node, ClientId, Topic]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Config ENV
|
||||
%%--------------------------------------------------------------------
|
||||
modify_config(App, Key, Value) ->
|
||||
Result = [modify_config(Node, App, Key, Value) || Node <- ekka_mnesia:running_nodes()],
|
||||
lists:any(fun(Item) -> Item =:= ok end, Result).
|
||||
|
||||
modify_config(Node, App, Key, Value) when Node =:= node() ->
|
||||
emqttd_config:set(App, Key, Value);
|
||||
modify_config(Node, App, Key, Value) ->
|
||||
rpc_call(Node, modify_config, [Node, App, Key, Value]).
|
||||
|
||||
get_configs() ->
|
||||
[{Node, get_config(Node)} || Node <- ekka_mnesia:running_nodes()].
|
||||
|
||||
get_config(Node) when Node =:= node()->
|
||||
emqttd_cli_config:all_cfgs();
|
||||
get_config(Node) ->
|
||||
rpc_call(Node, get_config, [Node]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Internel Functions.
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
-http_api({"^nodes/(.+?)/plugins/?$", 'GET', plugin_list, []}).
|
||||
-http_api({"^nodes/(.+?)/plugins/(.+?)/?$", 'PUT', enabled, [{<<"active">>, bool}]}).
|
||||
|
||||
-http_api({"^config/(.+?)/?$", 'PUT', modify_config, [{<<"key">>, binary}, {<<"value">>, binary}]}).
|
||||
-http_api({"^config/?$", 'GET', config_list, []}).
|
||||
-http_api({"^nodes/(.+?)/config/(.+?)/?$", 'PUT', modify_config, [{<<"key">>, binary}, {<<"value">>, binary}]}).
|
||||
-http_api({"^nodes/(.+?)/config/?$", 'GET', config_list, []}).
|
||||
-export([alarm_list/3]).
|
||||
-export([client/3, client_list/3, client_list/4, kick_client/3, clean_acl_cache/3]).
|
||||
-export([route/3, route_list/2]).
|
||||
|
@ -64,6 +68,7 @@
|
|||
-export([nodes/2, node/3, brokers/2, broker/3, listeners/2, listener/3, metrics/2, metric/3, stats/2, stat/3]).
|
||||
-export([publish/2, subscribe/2, unsubscribe/2]).
|
||||
-export([plugin_list/3, enabled/4]).
|
||||
-export([modify_config/3, modify_config/4, config_list/2, config_list/3]).
|
||||
|
||||
%%--------------------------------------------------------------------------
|
||||
%% alarm
|
||||
|
@ -363,6 +368,44 @@ plugin(#mqtt_plugin{name = Name, version = Ver, descr = Descr,
|
|||
{description, iolist_to_binary(Descr)},
|
||||
{active, Active}].
|
||||
|
||||
%%--------------------------------------------------------------------------
|
||||
%% modify config
|
||||
%%--------------------------------------------------------------------------
|
||||
modify_config('PUT', Params, App) ->
|
||||
Key = proplists:get_value(<<"key">>, Params, <<"">>),
|
||||
Value = proplists:get_value(<<"value">>, Params, <<"">>),
|
||||
case emqttd_mgmt:modify_config(l2a(App), b2l(Key), b2l(Value)) of
|
||||
true -> {ok, []};
|
||||
false -> {error, [{code, ?ERROR13}]}
|
||||
end.
|
||||
|
||||
modify_config('PUT', Params, Node, App) ->
|
||||
Key = proplists:get_value(<<"key">>, Params, <<"">>),
|
||||
Value = proplists:get_value(<<"value">>, Params, <<"">>),
|
||||
case emqttd_mgmt:modify_config(l2a(Node), l2a(App), b2l(Key), b2l(Value)) of
|
||||
ok -> {ok, []};
|
||||
_ -> {error, [{code, ?ERROR13}]}
|
||||
end.
|
||||
|
||||
config_list('GET', _Params) ->
|
||||
Data = emqttd_mgmt:get_configs(),
|
||||
{ok, [{Node, format_config(Config, [])} || {Node, Config} <- Data]}.
|
||||
|
||||
config_list('GET', _Params, Node) ->
|
||||
Data = emqttd_mgmt:get_config(l2a(Node)),
|
||||
{ok, [format_config(Config) || Config <- Data]}.
|
||||
|
||||
format_config([], Acc) ->
|
||||
Acc;
|
||||
format_config([{Key, Value, Datatpye, App}| Configs], Acc) ->
|
||||
format_config(Configs, [format_config({Key, Value, Datatpye, App}) | Acc]).
|
||||
|
||||
format_config({Key, Value, Datatpye, App}) ->
|
||||
[{<<"key">>, l2b(Key)},
|
||||
{<<"value">>, l2b(Value)},
|
||||
{<<"datatpye">>, l2b(Datatpye)},
|
||||
{<<"app">>, App}].
|
||||
|
||||
%%--------------------------------------------------------------------------
|
||||
%% Inner function
|
||||
%%--------------------------------------------------------------------------
|
||||
|
@ -399,6 +442,7 @@ bin(undefined) -> <<>>.
|
|||
int(L) -> list_to_integer(L).
|
||||
l2a(L) -> list_to_atom(L).
|
||||
l2b(L) -> list_to_binary(L).
|
||||
b2l(B) -> binary_to_list(B).
|
||||
|
||||
|
||||
page_params(Params) ->
|
||||
|
|
Loading…
Reference in New Issue