From 66c08bdc8b3b88baf526fa372f6453914499fa9b Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 27 Apr 2022 16:12:51 +0800 Subject: [PATCH 1/3] chore(gw): add default value for lwm2m gateway --- apps/emqx_gateway/src/emqx_gateway_schema.erl | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/apps/emqx_gateway/src/emqx_gateway_schema.erl b/apps/emqx_gateway/src/emqx_gateway_schema.erl index 686ba1cc7..83f51d110 100644 --- a/apps/emqx_gateway/src/emqx_gateway_schema.erl +++ b/apps/emqx_gateway/src/emqx_gateway_schema.erl @@ -103,6 +103,7 @@ fields(gateway) -> fields(stomp) -> [ {frame, sc(ref(stomp_frame))}, + {mountpoint, mountpoint()}, {listeners, sc(ref(tcp_listeners), #{desc => ?DESC(tcp_listeners)})} ] ++ gateway_common_options(); fields(stomp_frame) -> @@ -177,6 +178,7 @@ fields(mqttsn) -> desc => ?DESC(mqttsn_predefined) } )}, + {mountpoint, mountpoint()}, {listeners, sc(ref(udp_listeners), #{desc => ?DESC(udp_listeners)})} ] ++ gateway_common_options(); fields(mqttsn_predefined) -> @@ -235,6 +237,7 @@ fields(coap) -> desc => ?DESC(coap_publish_qos) } )}, + {mountpoint, mountpoint()}, {listeners, sc( ref(udp_listeners), @@ -302,6 +305,7 @@ fields(lwm2m) -> desc => ?DESC(lwm2m_translators) } )}, + {mountpoint, mountpoint("lwm2m/${endpoint_name}/")}, {listeners, sc(ref(udp_listeners), #{desc => ?DESC(udp_listeners)})} ] ++ gateway_common_options(); fields(exproto) -> @@ -322,6 +326,7 @@ fields(exproto) -> desc => ?DESC(exproto_handler) } )}, + {mountpoint, mountpoint()}, {listeners, sc(ref(tcp_udp_listeners), #{desc => ?DESC(tcp_udp_listeners)})} ] ++ gateway_common_options(); fields(exproto_grpc_server) -> @@ -592,15 +597,6 @@ gateway_common_options() -> desc => ?DESC(gateway_common_idle_timeout) } )}, - {mountpoint, - sc( - binary(), - #{ - default => <<>>, - %% TODO: variable support? - desc => ?DESC(gateway_common_mountpoint) - } - )}, {clientinfo_override, sc( ref(clientinfo_override), @@ -609,6 +605,17 @@ gateway_common_options() -> {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_ATOM, authentication_schema()} ]. +mountpoint() -> + mountpoint(<<>>). +mountpoint(Default) -> + sc( + binary(), + #{ + default => Default, + desc => ?DESC(gateway_common_mountpoint) + } + ). + common_listener_opts() -> [ {enable, From 4c8016e76df8dd871206d25f49e16bd93c3e8a5f Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 27 Apr 2022 16:13:15 +0800 Subject: [PATCH 2/3] chore(ignore-file): delete error commit hash --- git-blame-ignore-revs | 2 -- 1 file changed, 2 deletions(-) diff --git a/git-blame-ignore-revs b/git-blame-ignore-revs index a4c32a60d..b21b6a552 100644 --- a/git-blame-ignore-revs +++ b/git-blame-ignore-revs @@ -27,8 +27,6 @@ bf54f571fb8b27e76ada4ca75137d96ce4211d60 628f0bf57909f26208d45a02e33a7fbae8443249 # reformat apps/emqx_slow_subs 83511f8a4c1570a2c89d9c6c5b6f462520199ed8 -# reformat apps/emqx_psk -b168102615e574df15ec6a91304747b4637a9171 # reformat apps/emqx_machine|emqx_plugin_libs|emqx_statsd b4451823350ec46126c49ca915b4b169dd4cf49e # reformat apps/emqx_auto_subscribe and apps/emqx_conf From ff31a5a6a47ff066b304d0a836bdf11ad9e0e86a Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 27 Apr 2022 16:13:51 +0800 Subject: [PATCH 3/3] feat(gw-exproto): save ssl files for server&handler option --- apps/emqx_gateway/src/emqx_gateway_conf.erl | 19 ++++++++- .../src/exproto/emqx_exproto_impl.erl | 2 +- .../test/emqx_gateway_api_SUITE.erl | 42 ++++++++++++++++++- .../test/emqx_gateway_test_utils.erl | 29 +++++++++++++ 4 files changed, 89 insertions(+), 3 deletions(-) diff --git a/apps/emqx_gateway/src/emqx_gateway_conf.erl b/apps/emqx_gateway/src/emqx_gateway_conf.erl index 1ac8c50f8..7cc26906b 100644 --- a/apps/emqx_gateway/src/emqx_gateway_conf.erl +++ b/apps/emqx_gateway/src/emqx_gateway_conf.erl @@ -375,7 +375,8 @@ pre_config_update(_, {update_gateway, GwName, Conf}, RawConf) -> undefined -> badres_gateway(not_found, GwName); _ -> - NConf = maps:without([<<"listeners">>, ?AUTHN_BIN], Conf), + Conf1 = maps:without([<<"listeners">>, ?AUTHN_BIN], Conf), + NConf = tune_gw_certs(fun convert_certs/2, GwName, Conf1), {ok, emqx_map_lib:deep_merge(RawConf, #{GwName => NConf})} end; pre_config_update(_, {unload_gateway, GwName}, RawConf) -> @@ -622,6 +623,13 @@ post_config_update(_, _Req, _NewConfig, _OldConfig, _AppEnvs) -> %%-------------------------------------------------------------------- tune_gw_certs(Fun, GwName, Conf) -> + apply_to_gateway_basic_confs( + Fun, + GwName, + apply_to_listeners(Fun, GwName, Conf) + ). + +apply_to_listeners(Fun, GwName, Conf) -> SubDir = certs_dir(GwName), case maps:get(<<"listeners">>, Conf, undefined) of undefined -> @@ -644,6 +652,15 @@ tune_gw_certs(Fun, GwName, Conf) -> ) end. +apply_to_gateway_basic_confs(Fun, <<"exproto">>, Conf) -> + SvrDir = filename:join(["exproto", "server"]), + HdrDir = filename:join(["exproto", "handler"]), + NServerConf = erlang:apply(Fun, [SvrDir, maps:get(<<"server">>, Conf, #{})]), + NHandlerConf = erlang:apply(Fun, [HdrDir, maps:get(<<"handler">>, Conf, #{})]), + maps:put(<<"handler">>, NHandlerConf, maps:put(<<"server">>, NServerConf, Conf)); +apply_to_gateway_basic_confs(_Fun, _GwName, Conf) -> + Conf. + certs_dir(GwName) when is_binary(GwName) -> GwName. diff --git a/apps/emqx_gateway/src/exproto/emqx_exproto_impl.erl b/apps/emqx_gateway/src/exproto/emqx_exproto_impl.erl index 2c89d32c7..f059ec344 100644 --- a/apps/emqx_gateway/src/exproto/emqx_exproto_impl.erl +++ b/apps/emqx_gateway/src/exproto/emqx_exproto_impl.erl @@ -163,7 +163,7 @@ start_grpc_server(GwName, Options = #{bind := ListenOn}) -> [ {ssl_options, maps:to_list( - maps:without([enable], maps:get(ssl, Options, #{})) + maps:without([enable, handshake_timeout], maps:get(ssl, Options, #{})) )} ] end, diff --git a/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl b/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl index 6bb111e60..2e81c906d 100644 --- a/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl +++ b/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl @@ -25,7 +25,9 @@ assert_confs/2, assert_feilds_apperence/2, request/2, - request/3 + request/3, + ssl_server_opts/0, + ssl_client_opts/0 ] ). @@ -198,6 +200,44 @@ t_gateway_exproto(_) -> assert_confs(GwConf2, ConfResp2), {204, _} = request(delete, "/gateway/exproto"). +t_gateway_exproto_with_ssl(_) -> + {200, Gw} = request(get, "/gateway/exproto"), + assert_gw_unloaded(Gw), + + SslSvrOpts = ssl_server_opts(), + SslCliOpts = ssl_client_opts(), + %% post + GwConf = #{ + name => <<"exproto">>, + server => #{ + bind => <<"9100">>, + ssl => SslSvrOpts#{ + enable => true + } + }, + handler => #{ + address => <<"http://127.0.0.1:9001">>, + ssl => SslCliOpts#{enable => true} + }, + listeners => [ + #{name => <<"def">>, type => <<"tcp">>, bind => <<"7993">>} + ] + }, + {201, _} = request(post, "/gateway", GwConf), + {200, ConfResp} = request(get, "/gateway/exproto"), + assert_confs(GwConf, ConfResp), + %% put + GwConf2 = emqx_map_lib:deep_merge(GwConf, #{ + server => #{ + bind => <<"9200">>, + ssl => SslCliOpts#{enable => true} + } + }), + {200, _} = request(put, "/gateway/exproto", maps:without([name, listeners], GwConf2)), + {200, ConfResp2} = request(get, "/gateway/exproto"), + assert_confs(GwConf2, ConfResp2), + {204, _} = request(delete, "/gateway/exproto"). + t_authn(_) -> GwConf = #{name => <<"stomp">>}, {201, _} = request(post, "/gateway", GwConf), diff --git a/apps/emqx_gateway/test/emqx_gateway_test_utils.erl b/apps/emqx_gateway/test/emqx_gateway_test_utils.erl index e253aed4f..0fed97517 100644 --- a/apps/emqx_gateway/test/emqx_gateway_test_utils.erl +++ b/apps/emqx_gateway/test/emqx_gateway_test_utils.erl @@ -50,8 +50,11 @@ do_assert_confs(_Key, Expected, Effected) when Ks1 ); do_assert_confs(Key, Expected, Effected) when + Key == cacertfile; Key == <<"cacertfile">>; + Key == certfile; Key == <<"certfile">>; + Key == keyfile; Key == <<"keyfile">> -> case Expected == Effected of @@ -118,6 +121,32 @@ request(put = Mth, Path, Body) -> request(post = Mth, Path, Body) -> do_request(Mth, req(Path, [], Body)). +%%-------------------------------------------------------------------- +%% default pems + +ssl_server_opts() -> + #{ + cacertfile => file_content(cert_path("cacert.pem")), + certfile => file_content(cert_path("cert.pem")), + keyfile => file_content(cert_path("key.pem")) + }. + +ssl_client_opts() -> + #{ + cacertfile => file_content(cert_path("cacert.pem")), + certfile => file_content(cert_path("client-cert.pem")), + keyfile => file_content(cert_path("client-key.pem")) + }. + +cert_path(Name) -> + filename:join(["../../lib/emqx/etc/certs/", Name]). + +file_content(Filename) -> + case file:read_file(Filename) of + {ok, Bin} -> Bin; + Err -> error(Err) + end. + do_request(Mth, Req) -> case httpc:request(Mth, Req, [], [{body_format, binary}]) of {ok, {{_Vsn, Code, _Text}, _, Resp}} ->