feat(API): add a general API to update configs
This commit is contained in:
parent
990c383e01
commit
2738815af9
|
@ -23,8 +23,6 @@
|
||||||
-export([ config/2
|
-export([ config/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-define(CONFIG_NAMES, [log, rpc, broker, zones, sysmon, alarm]).
|
|
||||||
|
|
||||||
-define(PARAM_CONF_PATH, [#{
|
-define(PARAM_CONF_PATH, [#{
|
||||||
name => conf_path,
|
name => conf_path,
|
||||||
in => query,
|
in => query,
|
||||||
|
@ -33,30 +31,34 @@
|
||||||
schema => #{type => string, default => <<".">>}
|
schema => #{type => string, default => <<".">>}
|
||||||
}]).
|
}]).
|
||||||
|
|
||||||
api_spec() ->
|
-define(TEXT_BODY(DESCR), #{
|
||||||
{config_apis(), config_schemas()}.
|
description => list_to_binary(DESCR),
|
||||||
|
content => #{
|
||||||
|
<<"text/plain">> => #{
|
||||||
|
schema => #{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
|
||||||
config_schemas() ->
|
api_spec() ->
|
||||||
[#{RootName => #{type => object}} %% TODO: generate this from hocon schema
|
{config_apis(), []}.
|
||||||
|| RootName <- ?CONFIG_NAMES].
|
|
||||||
|
|
||||||
config_apis() ->
|
config_apis() ->
|
||||||
[config_api(RootName) || RootName <- ?CONFIG_NAMES].
|
[config_api()].
|
||||||
|
|
||||||
config_api(RootName) when is_atom(RootName) ->
|
config_api() ->
|
||||||
RootNameStr = atom_to_list(RootName),
|
|
||||||
Descr = fun(Prefix) -> list_to_binary(Prefix ++ " " ++ RootNameStr) end,
|
|
||||||
Metadata = #{
|
Metadata = #{
|
||||||
get => #{
|
get => #{
|
||||||
description => Descr("Get configs for"),
|
description => <<"Get configs">>,
|
||||||
parameters => ?PARAM_CONF_PATH,
|
parameters => ?PARAM_CONF_PATH,
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"200">> => emqx_mgmt_util:response_schema(<<"The config value for log">>,
|
<<"200">> => ?TEXT_BODY("Get configs successfully"),
|
||||||
RootName)
|
<<"404">> => emqx_mgmt_util:response_error_schema(
|
||||||
|
<<"Config not found">>, ['NOT_FOUND'])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
delete => #{
|
delete => #{
|
||||||
description => Descr("Remove configs for"),
|
description => <<"Remove configs for">>,
|
||||||
parameters => ?PARAM_CONF_PATH,
|
parameters => ?PARAM_CONF_PATH,
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"200">> => emqx_mgmt_util:response_schema(<<"Remove configs successfully">>),
|
<<"200">> => emqx_mgmt_util:response_schema(<<"Remove configs successfully">>),
|
||||||
|
@ -65,45 +67,47 @@ config_api(RootName) when is_atom(RootName) ->
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
description => Descr("Update configs for"),
|
description => <<"Update configs for">>,
|
||||||
'requestBody' => emqx_mgmt_util:request_body_schema(RootName),
|
parameters => ?PARAM_CONF_PATH,
|
||||||
|
'requestBody' => ?TEXT_BODY("The format of the request body is depend on the 'conf_path' parameter in the query string"),
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"200">> => emqx_mgmt_util:response_schema(<<"Update configs successfully">>,
|
<<"200">> => ?TEXT_BODY("Update configs successfully"),
|
||||||
RootName),
|
|
||||||
<<"400">> => emqx_mgmt_util:response_error_schema(
|
<<"400">> => emqx_mgmt_util:response_error_schema(
|
||||||
<<"Update configs failed">>, ['UPDATE_FAILED'])
|
<<"Update configs failed">>, ['UPDATE_FAILED'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{"/configs/" ++ RootNameStr, Metadata, config}.
|
{"/configs", Metadata, config}.
|
||||||
|
|
||||||
%%%==============================================================================================
|
%%%==============================================================================================
|
||||||
%% parameters trans
|
%% parameters trans
|
||||||
config(get, Req) ->
|
config(get, Req) ->
|
||||||
%% TODO: query the config specified by the query string param 'conf_path'
|
%% TODO: query the config specified by the query string param 'conf_path'
|
||||||
Conf = emqx_config:get_raw([root_name_from_path(Req) | conf_path_from_querystr(Req)]),
|
case emqx_config:find_raw(conf_path_from_querystr(Req)) of
|
||||||
|
{ok, Conf} ->
|
||||||
{200, Conf};
|
{200, Conf};
|
||||||
|
{not_found, _, _} ->
|
||||||
|
{404, #{code => 'NOT_FOUND', message => <<"Config cannot found">>}}
|
||||||
|
end;
|
||||||
|
|
||||||
config(delete, Req) ->
|
config(delete, Req) ->
|
||||||
%% TODO: remove the config specified by the query string param 'conf_path'
|
%% TODO: remove the config specified by the query string param 'conf_path'
|
||||||
emqx_config:remove([root_name_from_path(Req) | conf_path_from_querystr(Req)]),
|
emqx_config:remove(conf_path_from_querystr(Req)),
|
||||||
{200};
|
{200};
|
||||||
|
|
||||||
config(put, Req) ->
|
config(put, Req) ->
|
||||||
RootName = root_name_from_path(Req),
|
Path = [binary_to_atom(Key, latin1) || Key <- conf_path_from_querystr(Req)],
|
||||||
ok = emqx_config:update([RootName], http_body(Req)),
|
ok = emqx_config:update(Path, http_body(Req)),
|
||||||
{200, emqx_config:get_raw([RootName])}.
|
{201, emqx_config:get_raw(Path)}.
|
||||||
|
|
||||||
root_name_from_path(Req) ->
|
|
||||||
<<"/api/v5/configs/", RootName/binary>> = cowboy_req:path(Req),
|
|
||||||
string:trim(RootName, trailing, "/").
|
|
||||||
|
|
||||||
conf_path_from_querystr(Req) ->
|
conf_path_from_querystr(Req) ->
|
||||||
case proplists:get_value(<<"conf_path">>, cowboy_req:parse_qs(Req)) of
|
case proplists:get_value(<<"conf_path">>, cowboy_req:parse_qs(Req)) of
|
||||||
undefined -> [];
|
undefined -> [];
|
||||||
Path -> [string:lexemes(Path, ". ")]
|
Path -> string:lexemes(Path, ". ")
|
||||||
end.
|
end.
|
||||||
|
|
||||||
http_body(Req) ->
|
http_body(Req) ->
|
||||||
{ok, Body, _} = cowboy_req:read_body(Req),
|
{ok, Body, _} = cowboy_req:read_body(Req),
|
||||||
Body.
|
try jsx:decode(Body, [{return_maps, true}])
|
||||||
|
catch error:badarg -> Body
|
||||||
|
end.
|
||||||
|
|
|
@ -48,6 +48,14 @@ start_listener({Proto, Port, Options}) ->
|
||||||
openapi => "3.0.0",
|
openapi => "3.0.0",
|
||||||
info => #{title => "EMQ X API", version => "5.0.0"},
|
info => #{title => "EMQ X API", version => "5.0.0"},
|
||||||
servers => [#{url => ?BASE_PATH}],
|
servers => [#{url => ?BASE_PATH}],
|
||||||
|
tags => [#{
|
||||||
|
name => configs,
|
||||||
|
description => <<"The query string parameter `conf_path` is of jq format.">>,
|
||||||
|
externalDocs => #{
|
||||||
|
description => "Find out more about the path syntax in jq",
|
||||||
|
url => "https://stedolan.github.io/jq/manual/"
|
||||||
|
}
|
||||||
|
}],
|
||||||
components => #{
|
components => #{
|
||||||
schemas => #{},
|
schemas => #{},
|
||||||
securitySchemes => #{
|
securitySchemes => #{
|
||||||
|
|
Loading…
Reference in New Issue