fix: don't allow empty string in server_port schema
This commit is contained in:
parent
823128dfc7
commit
5be4d97c42
|
@ -2608,7 +2608,7 @@ non_empty_string(_) -> {error, invalid_string}.
|
||||||
servers_sc(Meta0, ParseOpts) ->
|
servers_sc(Meta0, ParseOpts) ->
|
||||||
%% if this filed has a default value
|
%% if this filed has a default value
|
||||||
%% then it is not NOT required
|
%% then it is not NOT required
|
||||||
%% NOTE: maps:is_key is not the solution beause #{default => undefined} is legit
|
%% NOTE: maps:is_key is not the solution because #{default => undefined} is legit
|
||||||
HasDefault = (maps:get(default, Meta0, undefined) =/= undefined),
|
HasDefault = (maps:get(default, Meta0, undefined) =/= undefined),
|
||||||
Required = maps:get(required, Meta0, not HasDefault),
|
Required = maps:get(required, Meta0, not HasDefault),
|
||||||
Meta = #{
|
Meta = #{
|
||||||
|
@ -2661,17 +2661,18 @@ normalize_host_port_str(Str) ->
|
||||||
%% NOTE: Validator is called after converter.
|
%% NOTE: Validator is called after converter.
|
||||||
servers_validator(Opts, Required) ->
|
servers_validator(Opts, Required) ->
|
||||||
fun(Str0) ->
|
fun(Str0) ->
|
||||||
Str = str(Str0),
|
case str(Str0) of
|
||||||
case Str =:= "" orelse Str =:= "undefined" of
|
"" ->
|
||||||
true when Required ->
|
%% Empty string is not allowed even if the field is not required
|
||||||
%% it's a required field
|
%% remove field from config if it's empty
|
||||||
%% but value is set to an empty string (from environment override)
|
throw("cannot_be_empty");
|
||||||
%% or when the filed is not set in config file
|
"undefined" when Required ->
|
||||||
|
%% when the filed is not set in config file
|
||||||
%% NOTE: assuming nobody is going to name their server "undefined"
|
%% NOTE: assuming nobody is going to name their server "undefined"
|
||||||
throw("cannot_be_empty");
|
throw("cannot_be_empty");
|
||||||
true ->
|
"undefined" ->
|
||||||
ok;
|
ok;
|
||||||
_ ->
|
Str ->
|
||||||
%% it's valid as long as it can be parsed
|
%% it's valid as long as it can be parsed
|
||||||
_ = parse_servers(Str, Opts),
|
_ = parse_servers(Str, Opts),
|
||||||
ok
|
ok
|
||||||
|
@ -2816,20 +2817,17 @@ is_port_number(Port) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_port(Port) ->
|
parse_port(Port) ->
|
||||||
try
|
case string:to_integer(string:strip(Port)) of
|
||||||
P = list_to_integer(string:strip(Port)),
|
{P, ""} when P < 0 -> throw("port_number_too_small");
|
||||||
true = (P > 0),
|
{P, ""} when P > 65535 -> throw("port_number_too_large");
|
||||||
true = (P =< 65535),
|
{P, ""} -> P;
|
||||||
P
|
_ -> throw("bad_port_number")
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
throw("bad_port_number")
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
quic_feature_toggle(Desc) ->
|
quic_feature_toggle(Desc) ->
|
||||||
sc(
|
sc(
|
||||||
%% true, false are for user facing
|
%% true, false are for user facing
|
||||||
%% 0, 1 are for internal represtation
|
%% 0, 1 are for internal representation
|
||||||
typerefl:alias("boolean", typerefl:union([true, false, 0, 1])),
|
typerefl:alias("boolean", typerefl:union([true, false, 0, 1])),
|
||||||
#{
|
#{
|
||||||
desc => Desc,
|
desc => Desc,
|
||||||
|
|
|
@ -33,6 +33,26 @@
|
||||||
"tags {\"t1\" = \"good\", test = 100}\n"
|
"tags {\"t1\" = \"good\", test = 100}\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
>>).
|
>>).
|
||||||
|
-define(BAD_CONF, <<
|
||||||
|
"\n"
|
||||||
|
"statsd {\n"
|
||||||
|
"enable = true\n"
|
||||||
|
"flush_time_interval = 4s\n"
|
||||||
|
"sample_time_interval = 4s\n"
|
||||||
|
"server = \"\"\n"
|
||||||
|
"tags {\"t1\" = \"good\", test = 100}\n"
|
||||||
|
"}\n"
|
||||||
|
>>).
|
||||||
|
|
||||||
|
-define(DEFAULT_CONF, <<
|
||||||
|
"\n"
|
||||||
|
"statsd {\n"
|
||||||
|
"enable = true\n"
|
||||||
|
"flush_time_interval = 4s\n"
|
||||||
|
"sample_time_interval = 4s\n"
|
||||||
|
"tags {\"t1\" = \"good\", test = 100}\n"
|
||||||
|
"}\n"
|
||||||
|
>>).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:start_apps(
|
emqx_common_test_helpers:start_apps(
|
||||||
|
@ -55,6 +75,33 @@ set_special_configs(_) ->
|
||||||
all() ->
|
all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
|
t_server_validator(_) ->
|
||||||
|
Server0 = emqx_conf:get_raw([statsd, server]),
|
||||||
|
?assertThrow(
|
||||||
|
#{
|
||||||
|
kind := validation_error,
|
||||||
|
path := "statsd.server",
|
||||||
|
reason := "cannot_be_empty",
|
||||||
|
value := ""
|
||||||
|
},
|
||||||
|
emqx_common_test_helpers:load_config(emqx_statsd_schema, ?BAD_CONF, #{
|
||||||
|
raw_with_default => true
|
||||||
|
})
|
||||||
|
),
|
||||||
|
%% default
|
||||||
|
ok = emqx_common_test_helpers:load_config(emqx_statsd_schema, ?DEFAULT_CONF, #{
|
||||||
|
raw_with_default => true
|
||||||
|
}),
|
||||||
|
undefined = emqx_conf:get_raw([statsd, server], undefined),
|
||||||
|
?assertMatch("127.0.0.1:8125", emqx_conf:get([statsd, server])),
|
||||||
|
%% recover
|
||||||
|
ok = emqx_common_test_helpers:load_config(emqx_statsd_schema, ?BASE_CONF, #{
|
||||||
|
raw_with_default => true
|
||||||
|
}),
|
||||||
|
Server2 = emqx_conf:get_raw([statsd, server]),
|
||||||
|
?assertMatch(Server0, Server2),
|
||||||
|
ok.
|
||||||
|
|
||||||
t_statsd(_) ->
|
t_statsd(_) ->
|
||||||
{ok, Socket} = gen_udp:open(8126, [{active, true}]),
|
{ok, Socket} = gen_udp:open(8126, [{active, true}]),
|
||||||
receive
|
receive
|
||||||
|
@ -137,7 +184,16 @@ t_config_update(_) ->
|
||||||
?assertNotEqual(OldPid, NewPid)
|
?assertNotEqual(OldPid, NewPid)
|
||||||
after
|
after
|
||||||
{ok, _} = emqx_statsd_config:update(OldRawConf)
|
{ok, _} = emqx_statsd_config:update(OldRawConf)
|
||||||
end.
|
end,
|
||||||
|
%% bad server url
|
||||||
|
BadRawConf = OldRawConf#{<<"server">> := <<"">>},
|
||||||
|
{error, #{
|
||||||
|
kind := validation_error,
|
||||||
|
path := "statsd.server",
|
||||||
|
reason := "cannot_be_empty",
|
||||||
|
value := ""
|
||||||
|
}} = emqx_statsd_config:update(BadRawConf),
|
||||||
|
ok.
|
||||||
|
|
||||||
request(Method) -> request(Method, []).
|
request(Method) -> request(Method, []).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue