diff --git a/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema b/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema index 289bd73443fd..30a8bc84c06a 100644 --- a/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema +++ b/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema @@ -521,3 +521,10 @@ end}. {datatype, {enum, [true, false]}}, {include_default, false} ]}. + +%% Disables add/remove/grow/shrink over API. + +{mapping, "management.restrictions.quorum_queue_replica_operations.disabled", "rabbitmq_management.restrictions.quorum_queue_replica_operations.disabled", [ + {datatype, {enum, [true, false]}}, + {include_default, false} +]}. diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_features.erl b/deps/rabbitmq_management/src/rabbit_mgmt_features.erl index 5318aa4ccaad..5d2d47a60ced 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_features.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_features.erl @@ -7,7 +7,11 @@ -module(rabbit_mgmt_features). --export([is_op_policy_updating_disabled/0]). +-export([is_op_policy_updating_disabled/0, + is_qq_replica_operations_disabled/0]). + +is_qq_replica_operations_disabled() -> + get_restriction([quorum_queue_replica_operations, disabled]). is_op_policy_updating_disabled() -> case get_restriction([operator_policy_changes, disabled]) of diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_add_member.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_add_member.erl index 6befd137c497..2e6376189f9c 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_add_member.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_add_member.erl @@ -56,4 +56,9 @@ accept_content(ReqData, Context) -> is_authorized(ReqData, Context) -> - rabbit_mgmt_util:is_authorized_admin(ReqData, Context). \ No newline at end of file + case rabbit_mgmt_features:is_qq_replica_operations_disabled() of + true -> + rabbit_mgmt_util:method_not_allowed(<<"Broker settings disallow quorum queue replica operations.">>, ReqData, Context); + false -> + rabbit_mgmt_util:is_authorized_admin(ReqData, Context) + end. diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_delete_member.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_delete_member.erl index 6d8fc7518a7f..ef4235cc32f8 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_delete_member.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_delete_member.erl @@ -56,5 +56,11 @@ delete_completed(ReqData, Context) -> %% return 202 Accepted since this is an inherently asynchronous operation {false, ReqData, Context}. + is_authorized(ReqData, Context) -> - rabbit_mgmt_util:is_authorized_admin(ReqData, Context). \ No newline at end of file + case rabbit_mgmt_features:is_qq_replica_operations_disabled() of + true -> + rabbit_mgmt_util:method_not_allowed(<<"Broker settings disallow quorum queue replica operations.">>, ReqData, Context); + false -> + rabbit_mgmt_util:is_authorized_admin(ReqData, Context) + end. diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_grow.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_grow.erl index 5c878c612556..7b87604fab40 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_grow.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_grow.erl @@ -48,6 +48,10 @@ accept_content(ReqData, Context) -> end), {true, ReqData, Context}. - is_authorized(ReqData, Context) -> - rabbit_mgmt_util:is_authorized_admin(ReqData, Context). \ No newline at end of file + case rabbit_mgmt_features:is_qq_replica_operations_disabled() of + true -> + rabbit_mgmt_util:method_not_allowed(<<"Broker settings disallow quorum queue replica operations.">>, ReqData, Context); + false -> + rabbit_mgmt_util:is_authorized_admin(ReqData, Context) + end. diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_shrink.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_shrink.erl index 745c77ae9b6a..19925dfc1f0b 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_shrink.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_quorum_queue_replicas_shrink.erl @@ -35,4 +35,9 @@ delete_completed(ReqData, Context) -> {false, ReqData, Context}. is_authorized(ReqData, Context) -> - rabbit_mgmt_util:is_authorized_admin(ReqData, Context). \ No newline at end of file + case rabbit_mgmt_features:is_qq_replica_operations_disabled() of + true -> + rabbit_mgmt_util:method_not_allowed(<<"Broker settings disallow quorum queue replica operations.">>, ReqData, Context); + false -> + rabbit_mgmt_util:is_authorized_admin(ReqData, Context) + end. diff --git a/deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl b/deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl index 4dcd5dde2413..38b0f7984dd3 100644 --- a/deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl +++ b/deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl @@ -22,7 +22,7 @@ http_put/4, http_put/6, http_post/4, http_post/6, http_upload_raw/8, - http_delete/3, http_delete/5, + http_delete/3, http_delete/4, http_delete/5, http_put_raw/4, http_post_accept_json/4, req/4, auth_header/2, assert_permanent_redirect/3, @@ -151,7 +151,8 @@ all_tests() -> [ auth_attempts_test, user_limits_list_test, user_limit_set_test, - config_environment_test + config_environment_test, + disabled_qq_replica_opers_test ]. %% ------------------------------------------------------------------- @@ -216,6 +217,11 @@ init_per_testcase(Testcase = disabled_operator_policy_test, Config) -> rabbit_ct_broker_helpers:rpc_all(Config, application, set_env, [rabbitmq_management, restrictions, Restrictions]), rabbit_ct_helpers:testcase_started(Config, Testcase); +init_per_testcase(Testcase = disabled_qq_replica_opers_test, Config) -> + Restrictions = [{quorum_queue_replica_operations, [{disabled, true}]}], + rabbit_ct_broker_helpers:rpc_all(Config, + application, set_env, [rabbitmq_management, restrictions, Restrictions]), + rabbit_ct_helpers:testcase_started(Config, Testcase); init_per_testcase(Testcase, Config) -> rabbit_ct_broker_helpers:close_all_connections(Config, 0, <<"rabbit_mgmt_SUITE:init_per_testcase">>), rabbit_ct_helpers:testcase_started(Config, Testcase). @@ -277,6 +283,10 @@ end_per_testcase0(disabled_operator_policy_test, Config) -> rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env, [rabbitmq_management, restrictions]), Config; +end_per_testcase0(disabled_qq_replica_opers_test, Config) -> + rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env, + [rabbitmq_management, restrictions]), + Config; end_per_testcase0(_, Config) -> Config. %% ------------------------------------------------------------------- @@ -3553,6 +3563,15 @@ config_environment_test(Config) -> ?assertEqual(config_environment_test_value, V). +disabled_qq_replica_opers_test(Config) -> + Nodename = rabbit_data_coercion:to_list(rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename)), + Body = [{node, Nodename}], + http_post(Config, "/queues/quorum/%2F/qq.whatever/replicas/add", Body, ?METHOD_NOT_ALLOWED), + http_delete(Config, "/queues/quorum/%2F/qq.whatever/replicas/delete", ?METHOD_NOT_ALLOWED, Body), + http_post(Config, "/queues/quorum/replicas/on/" ++ Nodename ++ "/grow", Body, ?METHOD_NOT_ALLOWED), + http_delete(Config, "/queues/quorum/replicas/on/" ++ Nodename ++ "/shrink", ?METHOD_NOT_ALLOWED), + passed. + %% ------------------------------------------------------------------- %% Helpers. %% -------------------------------------------------------------------