summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Kuratczyk <mkuratczyk@pivotal.io>2021-02-01 16:04:16 +0100
committerMichal Kuratczyk <mkuratczyk@pivotal.io>2021-02-01 16:04:16 +0100
commitea1f4a355ad4b5197414dbe06f1a1c8e921b3c5d (patch)
tree67528bcd0a0e2cc8a6d66973ae923b66c97bcd9b
parent5a967affdd71f71370334c46f7e93e1288af6fde (diff)
downloadrabbitmq-server-git-issue-2715.tar.gz
New command: `rabbitmqctl close_all_user_connections`issue-2715
-rw-r--r--deps/rabbit/src/rabbit_networking.erl1
-rw-r--r--deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_user_connections_command.ex9
-rw-r--r--deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs88
3 files changed, 90 insertions, 8 deletions
diff --git a/deps/rabbit/src/rabbit_networking.erl b/deps/rabbit/src/rabbit_networking.erl
index 8e7e86aaca..5f4976e087 100644
--- a/deps/rabbit/src/rabbit_networking.erl
+++ b/deps/rabbit/src/rabbit_networking.erl
@@ -29,6 +29,7 @@
connection_info_all/0, connection_info_all/1,
emit_connection_info_all/4, emit_connection_info_local/3,
close_connection/2, close_connections/2, close_all_connections/1,
+ close_all_user_connections/2,
force_connection_event_refresh/1, force_non_amqp_connection_event_refresh/1,
handshake/2, tcp_host/1,
ranch_ref/1, ranch_ref/2, ranch_ref_of_protocol/1,
diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_user_connections_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_user_connections_command.ex
index a0461b05d1..239b44b24c 100644
--- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_user_connections_command.ex
+++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_user_connections_command.ex
@@ -14,13 +14,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseAllUserConnectionsCommand do
use RabbitMQ.CLI.Core.RequiresRabbitAppRunning
- ## rabbit_networking:close_connections(lists:map(fun(X) -> element(6, X) end, rabbit_connection_tracking:list_of_user(<<"guest">>)), "because").
- # def run([username, explanation], %{node: node_name}) do
- # :rabbit_misc.rpc_call(node_name, :rabbit_networking, :close_connections, [
- # Enum.map(:rabbit_connection_tracking.list_of_user(username), fn x -> elem(6, x) end),
- # explanation
- # ])
- # end
def run([username, explanation], %{node: node_name}) do
:rabbit_misc.rpc_call(
node_name,
@@ -36,7 +29,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseAllUserConnectionsCommand do
def usage_additional do
[
- ["<username>", "TODO"],
+ ["<username>", "Self-explanatory"],
["<explanation>", "reason for connection closure"]
]
end
diff --git a/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs b/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs
new file mode 100644
index 0000000000..ffb2b6c1f8
--- /dev/null
+++ b/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs
@@ -0,0 +1,88 @@
+## 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-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CloseAllUserConnectionsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ # alias RabbitMQ.CLI.Ctl.RpcStream
+
+ @helpers RabbitMQ.CLI.Core.Helpers
+
+ @command RabbitMQ.CLI.Ctl.Commands.CloseAllUserConnectionsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ close_all_connections(get_rabbit_hostname())
+
+ on_exit([], fn ->
+ close_all_connections(get_rabbit_hostname())
+ end)
+
+ :ok
+ end
+
+ test "validate: with an invalid number of arguments returns an arg count error", context do
+ assert @command.validate(["username", "explanation", "extra"], context[:opts]) ==
+ {:validation_failure, :too_many_args}
+
+ assert @command.validate(["username"], context[:opts]) ==
+ {:validation_failure, :not_enough_args}
+ end
+
+ test "validate: with the correct number of arguments returns ok", context do
+ assert @command.validate(["username", "test"], context[:opts]) == :ok
+ end
+
+ test "run: a close connections request on a user with open connections", context do
+ with_connection("/", fn _ ->
+ node = @helpers.normalise_node(context[:node], :shortnames)
+ Process.sleep(500)
+
+ # make sure there is a connection to close
+ conns = fetch_user_connections("guest", context)
+ assert length(conns) > 0
+
+ # make sure closing yeti's connections doesn't affect guest's connections
+ assert :ok == @command.run(["yeti", "test"], %{node: node})
+ Process.sleep(500)
+ conns = fetch_user_connections("guest", context)
+ assert length(conns) > 0
+
+ # finally, make sure we can close guest's connections
+ assert :ok == @command.run(["guest", "test"], %{node: node})
+ Process.sleep(500)
+ conns = fetch_user_connections("guest", context)
+ assert length(conns) == 0
+ end)
+ end
+
+ test "run: a close connections request on for a non existing user returns successfully",
+ context do
+ assert match?(
+ :ok,
+ @command.run(["yeti", "test"], %{
+ node: @helpers.normalise_node(context[:node], :shortnames)
+ })
+ )
+ end
+
+ test "banner", context do
+ s = @command.banner(["username", "some reason"], context[:opts])
+ assert s =~ ~r/Closing connections/
+ assert s =~ ~r/user username/
+ assert s =~ ~r/reason: some reason/
+ end
+
+ defp fetch_user_connections(username, context) do
+ node = @helpers.normalise_node(context[:node], :shortnames)
+
+ :rabbit_misc.rpc_call(node, :rabbit_connection_tracking, :list_of_user, [
+ username
+ ])
+ end
+end