fix(sso): refactor update logic
This commit is contained in:
parent
08ad09a68f
commit
66d2107007
|
@ -271,8 +271,6 @@ handle_backend_update_result(ok, _) ->
|
||||||
204;
|
204;
|
||||||
handle_backend_update_result({error, not_exists}, _) ->
|
handle_backend_update_result({error, not_exists}, _) ->
|
||||||
{404, #{code => ?BACKEND_NOT_FOUND, message => <<"Backend not found">>}};
|
{404, #{code => ?BACKEND_NOT_FOUND, message => <<"Backend not found">>}};
|
||||||
handle_backend_update_result({error, already_exists}, _) ->
|
|
||||||
{400, #{code => ?BAD_REQUEST, message => <<"Backend already exists">>}};
|
|
||||||
handle_backend_update_result({error, failed_to_load_metadata}, _) ->
|
handle_backend_update_result({error, failed_to_load_metadata}, _) ->
|
||||||
{400, #{code => ?BAD_REQUEST, message => <<"Failed to load metadata">>}};
|
{400, #{code => ?BAD_REQUEST, message => <<"Failed to load metadata">>}};
|
||||||
handle_backend_update_result({error, Reason}, _) when is_binary(Reason) ->
|
handle_backend_update_result({error, Reason}, _) when is_binary(Reason) ->
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
running/0,
|
running/0,
|
||||||
get_backend_status/2,
|
|
||||||
lookup_state/1,
|
lookup_state/1,
|
||||||
|
get_backend_status/2,
|
||||||
make_resource_id/1,
|
make_resource_id/1,
|
||||||
create_resource/3,
|
create_resource/3,
|
||||||
update_resource/3
|
update_resource/3
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
-define(MOD_KEY_PATH, [dashboard, sso]).
|
-define(MOD_KEY_PATH, [dashboard, sso]).
|
||||||
-define(MOD_KEY_PATH(Sub), [dashboard, sso, Sub]).
|
-define(MOD_KEY_PATH(Sub), [dashboard, sso, Sub]).
|
||||||
-define(RESOURCE_GROUP, <<"emqx_dashboard_sso">>).
|
-define(RESOURCE_GROUP, <<"emqx_dashboard_sso">>).
|
||||||
-define(START_ERROR_KEY, start_error).
|
-define(NO_ERROR, <<>>).
|
||||||
-define(DEFAULT_RESOURCE_OPTS, #{
|
-define(DEFAULT_RESOURCE_OPTS, #{
|
||||||
start_after_created => false
|
start_after_created => false
|
||||||
}).
|
}).
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
-record(?MOD_TAB, {
|
-record(?MOD_TAB, {
|
||||||
backend :: atom(),
|
backend :: atom(),
|
||||||
state :: map(),
|
state :: map(),
|
||||||
last_error = <<>> :: term()
|
last_error = ?NO_ERROR :: term()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
@ -65,7 +65,7 @@ start_link() ->
|
||||||
running() ->
|
running() ->
|
||||||
lists:filtermap(
|
lists:filtermap(
|
||||||
fun
|
fun
|
||||||
(#?MOD_TAB{backend = Backend, last_error = <<>>}) ->
|
(#?MOD_TAB{backend = Backend, last_error = ?NO_ERROR}) ->
|
||||||
{true, Backend};
|
{true, Backend};
|
||||||
(_) ->
|
(_) ->
|
||||||
false
|
false
|
||||||
|
@ -78,7 +78,7 @@ get_backend_status(Backend, false) ->
|
||||||
backend => Backend,
|
backend => Backend,
|
||||||
enable => false,
|
enable => false,
|
||||||
running => false,
|
running => false,
|
||||||
last_error => <<>>
|
last_error => ?NO_ERROR
|
||||||
};
|
};
|
||||||
get_backend_status(Backend, _) ->
|
get_backend_status(Backend, _) ->
|
||||||
case lookup(Backend) of
|
case lookup(Backend) of
|
||||||
|
@ -87,7 +87,7 @@ get_backend_status(Backend, _) ->
|
||||||
backend => Backend,
|
backend => Backend,
|
||||||
enable => true,
|
enable => true,
|
||||||
running => false,
|
running => false,
|
||||||
last_error => <<"resource not found">>
|
last_error => <<"Resource not found">>
|
||||||
};
|
};
|
||||||
Data ->
|
Data ->
|
||||||
maps:merge(#{backend => Backend, enable => true}, do_get_backend_status(Data))
|
maps:merge(#{backend => Backend, enable => true}, do_get_backend_status(Data))
|
||||||
|
@ -179,54 +179,41 @@ start_backend_services() ->
|
||||||
msg => "start_sso_backend_successfully",
|
msg => "start_sso_backend_successfully",
|
||||||
backend => Backend
|
backend => Backend
|
||||||
}),
|
}),
|
||||||
ets:insert(?MOD_TAB, #?MOD_TAB{backend = Backend, state = State});
|
update_state(Backend, State);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
|
SafeReason = emqx_utils:redact(Reason),
|
||||||
|
update_last_error(Backend, SafeReason),
|
||||||
?SLOG(error, #{
|
?SLOG(error, #{
|
||||||
msg => "start_sso_backend_failed",
|
msg => "start_sso_backend_failed",
|
||||||
backend => Backend,
|
backend => Backend,
|
||||||
reason => emqx_utils:redact(Reason)
|
reason => SafeReason
|
||||||
})
|
})
|
||||||
end,
|
end
|
||||||
record_start_error(Backend, false)
|
|
||||||
end,
|
end,
|
||||||
maps:to_list(Backends)
|
maps:to_list(Backends)
|
||||||
).
|
).
|
||||||
|
|
||||||
update_config(Backend, UpdateReq) ->
|
update_config(Backend, UpdateReq) ->
|
||||||
OkFun = fun(Result) ->
|
|
||||||
?SLOG(info, #{
|
|
||||||
msg => "update_sso_successfully",
|
|
||||||
backend => Backend,
|
|
||||||
result => emqx_utils:redact(Result)
|
|
||||||
}),
|
|
||||||
Result
|
|
||||||
end,
|
|
||||||
|
|
||||||
ErrFun = fun({error, Reason} = Error) ->
|
|
||||||
SafeReason = emqx_utils:redact(Reason),
|
|
||||||
?SLOG(error, #{
|
|
||||||
msg => "update_sso_failed",
|
|
||||||
backend => Backend,
|
|
||||||
reason => SafeReason
|
|
||||||
}),
|
|
||||||
Error
|
|
||||||
end,
|
|
||||||
|
|
||||||
%% we always make sure the valid configuration will update successfully,
|
%% we always make sure the valid configuration will update successfully,
|
||||||
%% ignore the runtime error during its update
|
%% ignore the runtime error during its update
|
||||||
case emqx_conf:update(?MOD_KEY_PATH(Backend), UpdateReq, #{override_to => cluster}) of
|
case emqx_conf:update(?MOD_KEY_PATH(Backend), UpdateReq, #{override_to => cluster}) of
|
||||||
{ok, UpdateResult} ->
|
{ok, _UpdateResult} ->
|
||||||
#{post_config_update := #{?MODULE := Result}} = UpdateResult,
|
case lookup(Backend) of
|
||||||
case Result of
|
undefined ->
|
||||||
ok ->
|
ok;
|
||||||
OkFun(Result);
|
#?MOD_TAB{state = State, last_error = ?NO_ERROR} ->
|
||||||
{ok, _} ->
|
{ok, State};
|
||||||
OkFun(Result);
|
Data ->
|
||||||
{error, _} = Error ->
|
{error, Data#?MOD_TAB.last_error}
|
||||||
ErrFun(Error)
|
|
||||||
end;
|
end;
|
||||||
{error, _} = Error ->
|
{error, Reason} = Error ->
|
||||||
ErrFun(Error)
|
SafeReason = emqx_utils:redact(Reason),
|
||||||
|
?SLOG(error, #{
|
||||||
|
msg => "update_sso_failed",
|
||||||
|
backend => Backend,
|
||||||
|
reason => SafeReason
|
||||||
|
}),
|
||||||
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
pre_config_update(_, {update, _Backend, Config}, _OldConf) ->
|
pre_config_update(_, {update, _Backend, Config}, _OldConf) ->
|
||||||
|
@ -237,7 +224,8 @@ pre_config_update(_, {delete, _Backend}, _OldConf) ->
|
||||||
{ok, null}.
|
{ok, null}.
|
||||||
|
|
||||||
post_config_update(_, UpdateReq, NewConf, _OldConf, _AppEnvs) ->
|
post_config_update(_, UpdateReq, NewConf, _OldConf, _AppEnvs) ->
|
||||||
{ok, on_config_update(UpdateReq, NewConf)}.
|
_ = on_config_update(UpdateReq, NewConf),
|
||||||
|
ok.
|
||||||
|
|
||||||
propagated_post_config_update(
|
propagated_post_config_update(
|
||||||
?MOD_KEY_PATH(BackendBin) = Path, _UpdateReq, undefined, OldConf, AppEnvs
|
?MOD_KEY_PATH(BackendBin) = Path, _UpdateReq, undefined, OldConf, AppEnvs
|
||||||
|
@ -265,26 +253,23 @@ on_config_update({update, Backend, _RawConfig}, Config) ->
|
||||||
on_backend_updated(
|
on_backend_updated(
|
||||||
Backend,
|
Backend,
|
||||||
emqx_dashboard_sso:create(Provider, Config),
|
emqx_dashboard_sso:create(Provider, Config),
|
||||||
fun(State, LastError) ->
|
fun(State) ->
|
||||||
ets:insert(
|
update_state(Backend, State)
|
||||||
?MOD_TAB,
|
|
||||||
#?MOD_TAB{backend = Backend, state = State, last_error = LastError}
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
);
|
);
|
||||||
Data ->
|
Data ->
|
||||||
on_backend_updated(
|
on_backend_updated(
|
||||||
Backend,
|
Backend,
|
||||||
emqx_dashboard_sso:update(Provider, Config, Data#?MOD_TAB.state),
|
emqx_dashboard_sso:update(Provider, Config, Data#?MOD_TAB.state),
|
||||||
fun(State, LastError) ->
|
fun(State) ->
|
||||||
ets:insert(?MOD_TAB, Data#?MOD_TAB{state = State, last_error = LastError})
|
update_state(Backend, State)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end;
|
end;
|
||||||
on_config_update({delete, Backend}, _NewConf) ->
|
on_config_update({delete, Backend}, _NewConf) ->
|
||||||
case lookup(Backend) of
|
case lookup(Backend) of
|
||||||
undefined ->
|
undefined ->
|
||||||
{error, not_exists};
|
on_backend_updated(Backend, {error, not_exists}, undefined);
|
||||||
Data ->
|
Data ->
|
||||||
Provider = provider(Backend),
|
Provider = provider(Backend),
|
||||||
on_backend_updated(
|
on_backend_updated(
|
||||||
|
@ -306,31 +291,26 @@ lookup(Backend) ->
|
||||||
|
|
||||||
%% to avoid resource leakage the resource start will never affect the update result,
|
%% to avoid resource leakage the resource start will never affect the update result,
|
||||||
%% so the resource_id will always be recorded
|
%% so the resource_id will always be recorded
|
||||||
start_resource_if_enabled(ResourceId, {ok, _} = Result, #{enable := true}) ->
|
start_resource_if_enabled(ResourceId, {ok, _} = Result, #{enable := true, backend := Backend}) ->
|
||||||
clear_start_error(),
|
|
||||||
case emqx_resource:start(ResourceId) of
|
case emqx_resource:start(ResourceId) of
|
||||||
ok ->
|
ok ->
|
||||||
ok;
|
ok;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
SafeReason = emqx_utils:redact(Reason),
|
SafeReason = emqx_utils:redact(Reason),
|
||||||
mark_start_error(SafeReason),
|
|
||||||
?SLOG(error, #{
|
?SLOG(error, #{
|
||||||
msg => "start_backend_failed",
|
msg => "start_backend_failed",
|
||||||
resource_id => ResourceId,
|
resource_id => ResourceId,
|
||||||
reason => SafeReason
|
reason => SafeReason
|
||||||
}),
|
}),
|
||||||
|
update_last_error(Backend, SafeReason),
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
Result;
|
Result;
|
||||||
start_resource_if_enabled(_ResourceId, Result, _Config) ->
|
start_resource_if_enabled(_ResourceId, Result, _Config) ->
|
||||||
Result.
|
Result.
|
||||||
|
|
||||||
on_backend_updated(Backend, {ok, State} = Ok, Fun) ->
|
on_backend_updated(_Backend, {ok, State} = Ok, Fun) ->
|
||||||
Fun(State, <<>>),
|
Fun(State),
|
||||||
record_start_error(Backend, true),
|
|
||||||
Ok;
|
|
||||||
on_backend_updated(_Backend, {ok, State, LastError} = Ok, Fun) ->
|
|
||||||
Fun(State, LastError),
|
|
||||||
Ok;
|
Ok;
|
||||||
on_backend_updated(_Backend, ok, Fun) ->
|
on_backend_updated(_Backend, ok, Fun) ->
|
||||||
Fun(),
|
Fun(),
|
||||||
|
@ -373,29 +353,26 @@ new_ssl_source(Source, undefined) ->
|
||||||
new_ssl_source(Source, SSL) ->
|
new_ssl_source(Source, SSL) ->
|
||||||
Source#{<<"ssl">> => SSL}.
|
Source#{<<"ssl">> => SSL}.
|
||||||
|
|
||||||
clear_start_error() ->
|
update_state(Backend, State) ->
|
||||||
mark_start_error(<<>>).
|
Data = ensure_backend_data(Backend),
|
||||||
|
ets:insert(?MOD_TAB, Data#?MOD_TAB{state = State}).
|
||||||
|
|
||||||
mark_start_error(Reason) ->
|
update_last_error(Backend, LastError) ->
|
||||||
erlang:put(?START_ERROR_KEY, Reason).
|
Data = ensure_backend_data(Backend),
|
||||||
|
ets:insert(?MOD_TAB, Data#?MOD_TAB{last_error = LastError}).
|
||||||
|
|
||||||
record_start_error(Backend, Force) ->
|
ensure_backend_data(Backend) ->
|
||||||
case erlang:get(?START_ERROR_KEY) of
|
case ets:lookup(?MOD_TAB, Backend) of
|
||||||
<<>> when Force ->
|
[Data] ->
|
||||||
update_last_error(Backend, <<>>);
|
Data;
|
||||||
<<>> ->
|
[] ->
|
||||||
ok;
|
#?MOD_TAB{backend = Backend}
|
||||||
Reason ->
|
|
||||||
update_last_error(Backend, Reason)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
update_last_error(Backend, Reason) ->
|
|
||||||
ets:update_element(?MOD_TAB, Backend, {#?MOD_TAB.last_error, Reason}).
|
|
||||||
|
|
||||||
do_get_backend_status(#?MOD_TAB{state = #{resource_id := ResourceId}}) ->
|
do_get_backend_status(#?MOD_TAB{state = #{resource_id := ResourceId}}) ->
|
||||||
case emqx_resource_manager:lookup(ResourceId) of
|
case emqx_resource_manager:lookup(ResourceId) of
|
||||||
{ok, _Group, #{status := connected}} ->
|
{ok, _Group, #{status := connected}} ->
|
||||||
#{running => true, last_error => <<>>};
|
#{running => true, last_error => ?NO_ERROR};
|
||||||
{ok, _Group, #{status := Status}} ->
|
{ok, _Group, #{status := Status}} ->
|
||||||
#{
|
#{
|
||||||
running => false,
|
running => false,
|
||||||
|
@ -407,8 +384,8 @@ do_get_backend_status(#?MOD_TAB{state = #{resource_id := ResourceId}}) ->
|
||||||
last_error => <<"Resource not found">>
|
last_error => <<"Resource not found">>
|
||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
do_get_backend_status(#?MOD_TAB{last_error = <<>>}) ->
|
do_get_backend_status(#?MOD_TAB{last_error = ?NO_ERROR}) ->
|
||||||
#{running => true, last_error => <<>>};
|
#{running => true, last_error => ?NO_ERROR};
|
||||||
do_get_backend_status(#?MOD_TAB{last_error = LastError}) ->
|
do_get_backend_status(#?MOD_TAB{last_error = LastError}) ->
|
||||||
#{
|
#{
|
||||||
running => false,
|
running => false,
|
||||||
|
|
Loading…
Reference in New Issue