New command: `rabbitmqctl close_all_user_connections`

This commit is contained in:
Michal Kuratczyk 2021-02-01 16:04:16 +01:00
parent 5a967affdd
commit ea1f4a355a
3 changed files with 90 additions and 8 deletions

View File

@ -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,

View File

@ -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

View File

@ -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