feat(mgmt): add ignore_readonly qeury-string to PUT /configs API
This commit is contained in:
parent
10625eacac
commit
07cbdc6e90
|
@ -242,7 +242,7 @@ load_config(Bin, Opts) when is_binary(Bin) ->
|
||||||
load_config_from_raw(RawConf0, Opts) ->
|
load_config_from_raw(RawConf0, Opts) ->
|
||||||
SchemaMod = emqx_conf:schema_module(),
|
SchemaMod = emqx_conf:schema_module(),
|
||||||
RawConf1 = emqx_config:upgrade_raw_conf(SchemaMod, RawConf0),
|
RawConf1 = emqx_config:upgrade_raw_conf(SchemaMod, RawConf0),
|
||||||
case check_config(RawConf1) of
|
case check_config(RawConf1, Opts) of
|
||||||
{ok, RawConf} ->
|
{ok, RawConf} ->
|
||||||
%% It has been ensured that the connector is always the first configuration to be updated.
|
%% It has been ensured that the connector is always the first configuration to be updated.
|
||||||
%% However, when deleting the connector, we need to clean up the dependent actions/sources first;
|
%% However, when deleting the connector, we need to clean up the dependent actions/sources first;
|
||||||
|
@ -395,24 +395,28 @@ suggest_msg(#{kind := validation_error, reason := unknown_fields}, Mode) ->
|
||||||
suggest_msg(_, _) ->
|
suggest_msg(_, _) ->
|
||||||
<<"">>.
|
<<"">>.
|
||||||
|
|
||||||
check_config(Conf) ->
|
check_config(Conf0, Opts) ->
|
||||||
case check_keys_is_not_readonly(Conf) of
|
case check_keys_is_not_readonly(Conf0, Opts) of
|
||||||
ok ->
|
{ok, Conf1} ->
|
||||||
Conf1 = emqx_config:fill_defaults(Conf),
|
Conf = emqx_config:fill_defaults(Conf1),
|
||||||
case check_config_schema(Conf1) of
|
case check_config_schema(Conf) of
|
||||||
ok -> {ok, Conf1};
|
ok -> {ok, Conf};
|
||||||
{error, Reason} -> {error, Reason}
|
{error, Reason} -> {error, Reason}
|
||||||
end;
|
end;
|
||||||
Error ->
|
Error ->
|
||||||
Error
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
check_keys_is_not_readonly(Conf) ->
|
check_keys_is_not_readonly(Conf, Opts) ->
|
||||||
|
IgnoreReadonly = maps:get(ignore_readonly, Opts, false),
|
||||||
Keys = maps:keys(Conf),
|
Keys = maps:keys(Conf),
|
||||||
ReadOnlyKeys = [atom_to_binary(K) || K <- ?READONLY_KEYS],
|
ReadOnlyKeys = [atom_to_binary(K) || K <- ?READONLY_KEYS],
|
||||||
case lists:filter(fun(K) -> lists:member(K, Keys) end, ReadOnlyKeys) of
|
case lists:filter(fun(K) -> lists:member(K, Keys) end, ReadOnlyKeys) of
|
||||||
[] ->
|
[] ->
|
||||||
ok;
|
{ok, Conf};
|
||||||
|
BadKeys when IgnoreReadonly ->
|
||||||
|
?SLOG(warning, #{msg => "readonly_root_keys_ignored", keys => BadKeys}),
|
||||||
|
{ok, maps:without(BadKeys, Conf)};
|
||||||
BadKeys ->
|
BadKeys ->
|
||||||
BadKeysStr = lists:join(<<",">>, BadKeys),
|
BadKeysStr = lists:join(<<",">>, BadKeys),
|
||||||
{error, ?UPDATE_READONLY_KEYS_PROHIBITED, BadKeysStr}
|
{error, ?UPDATE_READONLY_KEYS_PROHIBITED, BadKeysStr}
|
||||||
|
|
|
@ -147,7 +147,9 @@ schema("/configs") ->
|
||||||
hoconsc:mk(
|
hoconsc:mk(
|
||||||
hoconsc:enum([replace, merge]),
|
hoconsc:enum([replace, merge]),
|
||||||
#{in => query, default => merge, required => false}
|
#{in => query, default => merge, required => false}
|
||||||
)}
|
)},
|
||||||
|
{ignore_readonly,
|
||||||
|
hoconsc:mk(boolean(), #{in => query, default => false, required => false})}
|
||||||
],
|
],
|
||||||
'requestBody' => #{
|
'requestBody' => #{
|
||||||
content =>
|
content =>
|
||||||
|
@ -361,8 +363,13 @@ configs(get, #{query_string := QueryStr, headers := Headers}, _Req) ->
|
||||||
{ok, <<"text/plain">>} -> get_configs_v2(QueryStr);
|
{ok, <<"text/plain">>} -> get_configs_v2(QueryStr);
|
||||||
{error, _} = Error -> {400, #{code => 'INVALID_ACCEPT', message => ?ERR_MSG(Error)}}
|
{error, _} = Error -> {400, #{code => 'INVALID_ACCEPT', message => ?ERR_MSG(Error)}}
|
||||||
end;
|
end;
|
||||||
configs(put, #{body := Conf, query_string := #{<<"mode">> := Mode}}, _Req) ->
|
configs(put, #{body := Conf, query_string := #{<<"mode">> := Mode} = QS}, _Req) ->
|
||||||
case emqx_conf_cli:load_config(Conf, #{mode => Mode, log => none}) of
|
IngnoreReadonly = maps:get(<<"ignore_readonly">>, QS, false),
|
||||||
|
case
|
||||||
|
emqx_conf_cli:load_config(Conf, #{
|
||||||
|
mode => Mode, log => none, ignore_readonly => IngnoreReadonly
|
||||||
|
})
|
||||||
|
of
|
||||||
ok ->
|
ok ->
|
||||||
{200};
|
{200};
|
||||||
%% bad hocon format
|
%% bad hocon format
|
||||||
|
|
|
@ -331,7 +331,7 @@ t_configs_key(_Config) ->
|
||||||
Log
|
Log
|
||||||
),
|
),
|
||||||
Log1 = emqx_utils_maps:deep_put([<<"log">>, <<"console">>, <<"level">>], Log, <<"error">>),
|
Log1 = emqx_utils_maps:deep_put([<<"log">>, <<"console">>, <<"level">>], Log, <<"error">>),
|
||||||
?assertEqual(<<>>, update_configs_with_binary(iolist_to_binary(hocon_pp:do(Log1, #{})))),
|
?assertEqual({ok, <<>>}, update_configs_with_binary(iolist_to_binary(hocon_pp:do(Log1, #{})))),
|
||||||
?assertEqual(<<"error">>, read_conf([<<"log">>, <<"console">>, <<"level">>])),
|
?assertEqual(<<"error">>, read_conf([<<"log">>, <<"console">>, <<"level">>])),
|
||||||
BadLog = emqx_utils_maps:deep_put([<<"log">>, <<"console">>, <<"level">>], Log, <<"erro1r">>),
|
BadLog = emqx_utils_maps:deep_put([<<"log">>, <<"console">>, <<"level">>], Log, <<"erro1r">>),
|
||||||
{error, Error} = update_configs_with_binary(iolist_to_binary(hocon_pp:do(BadLog, #{}))),
|
{error, Error} = update_configs_with_binary(iolist_to_binary(hocon_pp:do(BadLog, #{}))),
|
||||||
|
@ -358,6 +358,7 @@ t_configs_key(_Config) ->
|
||||||
ReadOnlyBin = iolist_to_binary(hocon_pp:do(ReadOnlyConf, #{})),
|
ReadOnlyBin = iolist_to_binary(hocon_pp:do(ReadOnlyConf, #{})),
|
||||||
{error, ReadOnlyError} = update_configs_with_binary(ReadOnlyBin),
|
{error, ReadOnlyError} = update_configs_with_binary(ReadOnlyBin),
|
||||||
?assertEqual(<<"{\"errors\":\"Cannot update read-only key 'cluster'.\"}">>, ReadOnlyError),
|
?assertEqual(<<"{\"errors\":\"Cannot update read-only key 'cluster'.\"}">>, ReadOnlyError),
|
||||||
|
?assertMatch({ok, <<>>}, update_configs_with_binary(ReadOnlyBin, _InogreReadonly = true)),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_get_configs_in_different_accept(_Config) ->
|
t_get_configs_in_different_accept(_Config) ->
|
||||||
|
@ -407,7 +408,7 @@ t_create_webhook_v1_bridges_api(Config) ->
|
||||||
WebHookFile = filename:join(?config(data_dir, Config), "webhook_v1.conf"),
|
WebHookFile = filename:join(?config(data_dir, Config), "webhook_v1.conf"),
|
||||||
?assertMatch({ok, _}, hocon:files([WebHookFile])),
|
?assertMatch({ok, _}, hocon:files([WebHookFile])),
|
||||||
{ok, WebHookBin} = file:read_file(WebHookFile),
|
{ok, WebHookBin} = file:read_file(WebHookFile),
|
||||||
?assertEqual(<<>>, update_configs_with_binary(WebHookBin)),
|
?assertEqual({ok, <<>>}, update_configs_with_binary(WebHookBin)),
|
||||||
Actions =
|
Actions =
|
||||||
#{
|
#{
|
||||||
<<"http">> =>
|
<<"http">> =>
|
||||||
|
@ -557,14 +558,25 @@ get_configs_with_binary(Key, Node) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
update_configs_with_binary(Bin) ->
|
update_configs_with_binary(Bin) ->
|
||||||
Path = emqx_mgmt_api_test_util:api_path(["configs"]),
|
update_configs_with_binary(Bin, _InogreReadonly = undefined).
|
||||||
|
|
||||||
|
update_configs_with_binary(Bin, IgnoreReadonly) ->
|
||||||
|
Path =
|
||||||
|
case IgnoreReadonly of
|
||||||
|
undefined ->
|
||||||
|
emqx_mgmt_api_test_util:api_path(["configs"]);
|
||||||
|
Boolean ->
|
||||||
|
emqx_mgmt_api_test_util:api_path([
|
||||||
|
"configs?ignore_readonly=" ++ atom_to_list(Boolean)
|
||||||
|
])
|
||||||
|
end,
|
||||||
Auth = emqx_mgmt_api_test_util:auth_header_(),
|
Auth = emqx_mgmt_api_test_util:auth_header_(),
|
||||||
Headers = [{"accept", "text/plain"}, Auth],
|
Headers = [{"accept", "text/plain"}, Auth],
|
||||||
case httpc:request(put, {Path, Headers, "text/plain", Bin}, [], [{body_format, binary}]) of
|
case httpc:request(put, {Path, Headers, "text/plain", Bin}, [], [{body_format, binary}]) of
|
||||||
{ok, {{"HTTP/1.1", Code, _}, _Headers, Body}} when
|
{ok, {{"HTTP/1.1", Code, _}, _Headers, Body}} when
|
||||||
Code >= 200 andalso Code =< 299
|
Code >= 200 andalso Code =< 299
|
||||||
->
|
->
|
||||||
Body;
|
{ok, Body};
|
||||||
{ok, {{"HTTP/1.1", 400, _}, _Headers, Body}} ->
|
{ok, {{"HTTP/1.1", 400, _}, _Headers, Body}} ->
|
||||||
{error, Body};
|
{error, Body};
|
||||||
Error ->
|
Error ->
|
||||||
|
|
Loading…
Reference in New Issue