summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNuwan Sameera <nuwan.s@synergentl.com>2022-07-21 06:52:58 +0000
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2022-08-05 22:16:16 +0000
commit8e5f20e9cabf5ad9d64668c0690b2b033d34b172 (patch)
treed47ce258dae3a6e4cf31756093f6070b7d92f451
parent5bbdbb021d6a75dfc27322733412a345156dcd8e (diff)
downloadrabbitmq-server-git-8e5f20e9cabf5ad9d64668c0690b2b033d34b172.tar.gz
Add delete connection by username feature
Format code Fix whitespace, fix warning Update API docs Remove blank lines Add get all connections by username Fix method name issue Enable GET method to get connections by username Update API documentation Modify list all connections of username method Remove list_by_username method and modify get all connections of user API Code formatting, break up lines for readability Refactor code to use pattern matching more effectively Typo (cherry picked from commit 6eb2630f554433aeb88bdfe62917db2787fb4846)
-rw-r--r--deps/rabbitmq_management/priv/www/api/index.html12
-rw-r--r--deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl1
-rw-r--r--deps/rabbitmq_management/src/rabbit_mgmt_wm_connection.erl10
-rw-r--r--deps/rabbitmq_management/src/rabbit_mgmt_wm_connection_user_name.erl91
-rw-r--r--deps/rabbitmq_management/src/rabbit_mgmt_wm_connections.erl1
5 files changed, 110 insertions, 5 deletions
diff --git a/deps/rabbitmq_management/priv/www/api/index.html b/deps/rabbitmq_management/priv/www/api/index.html
index 52b450ff25..c45df32d72 100644
--- a/deps/rabbitmq_management/priv/www/api/index.html
+++ b/deps/rabbitmq_management/priv/www/api/index.html
@@ -334,6 +334,18 @@ vary: accept, accept-encoding, origin</pre>
<tr>
<td>X</td>
<td></td>
+ <td>X</td>
+ <td></td>
+ <td class="path">/api/connections/username/<i>username</i></td>
+ <td>
+ A list of all open connections for a specific username. Use pagination parameters to filter connections.
+ DELETEing a resource will close all the connections for a username. Optionally set the
+ "X-Reason" header when DELETEing to provide a reason.
+ </td>
+ </tr>
+ <tr>
+ <td>X</td>
+ <td></td>
<td></td>
<td></td>
<td class="path">/api/connections/<i>name</i>/channels</td>
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl b/deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl
index 53eb15660d..5b560053c0 100644
--- a/deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl
@@ -114,6 +114,7 @@ dispatcher() ->
{"/vhost-limits/:vhost", rabbit_mgmt_wm_limits, []},
{"/connections", rabbit_mgmt_wm_connections, []},
{"/connections/:connection", rabbit_mgmt_wm_connection, []},
+ {"/connections/username/:username", rabbit_mgmt_wm_connection_user_name, []},
{"/connections/:connection/channels", rabbit_mgmt_wm_connection_channels, []},
{"/channels", rabbit_mgmt_wm_channels, []},
{"/channels/:channel", rabbit_mgmt_wm_channel, []},
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection.erl
index 4aebeda354..1c212937bb 100644
--- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection.erl
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection.erl
@@ -37,11 +37,13 @@ resource_exists(ReqData, Context) ->
to_json(ReqData, Context) ->
case rabbit_mgmt_util:disable_stats(ReqData) of
false ->
- rabbit_mgmt_util:reply(
- maps:from_list(rabbit_mgmt_format:strip_pids(conn_stats(ReqData))), ReqData, Context);
+ ConnStats = conn_stats(ReqData),
+ ConnStatsWithoutPids = rabbit_mgmt_format:strip_pids(ConnStats),
+ ReplyData = maps:from_list(ConnStatsWithoutPids),
+ rabbit_mgmt_util:reply(ReplyData, ReqData, Context);
true ->
- rabbit_mgmt_util:reply([{name, rabbit_mgmt_util:id(connection, ReqData)}],
- ReqData, Context)
+ ReplyData = [{name, rabbit_mgmt_util:id(connection, ReqData)}],
+ rabbit_mgmt_util:reply(ReplyData, ReqData, Context)
end.
delete_resource(ReqData, Context) ->
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection_user_name.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection_user_name.erl
new file mode 100644
index 0000000000..ee8d8c243f
--- /dev/null
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_connection_user_name.erl
@@ -0,0 +1,91 @@
+%% This Source Code Form is subject to the terms of the Mozilla Public
+%% License, v. 2.0. If a copy of the MPL was not distributed with this
+%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
+%%
+%% Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved.
+%%
+
+-module(rabbit_mgmt_wm_connection_user_name).
+
+-export([init/2, to_json/2, content_types_provided/2,
+ is_authorized/2, allowed_methods/2, delete_resource/2]).
+-export([variances/2]).
+
+-include_lib("rabbitmq_management_agent/include/rabbit_mgmt_records.hrl").
+-include_lib("rabbit_common/include/rabbit.hrl").
+
+%%--------------------------------------------------------------------
+
+init(Req, _State) ->
+ {cowboy_rest, rabbit_mgmt_headers:set_common_permission_headers(Req, ?MODULE), #context{}}.
+
+variances(Req, Context) ->
+ {[<<"accept-encoding">>, <<"origin">>], Req, Context}.
+
+content_types_provided(ReqData, Context) ->
+ {rabbit_mgmt_util:responder_map(to_json), ReqData, Context}.
+
+allowed_methods(ReqData, Context) ->
+ {[<<"HEAD">>, <<"GET">>, <<"DELETE">>, <<"OPTIONS">>], ReqData, Context}.
+
+to_json(ReqData, Context) ->
+ {ok, _Username, UserConns} = list_user_connections(ReqData),
+ FilteredConns = rabbit_mgmt_util:filter_tracked_conn_list(UserConns, ReqData, Context),
+ rabbit_mgmt_util:reply_list_or_paginate(FilteredConns, ReqData, Context).
+
+delete_resource(ReqData, Context) ->
+ delete_resource(list_user_connections(ReqData), ReqData, Context).
+
+delete_resource({ok, _Username, []}, ReqData, Context) ->
+ {true, ReqData, Context};
+delete_resource({ok, Username, UserConns}, ReqData, Context) ->
+ ok = close_user_connections(UserConns, Username, ReqData),
+ {true, ReqData, Context}.
+
+is_authorized(ReqData, Context) ->
+ try
+ UserConns = list_user_connections(ReqData),
+ rabbit_mgmt_util:is_authorized_user(ReqData, Context, UserConns)
+ catch
+ {error, invalid_range_parameters, Reason} ->
+ rabbit_mgmt_util:bad_request(iolist_to_binary(Reason), ReqData, Context)
+ end.
+
+%%--------------------------------------------------------------------
+
+list_user_connections(ReqData) ->
+ Username = rabbit_mgmt_util:id(username, ReqData),
+ UserConns = rabbit_connection_tracking:list_of_user(Username),
+ {ok, Username, UserConns}.
+
+close_user_connections([], _Username, _ReqData) ->
+ ok;
+close_user_connections([Conn | Rest], Username, ReqData) ->
+ ok = close_user_connection(Conn, Username, ReqData),
+ close_user_connections(Rest, Username, ReqData).
+
+close_user_connection(#tracked_connection{name = Name, pid = Pid, username = Username, type = Type}, Username, ReqData) when is_pid(Pid) ->
+ Conn = [{name, Name}, {pid, Pid}, {user, Username}, {type, Type}],
+ force_close_connection(ReqData, Conn, Pid);
+close_user_connection(#tracked_connection{pid = undefined}, _Username, _ReqData) ->
+ ok;
+close_user_connection(UnexpectedConn, Username, _ReqData) ->
+ rabbit_log:debug("~p Username: ~p", [?MODULE, Username]),
+ rabbit_log:debug("~p unexpected connection: ~p", [?MODULE, UnexpectedConn]),
+ ok.
+
+force_close_connection(ReqData, Conn, Pid) ->
+ Reason = case cowboy_req:header(<<"x-reason">>, ReqData) of
+ undefined -> "Closed via management plugin";
+ V -> binary_to_list(V)
+ end,
+ case proplists:get_value(type, Conn) of
+ direct ->
+ amqp_direct_connection:server_close(Pid, 320, Reason);
+ network ->
+ rabbit_networking:close_connection(Pid, Reason);
+ _ ->
+ % best effort, this will work for connections to the stream plugin
+ gen_server:cast(Pid, {shutdown, Reason})
+ end,
+ ok.
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_connections.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_connections.erl
index c626b4ba17..65785c3421 100644
--- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_connections.erl
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_connections.erl
@@ -14,7 +14,6 @@
-import(rabbit_misc, [pget/2]).
-include_lib("rabbitmq_management_agent/include/rabbit_mgmt_records.hrl").
--include_lib("rabbit_common/include/rabbit.hrl").
%%--------------------------------------------------------------------