Merge pull request #12606 from JimMoen/EMQX-11914/fix-prom-api-crash
fix(prom): api crash when tls cert file non existed
This commit is contained in:
commit
eaa0bfd120
|
@ -2,7 +2,7 @@
|
|||
{application, emqx_prometheus, [
|
||||
{description, "Prometheus for EMQX"},
|
||||
% strict semver, bump manually!
|
||||
{vsn, "5.0.19"},
|
||||
{vsn, "5.0.20"},
|
||||
{modules, []},
|
||||
{registered, [emqx_prometheus_sup]},
|
||||
{applications, [kernel, stdlib, prometheus, emqx, emqx_auth, emqx_resource, emqx_management]},
|
||||
|
|
|
@ -830,8 +830,7 @@ cert_data(undefined) ->
|
|||
cert_data(AllListeners) ->
|
||||
Points = lists:foldl(
|
||||
fun(ListenerType, PointsAcc) ->
|
||||
PointsAcc ++
|
||||
points_of_listeners(ListenerType, AllListeners)
|
||||
lists:append(PointsAcc, points_of_listeners(ListenerType, AllListeners))
|
||||
end,
|
||||
_PointsInitAcc = [],
|
||||
?LISTENER_TYPES
|
||||
|
@ -843,53 +842,71 @@ cert_data(AllListeners) ->
|
|||
points_of_listeners(Type, AllListeners) ->
|
||||
do_points_of_listeners(Type, maps:get(Type, AllListeners, undefined)).
|
||||
|
||||
-define(CERT_TYPES, [certfile]).
|
||||
|
||||
-spec do_points_of_listeners(Type, TypeOfListeners) ->
|
||||
-spec do_points_of_listeners(Type, Listeners) ->
|
||||
[_Point :: {[{LabelKey, LabelValue}], Epoch}]
|
||||
when
|
||||
Type :: ssl | wss | quic,
|
||||
TypeOfListeners :: #{ListenerName :: atom() => ListenerConf :: map()} | undefined,
|
||||
Listeners :: #{ListenerName :: atom() => ListenerConf :: map()} | undefined,
|
||||
LabelKey :: atom(),
|
||||
LabelValue :: atom(),
|
||||
Epoch :: non_neg_integer().
|
||||
do_points_of_listeners(_, undefined) ->
|
||||
[];
|
||||
do_points_of_listeners(ListenerType, TypeOfListeners) ->
|
||||
do_points_of_listeners(Type, Listeners) ->
|
||||
lists:foldl(
|
||||
fun(Name, PointsAcc) ->
|
||||
lists:foldl(
|
||||
fun(CertType, AccIn) ->
|
||||
case
|
||||
emqx_utils_maps:deep_get([Name, enable], Listeners, false) andalso
|
||||
emqx_utils_maps:deep_get(
|
||||
[Name, ssl_options, CertType], TypeOfListeners, undefined
|
||||
[Name, ssl_options, certfile], Listeners, undefined
|
||||
)
|
||||
of
|
||||
undefined -> AccIn;
|
||||
Path -> [gen_point(ListenerType, Name, Path) | AccIn]
|
||||
false -> PointsAcc;
|
||||
undefined -> PointsAcc;
|
||||
Path -> [gen_point_cert_expiry_at(Type, Name, Path) | PointsAcc]
|
||||
end
|
||||
end,
|
||||
[],
|
||||
?CERT_TYPES
|
||||
) ++ PointsAcc
|
||||
end,
|
||||
[],
|
||||
maps:keys(TypeOfListeners)
|
||||
%% listener names
|
||||
maps:keys(Listeners)
|
||||
).
|
||||
|
||||
gen_point(Type, Name, Path) ->
|
||||
gen_point_cert_expiry_at(Type, Name, Path) ->
|
||||
{[{listener_type, Type}, {listener_name, Name}], cert_expiry_at_from_path(Path)}.
|
||||
|
||||
%% TODO: cert manager for more generic utils functions
|
||||
cert_expiry_at_from_path(Path0) ->
|
||||
Path = emqx_schema:naive_env_interpolation(Path0),
|
||||
{ok, PemBin} = file:read_file(Path),
|
||||
try
|
||||
case file:read_file(Path) of
|
||||
{ok, PemBin} ->
|
||||
[CertEntry | _] = public_key:pem_decode(PemBin),
|
||||
Cert = public_key:pem_entry_decode(CertEntry),
|
||||
%% TODO: Not fully tested for all certs type
|
||||
{'utcTime', NotAfterUtc} =
|
||||
Cert#'Certificate'.'tbsCertificate'#'TBSCertificate'.validity#'Validity'.'notAfter',
|
||||
utc_time_to_epoch(NotAfterUtc).
|
||||
utc_time_to_epoch(NotAfterUtc);
|
||||
{error, Reason} ->
|
||||
?SLOG(error, #{
|
||||
msg => "read_cert_file_failed",
|
||||
path => Path0,
|
||||
resolved_path => Path,
|
||||
reason => Reason
|
||||
}),
|
||||
0
|
||||
end
|
||||
catch
|
||||
E:R:S ->
|
||||
?SLOG(error, #{
|
||||
msg => "obtain_cert_expiry_time_failed",
|
||||
error => E,
|
||||
reason => R,
|
||||
stacktrace => S,
|
||||
path => Path0,
|
||||
resolved_path => Path
|
||||
}),
|
||||
0
|
||||
end.
|
||||
|
||||
utc_time_to_epoch(UtcTime) ->
|
||||
date_to_expiry_epoch(utc_time_to_datetime(UtcTime)).
|
||||
|
@ -898,7 +915,7 @@ utc_time_to_datetime(Str) ->
|
|||
{ok, [Year, Month, Day, Hour, Minute, Second], _} = io_lib:fread(
|
||||
"~2d~2d~2d~2d~2d~2dZ", Str
|
||||
),
|
||||
%% Alwoys Assuming YY is in 2000
|
||||
%% Always Assuming YY is in 2000
|
||||
{{2000 + Year, Month, Day}, {Hour, Minute, Second}}.
|
||||
|
||||
%% 62167219200 =:= calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}).
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fix the issue of the endpoint `/prometheus/stats` crashing when the listener's cert file is unreadable.
|
Loading…
Reference in New Issue