feat: support HAProxy protocol for dashboard API
This commit is contained in:
parent
74ae7c4264
commit
fb763ecebd
|
@ -92,6 +92,16 @@ Note: `sample_interval` should be a divisor of 60."""
|
|||
zh: "IPv6 only"
|
||||
}
|
||||
}
|
||||
proxy_header {
|
||||
desc {
|
||||
en: "Enable support for HAProxy header. Be aware once enabled regular HTTP requests can't be handled anymore."
|
||||
zh: "[FIXME]"
|
||||
}
|
||||
label: {
|
||||
en: "Enable support for HAProxy header"
|
||||
zh: "[FIXME]"
|
||||
}
|
||||
}
|
||||
desc_dashboard {
|
||||
desc {
|
||||
en: "Configuration for EMQX dashboard."
|
||||
|
|
|
@ -92,8 +92,8 @@ start_listeners(Listeners) ->
|
|||
},
|
||||
Res =
|
||||
lists:foldl(
|
||||
fun({Name, Protocol, Bind, RanchOptions}, Acc) ->
|
||||
Minirest = BaseMinirest#{protocol => Protocol},
|
||||
fun({Name, Protocol, Bind, RanchOptions, ProtoOpts}, Acc) ->
|
||||
Minirest = BaseMinirest#{protocol => Protocol, protocol_options => ProtoOpts},
|
||||
case minirest:start(Name, RanchOptions, Minirest) of
|
||||
{ok, _} ->
|
||||
?ULOG("Listener ~ts on ~ts started.~n", [
|
||||
|
@ -125,7 +125,7 @@ stop_listeners(Listeners) ->
|
|||
?SLOG(warning, #{msg => "stop_listener_failed", name => Name, port => Port})
|
||||
end
|
||||
end
|
||||
|| {Name, _, Port, _} <- listeners(Listeners)
|
||||
|| {Name, _, Port, _, _} <- listeners(Listeners)
|
||||
],
|
||||
ok.
|
||||
|
||||
|
@ -164,7 +164,13 @@ listeners(Listeners) ->
|
|||
maps:get(enable, Conf) andalso
|
||||
begin
|
||||
{Conf1, Bind} = ip_port(Conf),
|
||||
{true, {listener_name(Protocol), Protocol, Bind, ranch_opts(Conf1)}}
|
||||
{true, {
|
||||
listener_name(Protocol),
|
||||
Protocol,
|
||||
Bind,
|
||||
ranch_opts(Conf1),
|
||||
proto_opts(Conf1)
|
||||
}}
|
||||
end
|
||||
end,
|
||||
maps:to_list(Listeners)
|
||||
|
@ -197,7 +203,7 @@ ranch_opts(Options) ->
|
|||
SocketOpts = maps:fold(
|
||||
fun filter_false/3,
|
||||
[],
|
||||
maps:without([enable, inet6, ipv6_v6only | Keys], Options)
|
||||
maps:without([enable, inet6, ipv6_v6only, proxy_header | Keys], Options)
|
||||
),
|
||||
InetOpts =
|
||||
case Options of
|
||||
|
@ -210,6 +216,9 @@ ranch_opts(Options) ->
|
|||
end,
|
||||
RanchOpts#{socket_opts => InetOpts ++ SocketOpts}.
|
||||
|
||||
proto_opts(Options) ->
|
||||
maps:with([proxy_header], Options).
|
||||
|
||||
filter_false(_K, false, S) -> S;
|
||||
filter_false(K, V, S) -> [{K, V} | S].
|
||||
|
||||
|
|
|
@ -160,6 +160,14 @@ common_listener_fields() ->
|
|||
default => false,
|
||||
desc => ?DESC(ipv6_v6only)
|
||||
}
|
||||
)},
|
||||
{"proxy_header",
|
||||
?HOCON(
|
||||
boolean(),
|
||||
#{
|
||||
desc => ?DESC(proxy_header),
|
||||
default => false
|
||||
}
|
||||
)}
|
||||
].
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
-export([
|
||||
set_default_config/0,
|
||||
set_default_config/1,
|
||||
set_default_config/2,
|
||||
request/2,
|
||||
request/3,
|
||||
request/4,
|
||||
|
@ -36,6 +37,9 @@ set_default_config() ->
|
|||
set_default_config(<<"admin">>).
|
||||
|
||||
set_default_config(DefaultUsername) ->
|
||||
set_default_config(DefaultUsername, false).
|
||||
|
||||
set_default_config(DefaultUsername, HAProxyEnabled) ->
|
||||
Config = #{
|
||||
listeners => #{
|
||||
http => #{
|
||||
|
@ -46,7 +50,8 @@ set_default_config(DefaultUsername) ->
|
|||
max_connections => 512,
|
||||
num_acceptors => 4,
|
||||
send_timeout => 5000,
|
||||
backlog => 512
|
||||
backlog => 512,
|
||||
proxy_header => HAProxyEnabled
|
||||
}
|
||||
},
|
||||
default_username => DefaultUsername,
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
%%--------------------------------------------------------------------
|
||||
%% Copyright (c) 2020-2023 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
%% You may obtain a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing, software
|
||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_dashboard_haproxy_SUITE).
|
||||
|
||||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-import(
|
||||
emqx_common_test_http,
|
||||
[
|
||||
request_api/3
|
||||
]
|
||||
).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include("emqx_dashboard.hrl").
|
||||
|
||||
-define(HOST, "http://127.0.0.1:18083").
|
||||
|
||||
-define(BASE_PATH, "/").
|
||||
|
||||
all() ->
|
||||
emqx_common_test_helpers:all(?MODULE).
|
||||
|
||||
end_suite() ->
|
||||
end_suite([]).
|
||||
|
||||
end_suite(Apps) ->
|
||||
application:unload(emqx_management),
|
||||
mnesia:clear_table(?ADMIN),
|
||||
emqx_common_test_helpers:stop_apps(Apps ++ [emqx_dashboard]).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
emqx_common_test_helpers:start_apps(
|
||||
[emqx_management, emqx_dashboard],
|
||||
fun set_special_configs/1
|
||||
),
|
||||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
emqx_common_test_helpers:stop_apps([emqx_dashboard, emqx_management]),
|
||||
mria:stop().
|
||||
|
||||
set_special_configs(emqx_dashboard) ->
|
||||
emqx_dashboard_api_test_helpers:set_default_config(<<"admin">>, true),
|
||||
ok;
|
||||
set_special_configs(_) ->
|
||||
ok.
|
||||
|
||||
disabled_t_status(_) ->
|
||||
%% no easy way since httpc doesn't support emulating the haproxy protocol
|
||||
{ok, 200, _Res} = http_get(["status"]),
|
||||
ok.
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% Internal functions
|
||||
%%------------------------------------------------------------------------------
|
||||
http_get(Parts) ->
|
||||
request_api(get, api_path(Parts), auth_header_()).
|
||||
|
||||
auth_header_() ->
|
||||
auth_header_(<<"admin">>, <<"public">>).
|
||||
|
||||
auth_header_(Username, Password) ->
|
||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
||||
|
||||
api_path(Parts) ->
|
||||
?HOST ++ filename:join([?BASE_PATH | Parts]).
|
|
@ -58,7 +58,7 @@
|
|||
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.13.7"}}}
|
||||
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "2.8.1"}}}
|
||||
, {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.7"}}}
|
||||
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.3.7"}}}
|
||||
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.3.8"}}}
|
||||
, {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.2"}}}
|
||||
, {replayq, {git, "https://github.com/emqx/replayq.git", {tag, "0.3.5"}}}
|
||||
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}
|
||||
|
|
Loading…
Reference in New Issue