emqx_node_dump.erl 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. %% Collection of functions for creating node dumps
  17. -module(emqx_node_dump).
  18. -export([ sys_info/0
  19. , app_env_dump/0
  20. ]).
  21. sys_info() ->
  22. #{ release => emqx_app:get_release()
  23. , otp_version => emqx_vm:get_otp_version()
  24. }.
  25. app_env_dump() ->
  26. censor(ets:tab2list(ac_tab)).
  27. censor([]) ->
  28. [];
  29. censor([{{env, App, Key}, Val} | Rest]) ->
  30. [{{env, App, Key}, censor([Key, App], Val)} | censor(Rest)];
  31. censor([_ | Rest]) ->
  32. censor(Rest).
  33. censor(Path, {Key, Val}) when is_atom(Key) ->
  34. {Key, censor([Key|Path], Val)};
  35. censor(Path, M) when is_map(M) ->
  36. Fun = fun(Key, Val) ->
  37. censor([Key|Path], Val)
  38. end,
  39. maps:map(Fun, M);
  40. censor(Path, L = [Fst|_]) when is_tuple(Fst) ->
  41. [censor(Path, I) || I <- L];
  42. censor([Key | _], Val) ->
  43. case is_sensitive(Key) of
  44. true -> obfuscate_value(Val);
  45. false -> Val
  46. end.
  47. is_sensitive(Key) when is_atom(Key) ->
  48. is_sensitive(atom_to_binary(Key, utf8));
  49. is_sensitive(Key) when is_list(Key) ->
  50. try iolist_to_binary(Key) of
  51. Bin ->
  52. is_sensitive(Bin)
  53. catch
  54. _ : _ ->
  55. false
  56. end;
  57. is_sensitive(Key) when is_binary(Key) ->
  58. lists:any(fun(Pattern) -> re:run(Key, Pattern) =/= nomatch end,
  59. ["passwd", "password", "secret"]);
  60. is_sensitive(Key) when is_tuple(Key) ->
  61. false.
  62. obfuscate_value(Val) when is_binary(Val) ->
  63. <<"********">>;
  64. obfuscate_value(_Val) ->
  65. "********".
  66. -ifdef(TEST).
  67. -include_lib("eunit/include/eunit.hrl").
  68. censor_test() ->
  69. ?assertMatch( [{{env, emqx, listeners}, #{password := <<"********">>}}]
  70. , censor([foo, {{env, emqx, listeners}, #{password => <<"secret">>}}, {app, bar}])
  71. ),
  72. ?assertMatch( [{{env, emqx, listeners}, [{foo, 1}, {password, "********"}]}]
  73. , censor([{{env, emqx, listeners}, [{foo, 1}, {password, "secret"}]}])
  74. ).
  75. -endif. %% TEST