diff options
author | Michal Kuratczyk <mkuratczyk@pivotal.io> | 2021-02-01 16:04:16 +0100 |
---|---|---|
committer | Michal Kuratczyk <mkuratczyk@pivotal.io> | 2021-02-01 16:04:16 +0100 |
commit | ea1f4a355ad4b5197414dbe06f1a1c8e921b3c5d (patch) | |
tree | 67528bcd0a0e2cc8a6d66973ae923b66c97bcd9b | |
parent | 5a967affdd71f71370334c46f7e93e1288af6fde (diff) | |
download | rabbitmq-server-git-issue-2715.tar.gz |
New command: `rabbitmqctl close_all_user_connections`issue-2715
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 |