From 25b7719db5faf95330a5ee91df44fb473349b142 Mon Sep 17 00:00:00 2001 From: zhouzb Date: Tue, 21 Dec 2021 17:00:49 +0800 Subject: [PATCH 1/4] feat(authz): support sync configuration in the cluster --- apps/emqx_authz/src/emqx_authz.erl | 30 ++++++++----------- .../src/emqx_authz_api_settings.erl | 7 +++-- apps/emqx_authz/src/emqx_authz_utils.erl | 12 ++++++-- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/apps/emqx_authz/src/emqx_authz.erl b/apps/emqx_authz/src/emqx_authz.erl index 54438793b..97e0fb595 100644 --- a/apps/emqx_authz/src/emqx_authz.erl +++ b/apps/emqx_authz/src/emqx_authz.erl @@ -33,7 +33,6 @@ , move/2 , move/3 , update/2 - , update/3 , authorize/5 ]). @@ -114,24 +113,18 @@ move(Type, Cmd) -> move(Type, Cmd, #{}). move(Type, #{<<"before">> := Before}, Opts) -> - emqx:update_config( ?CONF_KEY_PATH - , {?CMD_MOVE, type(Type), ?CMD_MOVE_BEFORE(type(Before))}, Opts); + emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_BEFORE(type(Before))}, Opts); move(Type, #{<<"after">> := After}, Opts) -> - emqx:update_config( ?CONF_KEY_PATH - , {?CMD_MOVE, type(Type), ?CMD_MOVE_AFTER(type(After))}, Opts); + emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_AFTER(type(After))}, Opts); move(Type, Position, Opts) -> - emqx:update_config( ?CONF_KEY_PATH - , {?CMD_MOVE, type(Type), Position}, Opts). + emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), Position}, Opts). +update({?CMD_REPLACE, Type}, Sources) -> + emqx_authz_utils:update_config(?CONF_KEY_PATH, {{?CMD_REPLACE, type(Type)}, Sources}); +update({?CMD_DELETE, Type}, Sources) -> + emqx_authz_utils:update_config(?CONF_KEY_PATH, {{?CMD_DELETE, type(Type)}, Sources}); update(Cmd, Sources) -> - update(Cmd, Sources, #{}). - -update({?CMD_REPLACE, Type}, Sources, Opts) -> - emqx:update_config(?CONF_KEY_PATH, {{?CMD_REPLACE, type(Type)}, Sources}, Opts); -update({?CMD_DELETE, Type}, Sources, Opts) -> - emqx:update_config(?CONF_KEY_PATH, {{?CMD_DELETE, type(Type)}, Sources}, Opts); -update(Cmd, Sources, Opts) -> - emqx:update_config(?CONF_KEY_PATH, {Cmd, Sources}, Opts). + emqx_authz_utils:update_config(?CONF_KEY_PATH, {Cmd, Sources}). do_update({?CMD_MOVE, Type, ?CMD_MOVE_TOP}, Conf) when is_list(Conf) -> {Source, Front, Rear} = take(Type, Conf), @@ -155,8 +148,8 @@ do_update({?CMD_APPEND, Sources}, Conf) when is_list(Sources), is_list(Conf) -> NConf = Conf ++ Sources, ok = check_dup_types(NConf), NConf; -do_update({{?CMD_REPLACE, Type}, #{<<"enable">> := true} = Source}, Conf) when is_map(Source), - is_list(Conf) -> +do_update({{?CMD_REPLACE, Type}, #{<<"enable">> := true} = Source}, Conf) + when is_map(Source), is_list(Conf) -> case create_dry_run(Type, Source) of ok -> {_Old, Front, Rear} = take(Type, Conf), @@ -165,7 +158,8 @@ do_update({{?CMD_REPLACE, Type}, #{<<"enable">> := true} = Source}, Conf) when i NConf; {error, _} = Error -> Error end; -do_update({{?CMD_REPLACE, Type}, Source}, Conf) when is_map(Source), is_list(Conf) -> +do_update({{?CMD_REPLACE, Type}, Source}, Conf) + when is_map(Source), is_list(Conf) -> {_Old, Front, Rear} = take(Type, Conf), NConf = Front ++ [Source | Rear], ok = check_dup_types(NConf), diff --git a/apps/emqx_authz/src/emqx_authz_api_settings.erl b/apps/emqx_authz/src/emqx_authz_api_settings.erl index c2a87da16..c7d75bbba 100644 --- a/apps/emqx_authz/src/emqx_authz_api_settings.erl +++ b/apps/emqx_authz/src/emqx_authz_api_settings.erl @@ -54,8 +54,9 @@ settings(get, _Params) -> settings(put, #{body := #{<<"no_match">> := NoMatch, <<"deny_action">> := DenyAction, <<"cache">> := Cache}}) -> - {ok, _} = emqx:update_config([authorization, no_match], NoMatch), - {ok, _} = emqx:update_config([authorization, deny_action], DenyAction), - {ok, _} = emqx:update_config([authorization, cache], Cache), + {ok, _} = emqx_authz_utils:update_config([authorization, no_match], NoMatch), + {ok, _} = emqx_authz_utils:update_config( + [authorization, deny_action], DenyAction), + {ok, _} = emqx_authz_utils:update_config([authorization, cache], Cache), ok = emqx_authz_cache:drain_cache(), {200, authorization_settings()}. diff --git a/apps/emqx_authz/src/emqx_authz_utils.erl b/apps/emqx_authz/src/emqx_authz_utils.erl index 73132aacb..78140d118 100644 --- a/apps/emqx_authz/src/emqx_authz_utils.erl +++ b/apps/emqx_authz/src/emqx_authz_utils.erl @@ -18,9 +18,11 @@ -include_lib("emqx/include/emqx_placeholder.hrl"). --export([cleanup_resources/0, - make_resource_id/1, - create_resource/2]). +-export([ cleanup_resources/0 + , make_resource_id/1 + , create_resource/2 + , update_config/2 + ]). -define(RESOURCE_GROUP, <<"emqx_authz">>). @@ -45,6 +47,10 @@ make_resource_id(Name) -> NameBin = bin(Name), emqx_resource:generate_id(?RESOURCE_GROUP, NameBin). +update_config(Path, ConfigRequest) -> + emqx_conf:update(Path, ConfigRequest, #{rawconf_with_defaults => true, + override_to => cluster}). + %%------------------------------------------------------------------------------ %% Internal functions %%------------------------------------------------------------------------------ From 80c1128b7a23f947b027ebca2fb076bd0011e071 Mon Sep 17 00:00:00 2001 From: zhouzb Date: Thu, 23 Dec 2021 11:45:58 +0800 Subject: [PATCH 2/4] fix(authz): fix deadlock issues --- apps/emqx_authz/src/emqx_authz_http.erl | 4 ++-- apps/emqx_authz/src/emqx_authz_mongodb.erl | 4 ++-- apps/emqx_authz/src/emqx_authz_mysql.erl | 4 ++-- apps/emqx_authz/src/emqx_authz_postgresql.erl | 4 ++-- apps/emqx_authz/src/emqx_authz_redis.erl | 4 ++-- apps/emqx_authz/src/emqx_authz_utils.erl | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/emqx_authz/src/emqx_authz_http.erl b/apps/emqx_authz/src/emqx_authz_http.erl index c2ee96594..fe48b35d0 100644 --- a/apps/emqx_authz/src/emqx_authz_http.erl +++ b/apps/emqx_authz/src/emqx_authz_http.erl @@ -48,12 +48,12 @@ init(#{url := Url} = Source) -> end. destroy(#{annotations := #{id := Id}}) -> - ok = emqx_resource:remove(Id). + ok = emqx_resource:remove_local(Id). dry_run(Source) -> URIMap = maps:get(url, Source), NSource = maps:put(base_url, maps:remove(query, URIMap), Source), - emqx_resource:create_dry_run(emqx_connector_http, NSource). + emqx_resource:create_dry_run_local(emqx_connector_http, NSource). authorize(Client, PubSub, Topic, #{type := http, diff --git a/apps/emqx_authz/src/emqx_authz_mongodb.erl b/apps/emqx_authz/src/emqx_authz_mongodb.erl index 97fac9627..84ef2f302 100644 --- a/apps/emqx_authz/src/emqx_authz_mongodb.erl +++ b/apps/emqx_authz/src/emqx_authz_mongodb.erl @@ -46,10 +46,10 @@ init(Source) -> end. dry_run(Source) -> - emqx_resource:create_dry_run(emqx_connector_mongo, Source). + emqx_resource:create_dry_run_local(emqx_connector_mongo, Source). destroy(#{annotations := #{id := Id}}) -> - ok = emqx_resource:remove(Id). + ok = emqx_resource:remove_local(Id). authorize(Client, PubSub, Topic, #{collection := Collection, diff --git a/apps/emqx_authz/src/emqx_authz_mysql.erl b/apps/emqx_authz/src/emqx_authz_mysql.erl index a5b14ec1b..181478a76 100644 --- a/apps/emqx_authz/src/emqx_authz_mysql.erl +++ b/apps/emqx_authz/src/emqx_authz_mysql.erl @@ -48,10 +48,10 @@ init(#{query := SQL} = Source) -> end. dry_run(Source) -> - emqx_resource:create_dry_run(emqx_connector_mysql, Source). + emqx_resource:create_dry_run_local(emqx_connector_mysql, Source). destroy(#{annotations := #{id := Id}}) -> - ok = emqx_resource:remove(Id). + ok = emqx_resource:remove_local(Id). authorize(Client, PubSub, Topic, #{annotations := #{id := ResourceID, diff --git a/apps/emqx_authz/src/emqx_authz_postgresql.erl b/apps/emqx_authz/src/emqx_authz_postgresql.erl index f101841c2..4e84fe418 100644 --- a/apps/emqx_authz/src/emqx_authz_postgresql.erl +++ b/apps/emqx_authz/src/emqx_authz_postgresql.erl @@ -48,10 +48,10 @@ init(#{query := SQL} = Source) -> end. destroy(#{annotations := #{id := Id}}) -> - ok = emqx_resource:remove(Id). + ok = emqx_resource:remove_local(Id). dry_run(Source) -> - emqx_resource:create_dry_run(emqx_connector_pgsql, Source). + emqx_resource:create_dry_run_local(emqx_connector_pgsql, Source). parse_query(Sql) -> case re:run(Sql, ?RE_PLACEHOLDER, [global, {capture, all, list}]) of diff --git a/apps/emqx_authz/src/emqx_authz_redis.erl b/apps/emqx_authz/src/emqx_authz_redis.erl index 1f6abe330..8765734cf 100644 --- a/apps/emqx_authz/src/emqx_authz_redis.erl +++ b/apps/emqx_authz/src/emqx_authz_redis.erl @@ -46,10 +46,10 @@ init(Source) -> end. destroy(#{annotations := #{id := Id}}) -> - ok = emqx_resource:remove(Id). + ok = emqx_resource:remove_local(Id). dry_run(Source) -> - emqx_resource:create_dry_run(emqx_connector_redis, Source). + emqx_resource:create_dry_run_local(emqx_connector_redis, Source). authorize(Client, PubSub, Topic, #{cmd := CMD, diff --git a/apps/emqx_authz/src/emqx_authz_utils.erl b/apps/emqx_authz/src/emqx_authz_utils.erl index 78140d118..435388e44 100644 --- a/apps/emqx_authz/src/emqx_authz_utils.erl +++ b/apps/emqx_authz/src/emqx_authz_utils.erl @@ -32,7 +32,7 @@ create_resource(Module, Config) -> ResourceID = make_resource_id(Module), - case emqx_resource:create(ResourceID, Module, Config) of + case emqx_resource:create_local(ResourceID, Module, Config) of {ok, already_created} -> {ok, ResourceID}; {ok, _} -> {ok, ResourceID}; {error, Reason} -> {error, Reason} @@ -40,7 +40,7 @@ create_resource(Module, Config) -> cleanup_resources() -> lists:foreach( - fun emqx_resource:remove/1, + fun emqx_resource:remove_local/1, emqx_resource:list_group_instances(?RESOURCE_GROUP)). make_resource_id(Name) -> From 72a27e9d8fe40eb124ee492e8b25b0c7e738006f Mon Sep 17 00:00:00 2001 From: zhouzb Date: Fri, 24 Dec 2021 13:44:28 +0800 Subject: [PATCH 3/4] fix: fix undefined function call --- apps/emqx_authz/src/emqx_authz.erl | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/emqx_authz/src/emqx_authz.erl b/apps/emqx_authz/src/emqx_authz.erl index 97e0fb595..d02da0958 100644 --- a/apps/emqx_authz/src/emqx_authz.erl +++ b/apps/emqx_authz/src/emqx_authz.erl @@ -31,7 +31,6 @@ , lookup/0 , lookup/1 , move/2 - , move/3 , update/2 , authorize/5 ]). @@ -109,15 +108,12 @@ lookup(Type) -> {Source, _Front, _Rear} = take(Type), Source. -move(Type, Cmd) -> - move(Type, Cmd, #{}). - -move(Type, #{<<"before">> := Before}, Opts) -> - emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_BEFORE(type(Before))}, Opts); -move(Type, #{<<"after">> := After}, Opts) -> - emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_AFTER(type(After))}, Opts); -move(Type, Position, Opts) -> - emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), Position}, Opts). +move(Type, #{<<"before">> := Before}) -> + emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_BEFORE(type(Before))}); +move(Type, #{<<"after">> := After}) -> + emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_AFTER(type(After))}); +move(Type, Position) -> + emqx_authz_utils:update_config(?CONF_KEY_PATH, {?CMD_MOVE, type(Type), Position}). update({?CMD_REPLACE, Type}, Sources) -> emqx_authz_utils:update_config(?CONF_KEY_PATH, {{?CMD_REPLACE, type(Type)}, Sources}); From 487b84f166e77e8a766d808624f071925047f304 Mon Sep 17 00:00:00 2001 From: zhouzb Date: Tue, 28 Dec 2021 11:37:51 +0800 Subject: [PATCH 4/4] test: fix test case --- apps/emqx_authz/test/emqx_authz_SUITE.erl | 7 +++---- apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl | 7 +++---- apps/emqx_authz/test/emqx_authz_http_SUITE.erl | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/emqx_authz/test/emqx_authz_SUITE.erl b/apps/emqx_authz/test/emqx_authz_SUITE.erl index e18901fc5..7038b59e0 100644 --- a/apps/emqx_authz/test/emqx_authz_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_SUITE.erl @@ -31,10 +31,9 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), - meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end), - meck:expect(emqx_resource, update, fun(_, _, _, _) -> {ok, meck_data} end), - meck:expect(emqx_resource, remove, fun(_) -> ok end), - meck:expect(emqx_resource, create_dry_run, fun(_, _) -> ok end), + meck:expect(emqx_resource, create_local, fun(_, _, _) -> {ok, meck_data} end), + meck:expect(emqx_resource, remove_local, fun(_) -> ok end), + meck:expect(emqx_resource, create_dry_run_local, fun(_, _) -> ok end), ok = emqx_common_test_helpers:start_apps( [emqx_connector, emqx_conf, emqx_authz], diff --git a/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl b/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl index 67e1b05da..b1b6676ad 100644 --- a/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl @@ -96,14 +96,13 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), - meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end), - meck:expect(emqx_resource, create_dry_run, + meck:expect(emqx_resource, create_local, fun(_, _, _) -> {ok, meck_data} end), + meck:expect(emqx_resource, create_dry_run_local, fun(emqx_connector_mysql, _) -> {ok, meck_data}; (T, C) -> meck:passthrough([T, C]) end), - meck:expect(emqx_resource, update, fun(_, _, _, _) -> {ok, meck_data} end), meck:expect(emqx_resource, health_check, fun(_) -> ok end), - meck:expect(emqx_resource, remove, fun(_) -> ok end ), + meck:expect(emqx_resource, remove_local, fun(_) -> ok end ), ok = emqx_common_test_helpers:start_apps( [emqx_conf, emqx_authz, emqx_dashboard], diff --git a/apps/emqx_authz/test/emqx_authz_http_SUITE.erl b/apps/emqx_authz/test/emqx_authz_http_SUITE.erl index c438b3f4b..939c8fb5e 100644 --- a/apps/emqx_authz/test/emqx_authz_http_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_http_SUITE.erl @@ -30,8 +30,8 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), - meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end), - meck:expect(emqx_resource, remove, fun(_) -> ok end ), + meck:expect(emqx_resource, create_local, fun(_, _, _) -> {ok, meck_data} end), + meck:expect(emqx_resource, remove_local, fun(_) -> ok end ), ok = emqx_common_test_helpers:start_apps( [emqx_conf, emqx_authz],