diff --git a/CHANGES-4.3.md b/CHANGES-4.3.md index 7c421f75e..3e84d406d 100644 --- a/CHANGES-4.3.md +++ b/CHANGES-4.3.md @@ -10,6 +10,15 @@ File format: - One list item per change topic Change log ends with a list of github PRs +## v4.3.13 + +### Enhancements + +* CLI `emqx_ctl pem_cache clean` to force purge x509 certificate cache, + to force an immediate reload of all certificates after the files are updated on disk. + +### Bug fixes + ## v4.3.12 ### Important changes diff --git a/apps/emqx_management/src/emqx_management.app.src b/apps/emqx_management/src/emqx_management.app.src index e8b235be7..bee65781a 100644 --- a/apps/emqx_management/src/emqx_management.app.src +++ b/apps/emqx_management/src/emqx_management.app.src @@ -1,6 +1,6 @@ {application, emqx_management, [{description, "EMQ X Management API and CLI"}, - {vsn, "4.3.10"}, % strict semver, bump manually! + {vsn, "4.3.11"}, % strict semver, bump manually! {modules, []}, {registered, [emqx_management_sup]}, {applications, [kernel,stdlib,minirest]}, diff --git a/apps/emqx_management/src/emqx_mgmt.erl b/apps/emqx_management/src/emqx_mgmt.erl index e68a6163f..2a9636b6b 100644 --- a/apps/emqx_management/src/emqx_mgmt.erl +++ b/apps/emqx_management/src/emqx_mgmt.erl @@ -51,6 +51,10 @@ , set_quota_policy/2 ]). +-export([ clean_pem_cache/0 + , clean_pem_cache/1 + ]). + %% Internal funcs -export([call_client/3]). @@ -254,15 +258,17 @@ clean_acl_cache(Node, ClientId) -> rpc_call(Node, clean_acl_cache, [Node, ClientId]). clean_acl_cache_all() -> - Results = [{Node, clean_acl_cache_all(Node)} || Node <- ekka_mnesia:running_nodes()], - case lists:filter(fun({_Node, Item}) -> Item =/= ok end, Results) of + for_nodes(fun clean_acl_cache_all/1). + +for_nodes(F) -> + Results = [{Node, F(Node)} || Node <- ekka_mnesia:running_nodes()], + case lists:filter(fun({_Node, Res}) -> Res =/= ok end, Results) of [] -> ok; BadNodes -> {error, BadNodes} end. clean_acl_cache_all(Node) when Node =:= node() -> emqx_acl_cache:drain_cache(); - clean_acl_cache_all(Node) -> rpc_call(Node, clean_acl_cache_all, [Node]). @@ -272,6 +278,15 @@ set_ratelimit_policy(ClientId, Policy) -> set_quota_policy(ClientId, Policy) -> call_client(ClientId, {quota, Policy}). +clean_pem_cache() -> + for_nodes(fun clean_pem_cache/1). + +clean_pem_cache(Node) when Node =:= node() -> + _ = ssl_pem_cache:clear(), + ok; +clean_pem_cache(Node) -> + rpc_call(Node, ?FUNCTION_NAME, [Node]). + %% @private call_client(ClientId, Req) -> Results = [call_client(Node, ClientId, Req) || Node <- ekka_mnesia:running_nodes()], diff --git a/apps/emqx_management/src/emqx_mgmt_cli.erl b/apps/emqx_management/src/emqx_mgmt_cli.erl index 95f5121cd..92dc4c578 100644 --- a/apps/emqx_management/src/emqx_mgmt_cli.erl +++ b/apps/emqx_management/src/emqx_mgmt_cli.erl @@ -40,6 +40,7 @@ , mgmt/1 , data/1 , acl/1 + , pem_cache/1 ]). -define(PROC_INFOKEYS, [status, @@ -576,7 +577,7 @@ data(_) -> %% @doc acl Command acl(["cache-clean", "node", Node]) -> - case emqx_mgmt:clean_acl_cache_all(erlang:list_to_existing_atom(Node)) of + case for_node(fun emqx_mgmt:clean_acl_cache_all/1, Node) of ok -> emqx_ctl:print("ACL cache drain started on node ~s.~n", [Node]); {error, Reason} -> @@ -600,6 +601,15 @@ acl(_) -> {"acl cache-clean ", "Clears acl cache for given client"} ]). +pem_cache(["clean", "all"]) -> + with_log(fun emqx_mgmt:clean_pem_cache/0, "PEM cache clean"); +pem_cache(["clean", "node", Node]) -> + with_log(fun() -> for_node(fun emqx_mgmt:clean_pem_cache/1, Node) end, "PEM cache clean"); +pem_cache(_) -> + emqx_ctl:usage([{"pem_cache clean all", "Clears x509 certificate cache on all nodes"}, + {"pem_cache clean node ", "Clears x509 certificate cache on given node"} + ]). + %%-------------------------------------------------------------------- %% Dump ETS %%-------------------------------------------------------------------- @@ -721,3 +731,20 @@ restart_http_listener(Scheme, AppName) -> http_mod_name(emqx_management) -> emqx_mgmt_http; http_mod_name(Name) -> Name. + +for_node(Fun, Node) -> + try list_to_existing_atom(Node) of + NodeAtom -> + Fun(NodeAtom) + catch + error : badarg -> + {error, unknown_node} + end. + +with_log(Fun, Msg) -> + case Fun() of + ok -> + emqx_ctl:print("~s OK~n", [Msg]); + {error, Reason} -> + emqx_ctl:print("~s FAILED~n~p~n", [Msg, Reason]) + end. diff --git a/lib-ce/emqx_dashboard/src/emqx_dashboard.app.src b/lib-ce/emqx_dashboard/src/emqx_dashboard.app.src index ea5ecdd79..efd362156 100644 --- a/lib-ce/emqx_dashboard/src/emqx_dashboard.app.src +++ b/lib-ce/emqx_dashboard/src/emqx_dashboard.app.src @@ -1,6 +1,6 @@ {application, emqx_dashboard, [{description, "EMQ X Web Dashboard"}, - {vsn, "4.3.8"}, % strict semver, bump manually! + {vsn, "4.3.9"}, % strict semver, bump manually! {modules, []}, {registered, [emqx_dashboard_sup]}, {applications, [kernel,stdlib,mnesia,minirest]},