Merge pull request #11311 from zhongwencool/improve-failed-message

chore: add more detail msg for merging failed
This commit is contained in:
zhongwencool 2023-07-20 22:24:28 +08:00 committed by GitHub
commit 5240ba70d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 31 deletions

View File

@ -213,10 +213,20 @@ load_config(Bin, ReplaceOrMerge) when is_binary(Bin) ->
load_config_from_raw(RawConf, ReplaceOrMerge) -> load_config_from_raw(RawConf, ReplaceOrMerge) ->
case check_config(RawConf) of case check_config(RawConf) of
ok -> ok ->
lists:foreach( Error =
fun({K, V}) -> update_config_cluster(K, V, ReplaceOrMerge) end, lists:filtermap(
to_sorted_list(RawConf) fun({K, V}) ->
); case update_config_cluster(K, V, ReplaceOrMerge) of
ok -> false;
{error, Msg} -> {true, Msg}
end
end,
to_sorted_list(RawConf)
),
case iolist_to_binary(Error) of
<<"">> -> ok;
ErrorBin -> {error, ErrorBin}
end;
{error, ?UPDATE_READONLY_KEYS_PROHIBITED = Reason} -> {error, ?UPDATE_READONLY_KEYS_PROHIBITED = Reason} ->
emqx_ctl:warning("load config failed~n~ts~n", [Reason]), emqx_ctl:warning("load config failed~n~ts~n", [Reason]),
emqx_ctl:warning( emqx_ctl:warning(
@ -234,34 +244,63 @@ load_config_from_raw(RawConf, ReplaceOrMerge) ->
{error, Errors} {error, Errors}
end. end.
update_config_cluster(?EMQX_AUTHORIZATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge) -> update_config_cluster(?EMQX_AUTHORIZATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge = Mode) ->
check_res(Key, emqx_authz:merge(Conf)); check_res(Key, emqx_authz:merge(Conf), Conf, Mode);
update_config_cluster(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge) -> update_config_cluster(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge = Mode) ->
check_res(Key, emqx_authn:merge_config(Conf)); check_res(Key, emqx_authn:merge_config(Conf), Conf, Mode);
update_config_cluster(Key, NewConf, merge) -> update_config_cluster(Key, NewConf, merge = Mode) ->
Merged = merge_conf(Key, NewConf), Merged = merge_conf(Key, NewConf),
check_res(Key, emqx_conf:update([Key], Merged, ?OPTIONS)); check_res(Key, emqx_conf:update([Key], Merged, ?OPTIONS), NewConf, Mode);
update_config_cluster(Key, Value, replace) -> update_config_cluster(Key, Value, replace = Mode) ->
check_res(Key, emqx_conf:update([Key], Value, ?OPTIONS)). check_res(Key, emqx_conf:update([Key], Value, ?OPTIONS), Value, Mode).
-define(LOCAL_OPTIONS, #{rawconf_with_defaults => true, persistent => false}). -define(LOCAL_OPTIONS, #{rawconf_with_defaults => true, persistent => false}).
update_config_local(?EMQX_AUTHORIZATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge) -> update_config_local(?EMQX_AUTHORIZATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge = Mode) ->
check_res(node(), Key, emqx_authz:merge_local(Conf, ?LOCAL_OPTIONS)); check_res(node(), Key, emqx_authz:merge_local(Conf, ?LOCAL_OPTIONS), Conf, Mode);
update_config_local(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge) -> update_config_local(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY = Key, Conf, merge = Mode) ->
check_res(node(), Key, emqx_authn:merge_config_local(Conf, ?LOCAL_OPTIONS)); check_res(node(), Key, emqx_authn:merge_config_local(Conf, ?LOCAL_OPTIONS), Conf, Mode);
update_config_local(Key, NewConf, merge) -> update_config_local(Key, NewConf, merge = Mode) ->
Merged = merge_conf(Key, NewConf), Merged = merge_conf(Key, NewConf),
check_res(node(), Key, emqx:update_config([Key], Merged, ?LOCAL_OPTIONS)); check_res(node(), Key, emqx:update_config([Key], Merged, ?LOCAL_OPTIONS), NewConf, Mode);
update_config_local(Key, Value, replace) -> update_config_local(Key, Value, replace = Mode) ->
check_res(node(), Key, emqx:update_config([Key], Value, ?LOCAL_OPTIONS)). check_res(node(), Key, emqx:update_config([Key], Value, ?LOCAL_OPTIONS), Value, Mode).
check_res(Key, Res) -> check_res(cluster, Key, Res). check_res(Key, Res, Conf, Mode) -> check_res(cluster, Key, Res, Conf, Mode).
check_res(Mode, Key, {ok, _} = Res) -> check_res(Node, Key, {ok, _}, _Conf, _Mode) ->
emqx_ctl:print("load ~ts in ~p ok~n", [Key, Mode]), emqx_ctl:print("load ~ts on ~p ok~n", [Key, Node]),
Res; ok;
check_res(_Mode, Key, {error, Reason} = Res) -> check_res(_Node, Key, {error, Reason}, Conf, Mode) ->
emqx_ctl:warning("load ~ts failed~n~p~n", [Key, Reason]), Warning =
Res. "Can't ~ts the new configurations!~n"
"Root key: ~ts~n"
"Reason: ~p~n",
emqx_ctl:warning(Warning, [Mode, Key, Reason]),
ActiveMsg0 =
"The effective configurations:~n"
"```~n"
"~ts```~n~n",
ActiveMsg = io_lib:format(ActiveMsg0, [hocon_pp:do(#{Key => emqx_conf:get_raw([Key])}, #{})]),
FailedMsg0 =
"Try to ~ts with:~n"
"```~n"
"~ts```~n",
FailedMsg = io_lib:format(FailedMsg0, [Mode, hocon_pp:do(#{Key => Conf}, #{})]),
SuggestMsg = suggest_msg(Mode),
Msg = iolist_to_binary([ActiveMsg, FailedMsg, SuggestMsg]),
emqx_ctl:print("~ts", [Msg]),
{error, iolist_to_binary([Warning, Msg])}.
suggest_msg(Mode) when Mode == merge orelse Mode == replace ->
RetryMode =
case Mode of
merge -> "replace";
replace -> "merge"
end,
io_lib:format(
"Tips: There may be some conflicts in the new configuration under `~ts` mode,~n"
"Please retry with the `~ts` mode.~n",
[Mode, RetryMode]
).
check_config(Conf) -> check_config(Conf) ->
case check_keys_is_not_readonly(Conf) of case check_keys_is_not_readonly(Conf) of
@ -349,7 +388,7 @@ filter_readonly_config(Raw) ->
reload_config(AllConf, ReplaceOrMerge) -> reload_config(AllConf, ReplaceOrMerge) ->
Fold = fun({Key, Conf}, Acc) -> Fold = fun({Key, Conf}, Acc) ->
case update_config_local(Key, Conf, ReplaceOrMerge) of case update_config_local(Key, Conf, ReplaceOrMerge) of
{ok, _} -> ok ->
Acc; Acc;
Error -> Error ->
?SLOG(error, #{ ?SLOG(error, #{

View File

@ -346,8 +346,7 @@ configs(get, #{query_string := QueryStr, headers := Headers}, _Req) ->
configs(put, #{body := Conf, query_string := #{<<"mode">> := Mode}}, _Req) -> configs(put, #{body := Conf, query_string := #{<<"mode">> := Mode}}, _Req) ->
case emqx_conf_cli:load_config(Conf, Mode) of case emqx_conf_cli:load_config(Conf, Mode) of
ok -> {200}; ok -> {200};
{error, [{_, Reason}]} -> {400, #{code => 'UPDATE_FAILED', message => ?ERR_MSG(Reason)}}; {error, Msg} -> {400, #{<<"content-type">> => <<"text/plain">>}, Msg}
{error, Errors} -> {400, #{code => 'UPDATE_FAILED', message => ?ERR_MSG(Errors)}}
end. end.
find_suitable_accept(Headers, Preferences) when is_list(Preferences), length(Preferences) > 0 -> find_suitable_accept(Headers, Preferences) when is_list(Preferences), length(Preferences) > 0 ->

View File

@ -506,7 +506,7 @@ fields(local_status_enabled) ->
)}, )},
{"process", {"process",
mk( mk(
hoconsc:union([rebalance, evacuation]), hoconsc:enum([rebalance, evacuation]),
#{ #{
desc => ?DESC(local_status_process), desc => ?DESC(local_status_process),
required => true required => true