Преглед изворни кода

Merge pull request #11677 from lafirest/fix/sso_cfg

adjust the config path for the SSO feature and improve the update logic
lafirest пре 2 година
родитељ
комит
1df8326fb8

+ 1 - 1
apps/emqx/src/emqx_config_handler.erl

@@ -678,7 +678,7 @@ return_change_result(ConfKeyPath, {{update, Req}, Opts}) ->
     case Req =/= ?TOMBSTONE_CONFIG_CHANGE_REQ of
         true ->
             #{
-                config => emqx_config:get(ConfKeyPath),
+                config => emqx_config:get(ConfKeyPath, undefined),
                 raw_config => return_rawconf(ConfKeyPath, Opts)
             };
         false ->

+ 16 - 1
apps/emqx_dashboard/src/emqx_dashboard_schema.erl

@@ -68,7 +68,7 @@ fields("dashboard") ->
                     importance => ?IMPORTANCE_HIDDEN
                 }
             )}
-    ];
+    ] ++ sso_fields();
 fields("listeners") ->
     [
         {"http",
@@ -299,3 +299,18 @@ https_converter(Conf = #{}, _Opts) ->
     Conf1#{<<"ssl_options">> => SslOpts};
 https_converter(Conf, _Opts) ->
     Conf.
+
+-if(?EMQX_RELEASE_EDITION == ee).
+sso_fields() ->
+    [
+        {sso,
+            ?HOCON(
+                ?R_REF(emqx_dashboard_sso_schema, sso),
+                #{required => {false, recursively}}
+            )}
+    ].
+
+-else.
+sso_fields() ->
+    [].
+-endif.

+ 4 - 3
apps/emqx_dashboard_sso/src/emqx_dashboard_sso_api.erl

@@ -40,6 +40,7 @@
 -define(BAD_REQUEST, 'BAD_REQUEST').
 -define(BACKEND_NOT_FOUND, 'BACKEND_NOT_FOUND').
 -define(TAGS, <<"Dashboard Single Sign-On">>).
+-define(MOD_KEY_PATH, [dashboard, sso]).
 
 namespace() -> "dashboard_sso".
 
@@ -139,7 +140,7 @@ fields(backend_status) ->
 %%--------------------------------------------------------------------
 
 running(get, _Request) ->
-    SSO = emqx:get_config([dashboard_sso], #{}),
+    SSO = emqx:get_config(?MOD_KEY_PATH, #{}),
     {200,
         lists:filtermap(
             fun
@@ -175,7 +176,7 @@ login(post, #{bindings := #{backend := Backend}, body := Body} = Request) ->
     end.
 
 sso(get, _Request) ->
-    SSO = emqx:get_config([dashboard_sso], #{}),
+    SSO = emqx:get_config(?MOD_KEY_PATH, #{}),
     {200,
         lists:map(
             fun(Backend) ->
@@ -185,7 +186,7 @@ sso(get, _Request) ->
         )}.
 
 backend(get, #{bindings := #{backend := Type}}) ->
-    case emqx:get_config([dashboard_sso, Type], undefined) of
+    case emqx:get_config(?MOD_KEY_PATH ++ [Type], undefined) of
         undefined ->
             {404, #{code => ?BACKEND_NOT_FOUND, message => <<"Backend not found">>}};
         Backend ->

+ 45 - 21
apps/emqx_dashboard_sso/src/emqx_dashboard_sso_manager.erl

@@ -35,12 +35,14 @@
     update/2,
     delete/1,
     pre_config_update/3,
-    post_config_update/5
+    post_config_update/5,
+    propagated_post_config_update/5
 ]).
 
 -import(emqx_dashboard_sso, [provider/1]).
 
--define(MOD_KEY_PATH, [dashboard_sso]).
+-define(MOD_KEY_PATH, [dashboard, sso]).
+-define(MOD_KEY_PATH(Sub), [dashboard, sso, Sub]).
 -define(RESOURCE_GROUP, <<"emqx_dashboard_sso">>).
 -define(DEFAULT_RESOURCE_OPTS, #{
     start_after_created => false
@@ -66,7 +68,7 @@ running() ->
                 Acc
         end,
         [],
-        emqx:get_config([emqx_dashboard_sso])
+        emqx:get_config(?MOD_KEY_PATH)
     ).
 
 update(Backend, Config) ->
@@ -110,7 +112,7 @@ call(Req) ->
 %%------------------------------------------------------------------------------
 init([]) ->
     process_flag(trap_exit, true),
-    emqx_conf:add_handler(?MOD_KEY_PATH, ?MODULE),
+    add_handler(),
     emqx_utils_ets:new(
         dashboard_sso,
         [
@@ -138,7 +140,7 @@ handle_info(_Info, State) ->
     {noreply, State}.
 
 terminate(_Reason, _State) ->
-    emqx_conf:remove_handler(?MOD_KEY_PATH),
+    remove_handler(),
     ok.
 
 code_change(_OldVsn, State, _Extra) ->
@@ -151,7 +153,7 @@ format_status(_Opt, Status) ->
 %% Internal functions
 %%------------------------------------------------------------------------------
 start_backend_services() ->
-    Backends = emqx_conf:get([dashboard_sso], #{}),
+    Backends = emqx_conf:get(?MOD_KEY_PATH, #{}),
     lists:foreach(
         fun({Backend, Config}) ->
             Provider = provider(Backend),
@@ -174,7 +176,7 @@ start_backend_services() ->
     ).
 
 update_config(Backend, UpdateReq) ->
-    case emqx_conf:update([dashboard_sso], UpdateReq, #{override_to => cluster}) of
+    case emqx_conf:update(?MOD_KEY_PATH(Backend), UpdateReq, #{override_to => cluster}) of
         {ok, UpdateResult} ->
             #{post_config_update := #{?MODULE := Result}} = UpdateResult,
             ?SLOG(info, #{
@@ -192,25 +194,38 @@ update_config(Backend, UpdateReq) ->
             Error
     end.
 
-pre_config_update(_Path, {update, Backend, Config}, OldConf) ->
-    BackendBin = bin(Backend),
-    {ok, OldConf#{BackendBin => Config}};
-pre_config_update(_Path, {delete, Backend}, OldConf) ->
-    BackendBin = bin(Backend),
-    case maps:find(BackendBin, OldConf) of
-        error ->
-            throw(not_exists);
-        {ok, _} ->
-            {ok, maps:remove(BackendBin, OldConf)}
-    end.
+pre_config_update(_, {update, _Backend, Config}, _OldConf) ->
+    {ok, Config};
+pre_config_update(_, {delete, _Backend}, undefined) ->
+    throw(not_exists);
+pre_config_update(_, {delete, _Backend}, _OldConf) ->
+    {ok, null}.
 
-post_config_update(_Path, UpdateReq, NewConf, _OldConf, _AppEnvs) ->
+post_config_update(_, UpdateReq, NewConf, _OldConf, _AppEnvs) ->
     Result = call({update_config, UpdateReq, NewConf}),
     {ok, Result}.
 
-on_config_update({update, Backend, _Config}, NewConf) ->
+propagated_post_config_update(
+    ?MOD_KEY_PATH(BackendBin) = Path, _UpdateReq, undefined, OldConf, AppEnvs
+) ->
+    case atom(BackendBin) of
+        {ok, Backend} ->
+            post_config_update(Path, {delete, Backend}, undefined, OldConf, AppEnvs);
+        Error ->
+            Error
+    end;
+propagated_post_config_update(
+    ?MOD_KEY_PATH(BackendBin) = Path, _UpdateReq, NewConf, OldConf, AppEnvs
+) ->
+    case atom(BackendBin) of
+        {ok, Backend} ->
+            post_config_update(Path, {update, Backend, undefined}, NewConf, OldConf, AppEnvs);
+        Error ->
+            Error
+    end.
+
+on_config_update({update, Backend, _RawConfig}, Config) ->
     Provider = provider(Backend),
-    Config = maps:get(Backend, NewConf),
     case lookup(Backend) of
         undefined ->
             on_backend_updated(
@@ -267,3 +282,12 @@ on_backend_updated(Error, _) ->
 bin(A) when is_atom(A) -> atom_to_binary(A, utf8);
 bin(L) when is_list(L) -> list_to_binary(L);
 bin(X) -> X.
+
+atom(B) ->
+    emqx_utils:safe_to_existing_atom(B).
+
+add_handler() ->
+    ok = emqx_conf:add_handler(?MOD_KEY_PATH('?'), ?MODULE).
+
+remove_handler() ->
+    ok = emqx_conf:remove_handler(?MOD_KEY_PATH('?')).

+ 10 - 11
apps/emqx_dashboard_sso/src/emqx_dashboard_sso_schema.erl

@@ -8,33 +8,32 @@
 -include_lib("typerefl/include/types.hrl").
 
 %% Hocon
--export([namespace/0, roots/0, fields/1, tags/0, desc/1]).
+-export([fields/1, desc/1]).
+
 -export([
     common_backend_schema/1,
     backend_schema/1,
     username_password_schema/0
 ]).
+
 -import(hoconsc, [ref/2, mk/2, enum/1]).
 
 %%------------------------------------------------------------------------------
 %% Hocon Schema
 %%------------------------------------------------------------------------------
-namespace() -> dashboard_sso.
-
-tags() ->
-    [<<"Dashboard Single Sign-On">>].
-
-roots() -> [dashboard_sso].
-
-fields(dashboard_sso) ->
+fields(sso) ->
     lists:map(
         fun({Type, Module}) ->
-            {Type, mk(emqx_dashboard_sso:hocon_ref(Module), #{required => {false, recursively}})}
+            {Type,
+                mk(
+                    emqx_dashboard_sso:hocon_ref(Module),
+                    #{required => {false, recursively}}
+                )}
         end,
         maps:to_list(emqx_dashboard_sso:backends())
     ).
 
-desc(dashboard_sso) ->
+desc(sso) ->
     "Dashboard Single Sign-On";
 desc(_) ->
     undefined.

+ 1 - 1
apps/emqx_dashboard_sso/test/emqx_dashboard_sso_ldap_SUITE.erl

@@ -29,7 +29,7 @@ all() ->
 
 init_per_suite(Config) ->
     _ = application:load(emqx_conf),
-    emqx_config:save_schema_mod_and_names(emqx_dashboard_sso_schema),
+    emqx_config:save_schema_mod_and_names(emqx_dashboard_schema),
     emqx_mgmt_api_test_util:init_suite([emqx_dashboard, emqx_dashboard_sso]),
     Config.
 

+ 1 - 2
apps/emqx_enterprise/src/emqx_enterprise_schema.erl

@@ -11,8 +11,7 @@
 -define(EE_SCHEMA_MODULES, [
     emqx_license_schema,
     emqx_schema_registry_schema,
-    emqx_ft_schema,
-    emqx_dashboard_sso_schema
+    emqx_ft_schema
 ]).
 
 namespace() ->