Merge pull request #6797 from zhongwencool/internal-acl-metrics

feat(acl): internal acl should support metrics[client.acl.ignore/allow/deny]
This commit is contained in:
zhongwencool 2022-01-20 10:36:59 +08:00 committed by GitHub
commit 964a77510d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 12 deletions

View File

@ -38,12 +38,26 @@
-type(acl_rules() :: #{publish => [emqx_access_rule:rule()], -type(acl_rules() :: #{publish => [emqx_access_rule:rule()],
subscribe => [emqx_access_rule:rule()]}). subscribe => [emqx_access_rule:rule()]}).
-record(acl_metrics, {
allow = 'client.acl.allow',
deny = 'client.acl.deny',
ignore = 'client.acl.ignore'
}).
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
-define(METRICS(Type, K), #Type{}#Type.K).
-define(ACL_METRICS, ?METRICS(acl_metrics)).
-define(ACL_METRICS(K), ?METRICS(acl_metrics, K)).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% API %% API
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
load(Env) -> load(Env) ->
Rules = rules_from_file(proplists:get_value(acl_file, Env)), Rules = rules_from_file(proplists:get_value(acl_file, Env)),
register_metrics(),
emqx_hooks:add('client.check_acl', {?MODULE, check_acl, [Rules]}, -1). emqx_hooks:add('client.check_acl', {?MODULE, check_acl, [Rules]}, -1).
unload(_Env) -> unload(_Env) ->
@ -68,9 +82,15 @@ description() ->
-> {ok, allow} | {ok, deny} | ok). -> {ok, allow} | {ok, deny} | ok).
check_acl(Client, PubSub, Topic, _AclResult, Rules) -> check_acl(Client, PubSub, Topic, _AclResult, Rules) ->
case match(Client, Topic, lookup(PubSub, Rules)) of case match(Client, Topic, lookup(PubSub, Rules)) of
{matched, allow} -> {ok, allow}; {matched, allow} ->
{matched, deny} -> {ok, deny}; emqx_metrics:inc(?ACL_METRICS(allow)),
nomatch -> ok {ok, allow};
{matched, deny} ->
emqx_metrics:inc(?ACL_METRICS(deny)),
{ok, deny};
nomatch ->
emqx_metrics:inc(?ACL_METRICS(ignore)),
ok
end. end.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -107,6 +127,9 @@ rules_from_file(AclFile) ->
#{} #{}
end. end.
register_metrics() ->
lists:foreach(fun emqx_metrics:ensure/1, ?ACL_METRICS).
filter(_PubSub, {allow, all}) -> filter(_PubSub, {allow, all}) ->
true; true;
filter(_PubSub, {deny, all}) -> filter(_PubSub, {deny, all}) ->
@ -119,4 +142,3 @@ filter(subscribe, {_AllowDeny, _Who, subscribe, _Topics}) ->
true; true;
filter(_PubSub, {_AllowDeny, _Who, _, _Topics}) -> filter(_PubSub, {_AllowDeny, _Who, _, _Topics}) ->
false. false.

View File

@ -1,6 +1,6 @@
{application, emqx_modules, {application, emqx_modules,
[{description, "EMQ X Module Management"}, [{description, "EMQ X Module Management"},
{vsn, "4.3.3"}, {vsn, "4.3.4"},
{modules, []}, {modules, []},
{applications, [kernel,stdlib]}, {applications, [kernel,stdlib]},
{mod, {emqx_modules_app, []}}, {mod, {emqx_modules_app, []}},

View File

@ -1,32 +1,45 @@
%% -*-: erlang -*- %% -*-: erlang -*-
{VSN, {VSN,
[ [
{"4.3.3", [
{apply, {emqx_metrics, ensure, [['client.acl.allow', 'client.acl.ignore', 'client.acl.deny']]}},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]},
{"4.3.2", [ {"4.3.2", [
{load_module, emqx_mod_presence, brutal_purge, soft_purge, []} {load_module, emqx_mod_presence, brutal_purge, soft_purge, []},
{apply, {emqx_metrics, ensure, [['client.acl.allow', 'client.acl.ignore', 'client.acl.deny']]}},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]}, ]},
{"4.3.1", [ {"4.3.1", [
{load_module, emqx_mod_presence, brutal_purge, soft_purge, []}, {load_module, emqx_mod_presence, brutal_purge, soft_purge, []},
{load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []} {load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []},
{apply, {emqx_metrics, ensure, [['client.acl.allow', 'client.acl.ignore', 'client.acl.deny']]}},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]}, ]},
{"4.3.0", [ {"4.3.0", [
{update, emqx_mod_delayed, {advanced, []}}, {update, emqx_mod_delayed, {advanced, []}},
{load_module, emqx_mod_presence, brutal_purge, soft_purge, []}, {load_module, emqx_mod_presence, brutal_purge, soft_purge, []},
{load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []} {load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []},
{apply, {emqx_metrics, ensure, [['client.acl.allow', 'client.acl.ignore', 'client.acl.deny']]}},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]}, ]},
{<<".*">>, []} {<<".*">>, []}
], ],
[ [
{"4.3.2", [ {"4.3.2", [
{load_module, emqx_mod_presence, brutal_purge, soft_purge, []} {load_module, emqx_mod_presence, brutal_purge, soft_purge, []},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]}, ]},
{"4.3.1", [ {"4.3.1", [
{load_module, emqx_mod_presence, brutal_purge, soft_purge, []}, {load_module, emqx_mod_presence, brutal_purge, soft_purge, []},
{load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []} {load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]}, ]},
{"4.3.0", [ {"4.3.0", [
{update, emqx_mod_delayed, {advanced, []}}, {update, emqx_mod_delayed, {advanced, []}},
{load_module, emqx_mod_presence, brutal_purge, soft_purge, []}, {load_module, emqx_mod_presence, brutal_purge, soft_purge, []},
{load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []} {load_module, emqx_mod_api_topic_metrics, brutal_purge, soft_purge, []},
{load_module, emqx_mod_acl_internal, brutal_purge, soft_purge, []}
]}, ]},
{<<".*">>, []} {<<".*">>, []}
] ]

View File

@ -38,10 +38,12 @@ t_load_unload(_) ->
?assertEqual({error,already_exists}, emqx_mod_acl_internal:load([])). ?assertEqual({error,already_exists}, emqx_mod_acl_internal:load([])).
t_check_acl(_) -> t_check_acl(_) ->
emqx_mod_acl_internal:load([]),
Rules=#{publish => [{allow,all}], subscribe => [{deny, all}]}, Rules=#{publish => [{allow,all}], subscribe => [{deny, all}]},
?assertEqual({ok, allow}, emqx_mod_acl_internal:check_acl(clientinfo(), publish, <<"t">>, [], Rules)), ?assertEqual({ok, allow}, emqx_mod_acl_internal:check_acl(clientinfo(), publish, <<"t">>, [], Rules)),
?assertEqual({ok, deny}, emqx_mod_acl_internal:check_acl(clientinfo(), subscribe, <<"t">>, [], Rules)), ?assertEqual({ok, deny}, emqx_mod_acl_internal:check_acl(clientinfo(), subscribe, <<"t">>, [], Rules)),
?assertEqual(ok, emqx_mod_acl_internal:check_acl(clientinfo(), connect, <<"t">>, [], Rules)). ?assertEqual(ok, emqx_mod_acl_internal:check_acl(clientinfo(), connect, <<"t">>, [], Rules)),
emqx_mod_acl_internal:unload([]).
t_reload_acl(_) -> t_reload_acl(_) ->
?assertEqual(ok, emqx_mod_acl_internal:reload([])). ?assertEqual(ok, emqx_mod_acl_internal:reload([])).