feat(gw): return the created/updated resource info

This commit is contained in:
JianBo He 2021-11-24 14:40:59 +08:00
parent bc012d6554
commit 169848c027
5 changed files with 120 additions and 79 deletions

View File

@ -82,17 +82,15 @@ authn(get, #{bindings := #{name := Name0}}) ->
authn(put, #{bindings := #{name := Name0},
body := Body}) ->
with_gateway(Name0, fun(GwName, _) ->
%% TODO: return the authn instances?
ok = emqx_gateway_http:update_authn(GwName, Body),
{204}
{ok, Authn} = emqx_gateway_http:update_authn(GwName, Body),
{200, Authn}
end);
authn(post, #{bindings := #{name := Name0},
body := Body}) ->
with_gateway(Name0, fun(GwName, _) ->
%% TODO: return the authn instances?
ok = emqx_gateway_http:add_authn(GwName, Body),
{204}
{ok, Authn} = emqx_gateway_http:add_authn(GwName, Body),
{201, Authn}
end);
authn(delete, #{bindings := #{name := Name0}}) ->
@ -181,7 +179,7 @@ schema("/gateway/:name/authentication") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 204 => <<"Updated">> %% XXX: ??? return the updated object
, 200 => schema_authn()
}
},
post =>
@ -193,7 +191,7 @@ schema("/gateway/:name/authentication") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 204 => <<"Added">>
, 201 => schema_authn()
}
},
delete =>

View File

@ -93,8 +93,9 @@ listeners(post, #{bindings := #{name := Name0}, body := LConf}) ->
undefined ->
ListenerId = emqx_gateway_utils:listener_id(
GwName, Type, LName),
ok = emqx_gateway_http:add_listener(ListenerId, LConf),
{204};
{ok, RespConf} = emqx_gateway_http:add_listener(
ListenerId, LConf),
{201, RespConf};
_ ->
return_http_error(400, "Listener name has occupied")
end
@ -123,8 +124,8 @@ listeners_insta(put, #{body := LConf,
}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(_GwName, _) ->
ok = emqx_gateway_http:update_listener(ListenerId, LConf),
{204}
{ok, RespConf} = emqx_gateway_http:update_listener(ListenerId, LConf),
{200, RespConf}
end).
listeners_insta_authn(get, #{bindings := #{name := Name0,
@ -145,16 +146,17 @@ listeners_insta_authn(post, #{body := Conf,
id := ListenerId0}}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(GwName, _) ->
ok = emqx_gateway_http:add_authn(GwName, ListenerId, Conf),
{204}
{ok, Authn} = emqx_gateway_http:add_authn(GwName, ListenerId, Conf),
{201, Authn}
end);
listeners_insta_authn(put, #{body := Conf,
bindings := #{name := Name0,
id := ListenerId0}}) ->
ListenerId = emqx_mgmt_util:urldecode(ListenerId0),
with_gateway(Name0, fun(GwName, _) ->
ok = emqx_gateway_http:update_authn(GwName, ListenerId, Conf),
{204}
{ok, Authn} = emqx_gateway_http:update_authn(
GwName, ListenerId, Conf),
{200, Authn}
end);
listeners_insta_authn(delete, #{bindings := #{name := Name0,
id := ListenerId0}}) ->
@ -246,7 +248,9 @@ schema("/gateway/:name/listeners") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 204 => <<"Created">>
, 201 => emqx_dashboard_swagger:schema_with_examples(
ref(listener),
examples_listener_list())
}
}
};
@ -290,7 +294,9 @@ schema("/gateway/:name/listeners/:id") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 200 => <<"Updated">>
, 200 => emqx_dashboard_swagger:schema_with_examples(
ref(listener),
examples_listener())
}
}
};
@ -319,7 +325,7 @@ schema("/gateway/:name/listeners/:id/authentication") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 204 => <<"Added">>
, 201 => schema_authn()
}
},
put =>
@ -332,7 +338,7 @@ schema("/gateway/:name/listeners/:id/authentication") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 204 => <<"Updated">>
, 200 => schema_authn()
}
},
delete =>
@ -344,7 +350,7 @@ schema("/gateway/:name/listeners/:id/authentication") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 204 => <<"Deleted">>
, 200 => <<"Deleted">>
}
}
};
@ -431,9 +437,7 @@ schema("/gateway/:name/listeners/:id/authentication/users/:uid") ->
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
, 200 => emqx_dashboard_swagger:schema_with_example(
ref(emqx_authn_api, response_user),
emqx_authn_api:response_user_examples())
, 204 => <<"Deleted">>
}
}
};
@ -451,8 +455,7 @@ schema("/gateway/:name/listeners/:id/authentication/import_users") ->
#{ 400 => error_codes([?BAD_REQUEST], <<"Bad Request">>)
, 404 => error_codes([?NOT_FOUND], <<"Not Found">>)
, 500 => error_codes([?INTERNAL_ERROR],
<<"Ineternal Server Error">>)
%% XXX: Put a hint message into 204 return ?
<<"Ineternal Server Error">>)
, 204 => <<"Imported">>
}
}

View File

@ -59,7 +59,8 @@
-define(AUTHN_BIN, ?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY).
-type atom_or_bin() :: atom() | binary().
-type ok_or_err() :: ok_or_err().
-type ok_or_err() :: ok | {error, term()}.
-type map_or_err() :: map() | {error, term()}.
-type listener_ref() :: {ListenerType :: atom_or_bin(),
ListenerName :: atom_or_bin()}.
@ -85,7 +86,8 @@ load_gateway(GwName, Conf) ->
{Ls, Conf1} ->
Conf1#{<<"listeners">> => unconvert_listeners(Ls)}
end,
update({?FUNCTION_NAME, bin(GwName), NConf}).
%% TODO:
ret_ok_err(update({?FUNCTION_NAME, bin(GwName), NConf})).
%% @doc convert listener array to map
unconvert_listeners(Ls) when is_list(Ls) ->
@ -111,13 +113,14 @@ update_gateway(GwName, Conf0) ->
Exclude0 = [listeners, ?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_ATOM],
Exclude1 = [atom_to_binary(K, utf8) || K <- Exclude0],
Conf = maps:without(Exclude0 ++ Exclude1, Conf0),
update({?FUNCTION_NAME, bin(GwName), Conf}).
ret_ok_err(update({?FUNCTION_NAME, bin(GwName), Conf})).
%% FIXME: delete cert files ??
-spec unload_gateway(atom_or_bin()) -> ok_or_err().
unload_gateway(GwName) ->
update({?FUNCTION_NAME, bin(GwName)}).
ret_ok_err(update({?FUNCTION_NAME, bin(GwName)})).
%% @doc Get the gateway configurations.
%% Missing fields are filled with default values. This function is typically
@ -139,18 +142,20 @@ convert_listeners(GwName, Ls) when is_map(Ls) ->
lists:append([do_convert_listener(GwName, Type, maps:to_list(Conf))
|| {Type, Conf} <- maps:to_list(Ls)]).
do_convert_listener(GwName, Type, Conf) ->
[begin
ListenerId = emqx_gateway_utils:listener_id(GwName, Type, LName),
Running = emqx_gateway_utils:is_running(ListenerId, LConf),
bind2str(
LConf#{
id => ListenerId,
type => Type,
name => LName,
running => Running
})
end || {LName, LConf} <- Conf, is_map(LConf)].
do_convert_listener(GwName, LType, Conf) ->
[ do_convert_listener2(GwName, LType, LName, LConf)
|| {LName, LConf} <- Conf, is_map(LConf)].
do_convert_listener2(GwName, LType, LName, LConf) ->
ListenerId = emqx_gateway_utils:listener_id(GwName, LType, LName),
Running = emqx_gateway_utils:is_running(ListenerId, LConf),
bind2str(
LConf#{
id => ListenerId,
type => LType,
name => LName,
running => Running
}).
bind2str(LConf = #{bind := Bind}) when is_integer(Bind) ->
maps:put(bind, integer_to_binary(Bind), LConf);
@ -194,48 +199,56 @@ listener(ListenerId) ->
{error, Reason}
end.
-spec add_listener(atom_or_bin(), listener_ref(), map()) -> ok_or_err().
-spec add_listener(atom_or_bin(), listener_ref(), map()) -> map_or_err().
add_listener(GwName, ListenerRef, Conf) ->
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf}).
ret_listener_or_err(
GwName, ListenerRef,
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf})).
-spec update_listener(atom_or_bin(), listener_ref(), map()) -> ok_or_err().
-spec update_listener(atom_or_bin(), listener_ref(), map()) -> map_or_err().
update_listener(GwName, ListenerRef, Conf) ->
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf}).
ret_listener_or_err(
GwName, ListenerRef,
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf})).
-spec remove_listener(atom_or_bin(), listener_ref()) -> ok_or_err().
remove_listener(GwName, ListenerRef) ->
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef)}).
ret_ok_err(update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef)})).
-spec add_authn(atom_or_bin(), map()) -> ok_or_err().
-spec add_authn(atom_or_bin(), map()) -> map_or_err().
add_authn(GwName, Conf) ->
update({?FUNCTION_NAME, bin(GwName), Conf}).
ret_authn(GwName, update({?FUNCTION_NAME, bin(GwName), Conf})).
-spec add_authn(atom_or_bin(), listener_ref(), map()) -> ok_or_err().
-spec add_authn(atom_or_bin(), listener_ref(), map()) -> map_or_err().
add_authn(GwName, ListenerRef, Conf) ->
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf}).
ret_authn(
GwName, ListenerRef,
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf})).
-spec update_authn(atom_or_bin(), map()) -> ok_or_err().
-spec update_authn(atom_or_bin(), map()) -> map_or_err().
update_authn(GwName, Conf) ->
update({?FUNCTION_NAME, bin(GwName), Conf}).
ret_authn(GwName, update({?FUNCTION_NAME, bin(GwName), Conf})).
-spec update_authn(atom_or_bin(), listener_ref(), map()) -> ok_or_err().
-spec update_authn(atom_or_bin(), listener_ref(), map()) -> map_or_err().
update_authn(GwName, ListenerRef, Conf) ->
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf}).
ret_authn(
GwName, ListenerRef,
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf})).
-spec remove_authn(atom_or_bin()) -> ok_or_err().
remove_authn(GwName) ->
update({?FUNCTION_NAME, bin(GwName)}).
ret_ok_err(update({?FUNCTION_NAME, bin(GwName)})).
-spec remove_authn(atom_or_bin(), listener_ref()) -> ok_or_err().
remove_authn(GwName, ListenerRef) ->
update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef)}).
ret_ok_err(update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef)})).
%% @private
update(Req) ->
res(emqx_conf:update([gateway], Req, #{override_to => cluster})).
res({ok, _Result}) -> ok;
res({error, {pre_config_update, emqx_gateway_conf, Reason}}) -> {error, Reason};
res({ok, Result}) -> {ok, Result};
res({error, {error, {pre_config_update,emqx_gateway_conf,Reason}}}) -> {error, Reason};
res({error, Reason}) -> {error, Reason}.
bin({LType, LName}) ->
@ -245,6 +258,32 @@ bin(A) when is_atom(A) ->
bin(B) when is_binary(B) ->
B.
ret_ok_err({ok, _}) -> ok;
ret_ok_err(Err) -> Err.
ret_authn(GwName, {ok, #{raw_config := GwConf}}) ->
Authn = emqx_map_lib:deep_get(
[bin(GwName), <<"authentication">>],
GwConf),
{ok, Authn};
ret_authn(_GwName, Err) -> Err.
ret_authn(GwName, {LType, LName}, {ok, #{raw_config := GwConf}}) ->
Authn = emqx_map_lib:deep_get(
[bin(GwName), <<"listeners">>, bin(LType),
bin(LName), <<"authentication">>],
GwConf),
{ok, Authn};
ret_authn(_, _, Err) -> Err.
ret_listener_or_err(GwName, {LType, LName}, {ok, #{raw_config := GwConf}}) ->
LConf = emqx_map_lib:deep_get(
[bin(GwName), <<"listeners">>, bin(LType), bin(LName)],
GwConf),
{ok, do_convert_listener2(GwName, LType, LName, LConf)};
ret_listener_or_err(_, _, Err) ->
Err.
%%--------------------------------------------------------------------
%% Config Handler
%%--------------------------------------------------------------------

View File

@ -146,14 +146,14 @@ get_listeners_status(GwName, Config) ->
%% Mgmt APIs - listeners
%%--------------------------------------------------------------------
-spec add_listener(atom() | binary(), map()) -> ok.
-spec add_listener(atom() | binary(), map()) -> {ok, map()}.
add_listener(ListenerId, NewConf0) ->
{GwName, Type, Name} = emqx_gateway_utils:parse_listener_id(ListenerId),
NewConf = maps:without([<<"id">>, <<"name">>,
<<"type">>, <<"running">>], NewConf0),
confexp(emqx_gateway_conf:add_listener(GwName, {Type, Name}, NewConf)).
-spec update_listener(atom() | binary(), map()) -> ok.
-spec update_listener(atom() | binary(), map()) -> {ok, map()}.
update_listener(ListenerId, NewConf0) ->
{GwName, Type, Name} = emqx_gateway_utils:parse_listener_id(ListenerId),
@ -194,23 +194,23 @@ wrap_chain_name(ChainName, Conf) ->
Conf
end.
-spec add_authn(gateway_name(), map()) -> ok.
-spec add_authn(gateway_name(), map()) -> {ok, map()}.
add_authn(GwName, AuthConf) ->
confexp(emqx_gateway_conf:add_authn(GwName, AuthConf)).
-spec add_authn(gateway_name(), binary(), map()) -> ok.
-spec add_authn(gateway_name(), binary(), map()) -> {ok, map()}.
add_authn(GwName, ListenerId, AuthConf) ->
{_, Type, Name} = emqx_gateway_utils:parse_listener_id(ListenerId),
confexp(emqx_gateway_conf:add_authn(GwName, {Type, Name}, AuthConf)).
{_, LType, LName} = emqx_gateway_utils:parse_listener_id(ListenerId),
confexp(emqx_gateway_conf:add_authn(GwName, {LType, LName}, AuthConf)).
-spec update_authn(gateway_name(), map()) -> ok.
-spec update_authn(gateway_name(), map()) -> {ok, map()}.
update_authn(GwName, AuthConf) ->
confexp(emqx_gateway_conf:update_authn(GwName, AuthConf)).
-spec update_authn(gateway_name(), binary(), map()) -> ok.
-spec update_authn(gateway_name(), binary(), map()) -> {ok, map()}.
update_authn(GwName, ListenerId, AuthConf) ->
{_, Type, Name} = emqx_gateway_utils:parse_listener_id(ListenerId),
confexp(emqx_gateway_conf:update_authn(GwName, {Type, Name}, AuthConf)).
{_, LType, LName} = emqx_gateway_utils:parse_listener_id(ListenerId),
confexp(emqx_gateway_conf:update_authn(GwName, {LType, LName}, AuthConf)).
-spec remove_authn(gateway_name()) -> ok.
remove_authn(GwName) ->
@ -218,10 +218,11 @@ remove_authn(GwName) ->
-spec remove_authn(gateway_name(), binary()) -> ok.
remove_authn(GwName, ListenerId) ->
{_, Type, Name} = emqx_gateway_utils:parse_listener_id(ListenerId),
confexp(emqx_gateway_conf:remove_authn(GwName, {Type, Name})).
{_, LType, LName} = emqx_gateway_utils:parse_listener_id(ListenerId),
confexp(emqx_gateway_conf:remove_authn(GwName, {LType, LName})).
confexp(ok) -> ok;
confexp({ok, Res}) -> {ok, Res};
confexp({error, not_found}) ->
error({update_conf_error, not_found});
confexp({error, already_exist}) ->

View File

@ -196,12 +196,12 @@ t_authn(_) ->
backend => <<"built-in-database">>,
user_id_type => <<"clientid">>
},
{204, _} = request(post, "/gateway/stomp/authentication", AuthConf),
{201, _} = request(post, "/gateway/stomp/authentication", AuthConf),
{200, ConfResp} = request(get, "/gateway/stomp/authentication"),
assert_confs(AuthConf, ConfResp),
AuthConf2 = maps:merge(AuthConf, #{user_id_type => <<"username">>}),
{204, _} = request(put, "/gateway/stomp/authentication", AuthConf2),
{200, _} = request(put, "/gateway/stomp/authentication", AuthConf2),
{200, ConfResp2} = request(get, "/gateway/stomp/authentication"),
assert_confs(AuthConf2, ConfResp2),
@ -219,7 +219,7 @@ t_authn_data_mgmt(_) ->
backend => <<"built-in-database">>,
user_id_type => <<"clientid">>
},
{204, _} = request(post, "/gateway/stomp/authentication", AuthConf),
{201, _} = request(post, "/gateway/stomp/authentication", AuthConf),
{200, ConfResp} = request(get, "/gateway/stomp/authentication"),
assert_confs(AuthConf, ConfResp),
@ -262,14 +262,14 @@ t_listeners(_) ->
type => <<"tcp">>,
bind => <<"61613">>
},
{204, _} = request(post, "/gateway/stomp/listeners", LisConf),
{201, _} = request(post, "/gateway/stomp/listeners", LisConf),
{200, ConfResp} = request(get, "/gateway/stomp/listeners"),
assert_confs([LisConf], ConfResp),
{200, ConfResp1} = request(get, "/gateway/stomp/listeners/stomp:tcp:def"),
assert_confs(LisConf, ConfResp1),
LisConf2 = maps:merge(LisConf, #{bind => <<"61614">>}),
{204, _} = request(
{200, _} = request(
put,
"/gateway/stomp/listeners/stomp:tcp:def",
LisConf2
@ -298,12 +298,12 @@ t_listeners_authn(_) ->
user_id_type => <<"clientid">>
},
Path = "/gateway/stomp/listeners/stomp:tcp:def/authentication",
{204, _} = request(post, Path, AuthConf),
{201, _} = request(post, Path, AuthConf),
{200, ConfResp2} = request(get, Path),
assert_confs(AuthConf, ConfResp2),
AuthConf2 = maps:merge(AuthConf, #{user_id_type => <<"username">>}),
{204, _} = request(put, Path, AuthConf2),
{200, _} = request(put, Path, AuthConf2),
{200, ConfResp3} = request(get, Path),
assert_confs(AuthConf2, ConfResp3),
@ -325,7 +325,7 @@ t_listeners_authn_data_mgmt(_) ->
user_id_type => <<"clientid">>
},
Path = "/gateway/stomp/listeners/stomp:tcp:def/authentication",
{204, _} = request(post, Path, AuthConf),
{201, _} = request(post, Path, AuthConf),
{200, ConfResp2} = request(get, Path),
assert_confs(AuthConf, ConfResp2),