From 0eed01abee30a7c934b940cd6f89e0642328e1f9 Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Fri, 22 Sep 2023 16:03:28 +0800 Subject: [PATCH 1/6] fix: create ssl listener return 500 crash --- .../src/emqx_mgmt_api_listeners.erl | 36 ++++++++++--------- .../test/emqx_mgmt_api_listeners_SUITE.erl | 14 ++++++-- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl index 90fb1f98e..8295047b9 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl @@ -266,7 +266,7 @@ fields(node_status) -> })}, {status, ?HOCON(?R_REF(status))} ]; -fields({Type, with_name}) -> +fields("with_name_" ++ Type) -> listener_struct_with_name(Type); fields(Type) -> listener_struct(Type). @@ -308,7 +308,7 @@ listener_union_member_selector(Opts) -> create_listener_schema(Opts) -> Schemas = [ - ?R_REF(Mod, {Type, with_name}) + ?R_REF(Mod, "with_name_" ++ Type) || #{ref := ?R_REF(Mod, Type)} <- listeners_info(Opts) ], Example = maps:remove(id, tcp_schema_example()), @@ -399,7 +399,7 @@ list_listeners(get, #{query_string := Query}) -> end, {200, listener_status_by_id(NodeL)}; list_listeners(post, #{body := Body}) -> - create_listener(Body). + create_listener(name, Body). crud_listeners_by_id(get, #{bindings := #{id := Id}}) -> case find_listeners_by_id(Id) of @@ -407,7 +407,7 @@ crud_listeners_by_id(get, #{bindings := #{id := Id}}) -> [L] -> {200, L} end; crud_listeners_by_id(put, #{bindings := #{id := Id}, body := Body0}) -> - case parse_listener_conf(Body0) of + case parse_listener_conf(id, Body0) of {Id, Type, Name, Conf} -> case get_raw(Type, Name) of undefined -> @@ -430,7 +430,7 @@ crud_listeners_by_id(put, #{bindings := #{id := Id}, body := Body0}) -> {400, #{code => 'BAD_LISTENER_ID', message => ?LISTENER_ID_INCONSISTENT}} end; crud_listeners_by_id(post, #{body := Body}) -> - create_listener(Body); + create_listener(id, Body); crud_listeners_by_id(delete, #{bindings := #{id := Id}}) -> {ok, #{type := Type, name := Name}} = emqx_listeners:parse_listener_id(Id), case find_listeners_by_id(Id) of @@ -441,11 +441,10 @@ crud_listeners_by_id(delete, #{bindings := #{id := Id}}) -> {404, #{code => 'BAD_LISTENER_ID', message => ?LISTENER_NOT_FOUND}} end. -parse_listener_conf(Conf0) -> +parse_listener_conf(id, Conf0) -> Conf1 = maps:without([<<"running">>, <<"current_connections">>], Conf0), {TypeBin, Conf2} = maps:take(<<"type">>, Conf1), TypeAtom = binary_to_existing_atom(TypeBin), - case maps:take(<<"id">>, Conf2) of {IdBin, Conf3} -> {ok, #{type := Type, name := Name}} = emqx_listeners:parse_listener_id(IdBin), @@ -454,13 +453,18 @@ parse_listener_conf(Conf0) -> false -> {error, listener_type_inconsistent} end; _ -> - case maps:take(<<"name">>, Conf2) of - {Name, Conf3} -> - IdBin = <>, - {binary_to_atom(IdBin), TypeAtom, Name, Conf3}; - _ -> - {error, listener_config_invalid} - end + {error, listener_config_invalid} + end; +parse_listener_conf(name, Conf0) -> + Conf1 = maps:without([<<"running">>, <<"current_connections">>], Conf0), + {TypeBin, Conf2} = maps:take(<<"type">>, Conf1), + TypeAtom = binary_to_existing_atom(TypeBin), + case maps:take(<<"name">>, Conf2) of + {Name, Conf3} -> + IdBin = <>, + {binary_to_atom(IdBin), TypeAtom, Name, Conf3}; + _ -> + {error, listener_config_invalid} end. stop_listeners_by_id(Method, Body = #{bindings := Bindings}) -> @@ -832,8 +836,8 @@ tcp_schema_example() -> type => tcp }. -create_listener(Body) -> - case parse_listener_conf(Body) of +create_listener(From, Body) -> + case parse_listener_conf(From, Body) of {Id, Type, Name, Conf} -> case create(Type, Name, Conf) of {ok, #{raw_config := _RawConf}} -> diff --git a/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl b/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl index 96ec8f2de..53579406f 100644 --- a/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl +++ b/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl @@ -238,7 +238,6 @@ t_clear_certs(Config) when is_list(Config) -> NewConf2 = emqx_utils_maps:deep_put( [<<"ssl_options">>, <<"keyfile">>], NewConf, cert_file("keyfile") ), - _ = request(post, NewPath, [], NewConf2), ListResult1 = list_pem_dir("ssl", "clear"), ?assertMatch({ok, [_, _]}, ListResult1), @@ -251,7 +250,7 @@ t_clear_certs(Config) when is_list(Config) -> _ = emqx_tls_certfile_gc:force(), ListResult2 = list_pem_dir("ssl", "clear"), - %% make sure the old cret file is deleted + %% make sure the old cert file is deleted ?assertMatch({ok, [_, _]}, ListResult2), {ok, ResultList1} = ListResult1, @@ -273,6 +272,17 @@ t_clear_certs(Config) when is_list(Config) -> _ = delete(NewPath), _ = emqx_tls_certfile_gc:force(), ?assertMatch({error, enoent}, list_pem_dir("ssl", "clear")), + + %% test create listeners without id in path + NewPath1 = emqx_mgmt_api_test_util:api_path(["listeners"]), + NewConf3 = maps:remove(<<"id">>, NewConf2#{<<"name">> => <<"clear">>}), + ?assertNotMatch({error, {"HTTP/1.1", 400, _}}, request(post, NewPath1, [], NewConf3)), + ListResult3 = list_pem_dir("ssl", "clear"), + ?assertMatch({ok, [_, _]}, ListResult3), + _ = delete(NewPath), + _ = emqx_tls_certfile_gc:force(), + ?assertMatch({error, enoent}, list_pem_dir("ssl", "clear")), + ok. get_tcp_listeners(Node) -> From ff7f37ccf5e38fafdd6d77a8652308b3594faeeb Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Mon, 25 Sep 2023 13:22:41 -0300 Subject: [PATCH 2/6] test(cth): allow defining schema to load for app --- apps/emqx/test/emqx_cth_suite.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/emqx/test/emqx_cth_suite.erl b/apps/emqx/test/emqx_cth_suite.erl index 24105b2b4..5cbca3243 100644 --- a/apps/emqx/test/emqx_cth_suite.erl +++ b/apps/emqx/test/emqx_cth_suite.erl @@ -52,7 +52,7 @@ %% (e.g. in `init_per_suite/1` / `init_per_group/2`), providing the appspecs %% and unique work dir for the testrun (e.g. `work_dir/1`). Save the result %% in a context. -%% 3. Call `emqx_cth_sutie:stop/1` to stop the applications after the testrun +%% 3. Call `emqx_cth_suite:stop/1` to stop the applications after the testrun %% finishes (e.g. in `end_per_suite/1` / `end_per_group/2`), providing the %% result from step 2. -module(emqx_cth_suite). @@ -245,6 +245,9 @@ spec_fmt(ffun, {_, X}) -> X. maybe_configure_app(_App, #{config := false}) -> ok; +maybe_configure_app(_App, AppConfig = #{schema_mod := SchemaModule}) when is_atom(SchemaModule) -> + #{config := Config} = AppConfig, + configure_app(SchemaModule, Config); maybe_configure_app(App, #{config := Config}) -> case app_schema(App) of {ok, SchemaModule} -> From 5d212e1086e9dcbc31001bd5c4e6be039866977f Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Mon, 25 Sep 2023 13:23:39 -0300 Subject: [PATCH 3/6] fix(audit): only support audit log on enterprise edition Fixes https://emqx.atlassian.net/browse/EMQX-11039 --- apps/emqx_conf/src/emqx_conf_schema.erl | 57 +------------- .../emqx_conf/test/emqx_conf_logger_SUITE.erl | 11 +-- .../emqx_conf/test/emqx_conf_schema_tests.erl | 19 +---- .../src/emqx_enterprise_schema.erl | 77 ++++++++++++++++++- .../test/emqx_enterprise_schema_SUITE.erl | 52 +++++++++++++ .../test/emqx_enterprise_schema_tests.erl | 35 +++++++++ rel/i18n/emqx_conf_schema.hocon | 3 - 7 files changed, 169 insertions(+), 85 deletions(-) diff --git a/apps/emqx_conf/src/emqx_conf_schema.erl b/apps/emqx_conf/src/emqx_conf_schema.erl index f1bfc3d31..27799fa93 100644 --- a/apps/emqx_conf/src/emqx_conf_schema.erl +++ b/apps/emqx_conf/src/emqx_conf_schema.erl @@ -43,6 +43,9 @@ ]). -export([conf_get/2, conf_get/3, keys/2, filter/1]). +%% internal exports for `emqx_enterprise_schema' only. +-export([ensure_unicode_path/2, convert_rotation/2, log_handler_common_confs/2]). + %% Static apps which merge their configs into the merged emqx.conf %% The list can not be made a dynamic read at run-time as it is used %% by nodetool to generate app.