Merge branch 'stable'
This commit is contained in:
commit
dffde95b82
|
|
@ -18,7 +18,7 @@
|
|||
</p>
|
||||
|
||||
<p>
|
||||
To use it, <a href="/cli/rabbitmqadmin">download it</a> from this node (right click,
|
||||
To use it, <a href="rabbitmqadmin">download it</a> from this node (right click,
|
||||
Save As), make sure it is executable, and drop it in your <code>PATH</code>. Note that
|
||||
many browsers will rename the
|
||||
file <code>rabbitmqadmin.txt</code>. <code>rabbitmqadmin</code> requires Python
|
||||
|
|
|
|||
|
|
@ -22,18 +22,43 @@
|
|||
-export([dispatcher/0, web_ui/0]).
|
||||
|
||||
build_dispatcher(Ignore) ->
|
||||
Routes = build_routes(Ignore),
|
||||
cowboy_router:compile(Routes).
|
||||
|
||||
build_routes(Ignore) ->
|
||||
ManagementApp = module_app(?MODULE),
|
||||
Prefix = rabbit_mgmt_util:get_path_prefix(),
|
||||
RootIdxRtes = build_root_index_routes(Prefix, ManagementApp),
|
||||
ApiIdxRte = {"/api", cowboy_static, {priv_file, ManagementApp, "www/api/index.html"}},
|
||||
CliIdxRte = {"/cli", cowboy_static, {priv_file, ManagementApp, "www/cli/index.html"}},
|
||||
MgmtRdrRte = {"/mgmt", rabbit_mgmt_wm_redirect, "/"},
|
||||
LocalPaths = [{module_app(M), "www"} || M <- modules(Ignore)],
|
||||
cowboy_router:compile([{'_',
|
||||
[{"/api" ++ Path, Mod, Args}
|
||||
|| {Path, Mod, Args} <- lists:append([Module:dispatcher()
|
||||
|| Module <- modules(Ignore)])]
|
||||
++ [{"/", cowboy_static, {priv_file, ManagementApp, "www/index.html"}},
|
||||
{"/api", cowboy_static, {priv_file, ManagementApp, "www/api/index.html"}},
|
||||
{"/cli", cowboy_static, {priv_file, ManagementApp, "www/cli/index.html"}},
|
||||
{"/mgmt", rabbit_mgmt_wm_redirect, "/"}]
|
||||
++ [{"/[...]", rabbit_mgmt_wm_static, LocalPaths}]
|
||||
}]).
|
||||
LocalStaticRte = {"/[...]", rabbit_mgmt_wm_static, LocalPaths},
|
||||
% NB: order is significant in the routing list
|
||||
Routes0 = build_module_routes(Ignore) ++
|
||||
[ApiIdxRte, CliIdxRte, MgmtRdrRte, LocalStaticRte],
|
||||
Routes1 = maybe_add_path_prefix(Routes0, Prefix),
|
||||
% NB: ensure the root routes are first
|
||||
Routes2 = RootIdxRtes ++ Routes1,
|
||||
[{'_', Routes2}].
|
||||
|
||||
build_root_index_routes("", ManagementApp) ->
|
||||
[{"/", cowboy_static, root_idx_file(ManagementApp)}];
|
||||
build_root_index_routes(Prefix, ManagementApp) ->
|
||||
[{"/", rabbit_mgmt_wm_redirect, Prefix ++ "/"},
|
||||
{Prefix, cowboy_static, root_idx_file(ManagementApp)}].
|
||||
|
||||
root_idx_file(ManagementApp) ->
|
||||
{priv_file, ManagementApp, "www/index.html"}.
|
||||
|
||||
maybe_add_path_prefix(Routes, "") ->
|
||||
Routes;
|
||||
maybe_add_path_prefix(Routes, Prefix) ->
|
||||
[{Prefix ++ Path, Mod, Args} || {Path, Mod, Args} <- Routes].
|
||||
|
||||
build_module_routes(Ignore) ->
|
||||
Routes = [Module:dispatcher() || Module <- modules(Ignore)],
|
||||
[{"/api" ++ Path, Mod, Args} || {Path, Mod, Args} <- lists:append(Routes)].
|
||||
|
||||
modules(IgnoreApps) ->
|
||||
[Module || {App, Module, Behaviours} <-
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
]).
|
||||
-export([direct_request/6]).
|
||||
-export([qs_val/2]).
|
||||
-export([get_path_prefix/0]).
|
||||
|
||||
-import(rabbit_misc, [pget/2]).
|
||||
|
||||
|
|
@ -427,6 +428,19 @@ get_data({paged, Data}) ->
|
|||
get_data({_, Data}) ->
|
||||
Data.
|
||||
|
||||
get_path_prefix() ->
|
||||
EnvPrefix = rabbit_misc:get_env(rabbitmq_management, path_prefix, ""),
|
||||
fixup_prefix(EnvPrefix).
|
||||
|
||||
fixup_prefix("") ->
|
||||
"";
|
||||
fixup_prefix([Char|_Rest]=EnvPrefix) when is_list(EnvPrefix), Char =:= $/ ->
|
||||
EnvPrefix;
|
||||
fixup_prefix(EnvPrefix) when is_list(EnvPrefix) ->
|
||||
"/" ++ EnvPrefix;
|
||||
fixup_prefix(EnvPrefix) when is_binary(EnvPrefix) ->
|
||||
fixup_prefix(rabbit_data_coercion:to_list(EnvPrefix)).
|
||||
|
||||
%% XXX sort_list_and_paginate/2 is a more proper name for this function, keeping it
|
||||
%% with this name for backwards compatibility
|
||||
-spec sort_list([Fact], [string()]) -> [Fact] when
|
||||
|
|
|
|||
|
|
@ -93,13 +93,14 @@ accept_content(ReqData0, {_Mode, Context}) ->
|
|||
{stop, _, _} = Res ->
|
||||
Res;
|
||||
{true, ReqData, Context2} ->
|
||||
Loc = rabbit_web_dispatch_util:relativise(
|
||||
binary_to_list(cowboy_req:path(ReqData)),
|
||||
binary_to_list(
|
||||
rabbit_mgmt_format:url(
|
||||
"/api/bindings/~s/e/~s/~s/~s/~s",
|
||||
[VHost, Source, DestType, Dest,
|
||||
rabbit_mgmt_format:pack_binding_props(Key, Args)]))),
|
||||
From = binary_to_list(cowboy_req:path(ReqData)),
|
||||
Prefix = rabbit_mgmt_util:get_path_prefix(),
|
||||
BindingProps = rabbit_mgmt_format:pack_binding_props(Key, Args),
|
||||
UrlWithBindings = rabbit_mgmt_format:url("/api/bindings/~s/e/~s/~s/~s/~s",
|
||||
[VHost, Source, DestType,
|
||||
Dest, BindingProps]),
|
||||
To = Prefix ++ binary_to_list(UrlWithBindings),
|
||||
Loc = rabbit_web_dispatch_util:relativise(From, To),
|
||||
{{true, Loc}, ReqData, Context2}
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -38,101 +38,101 @@
|
|||
-import(rabbit_misc, [pget/2]).
|
||||
|
||||
-define(COLLECT_INTERVAL, 1000).
|
||||
-define(PATH_PREFIX, "/custom-prefix").
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
all() ->
|
||||
[
|
||||
{group, non_parallel_tests}
|
||||
{group, all_tests_with_prefix},
|
||||
{group, all_tests_without_prefix}
|
||||
].
|
||||
|
||||
groups() ->
|
||||
[
|
||||
{non_parallel_tests, [], [
|
||||
overview_test,
|
||||
auth_test,
|
||||
cluster_name_test,
|
||||
nodes_test,
|
||||
memory_test,
|
||||
ets_tables_memory_test,
|
||||
vhosts_test,
|
||||
vhosts_trace_test,
|
||||
users_test,
|
||||
without_permissions_users_test,
|
||||
users_bulk_delete_test,
|
||||
users_legacy_administrator_test,
|
||||
adding_a_user_with_password_test,
|
||||
adding_a_user_with_password_hash_test,
|
||||
adding_a_user_with_permissions_in_single_operation_test,
|
||||
adding_a_user_without_tags_fails_test,
|
||||
adding_a_user_without_password_or_hash_test,
|
||||
adding_a_user_with_both_password_and_hash_fails_test,
|
||||
updating_a_user_without_password_or_hash_clears_password_test,
|
||||
user_credential_validation_accept_everything_succeeds_test,
|
||||
user_credential_validation_min_length_succeeds_test,
|
||||
user_credential_validation_min_length_fails_test,
|
||||
permissions_validation_test,
|
||||
permissions_list_test,
|
||||
permissions_test,
|
||||
topic_permissions_list_test,
|
||||
topic_permissions_test,
|
||||
connections_test,
|
||||
multiple_invalid_connections_test,
|
||||
exchanges_test,
|
||||
queues_test,
|
||||
queues_well_formed_json_test,
|
||||
bindings_test,
|
||||
bindings_post_test,
|
||||
bindings_e2e_test,
|
||||
permissions_administrator_test,
|
||||
permissions_vhost_test,
|
||||
permissions_amqp_test,
|
||||
permissions_connection_channel_consumer_test,
|
||||
consumers_test,
|
||||
definitions_test,
|
||||
definitions_vhost_test,
|
||||
definitions_password_test,
|
||||
definitions_remove_things_test,
|
||||
definitions_server_named_queue_test,
|
||||
aliveness_test,
|
||||
healthchecks_test,
|
||||
arguments_test,
|
||||
arguments_table_test,
|
||||
queue_purge_test,
|
||||
queue_actions_test,
|
||||
exclusive_consumer_test,
|
||||
exclusive_queue_test,
|
||||
connections_channels_pagination_test,
|
||||
exchanges_pagination_test,
|
||||
exchanges_pagination_permissions_test,
|
||||
queue_pagination_test,
|
||||
queue_pagination_columns_test,
|
||||
queues_pagination_permissions_test,
|
||||
samples_range_test,
|
||||
sorting_test,
|
||||
format_output_test,
|
||||
columns_test,
|
||||
get_test,
|
||||
get_fail_test,
|
||||
publish_test,
|
||||
publish_accept_json_test,
|
||||
publish_fail_test,
|
||||
publish_base64_test,
|
||||
publish_unrouted_test,
|
||||
if_empty_unused_test,
|
||||
parameters_test,
|
||||
global_parameters_test,
|
||||
policy_test,
|
||||
policy_permissions_test,
|
||||
issue67_test,
|
||||
extensions_test,
|
||||
cors_test,
|
||||
vhost_limits_list_test,
|
||||
vhost_limit_set_test,
|
||||
rates_test
|
||||
]}
|
||||
{all_tests_with_prefix, [], all_tests()},
|
||||
{all_tests_without_prefix, [], all_tests()}
|
||||
].
|
||||
|
||||
all_tests() -> [
|
||||
overview_test,
|
||||
auth_test,
|
||||
cluster_name_test,
|
||||
nodes_test,
|
||||
memory_test,
|
||||
ets_tables_memory_test,
|
||||
vhosts_test,
|
||||
vhosts_trace_test,
|
||||
users_test,
|
||||
users_legacy_administrator_test,
|
||||
adding_a_user_with_password_test,
|
||||
adding_a_user_with_password_hash_test,
|
||||
adding_a_user_with_permissions_in_single_operation_test,
|
||||
adding_a_user_without_tags_fails_test,
|
||||
adding_a_user_without_password_or_hash_test,
|
||||
adding_a_user_with_both_password_and_hash_fails_test,
|
||||
updating_a_user_without_password_or_hash_clears_password_test,
|
||||
user_credential_validation_accept_everything_succeeds_test,
|
||||
user_credential_validation_min_length_succeeds_test,
|
||||
user_credential_validation_min_length_fails_test,
|
||||
permissions_validation_test,
|
||||
permissions_list_test,
|
||||
permissions_test,
|
||||
connections_test,
|
||||
multiple_invalid_connections_test,
|
||||
exchanges_test,
|
||||
queues_test,
|
||||
queues_well_formed_json_test,
|
||||
bindings_test,
|
||||
bindings_post_test,
|
||||
bindings_e2e_test,
|
||||
permissions_administrator_test,
|
||||
permissions_vhost_test,
|
||||
permissions_amqp_test,
|
||||
permissions_connection_channel_consumer_test,
|
||||
consumers_test,
|
||||
definitions_test,
|
||||
definitions_vhost_test,
|
||||
definitions_password_test,
|
||||
definitions_remove_things_test,
|
||||
definitions_server_named_queue_test,
|
||||
aliveness_test,
|
||||
healthchecks_test,
|
||||
arguments_test,
|
||||
arguments_table_test,
|
||||
queue_purge_test,
|
||||
queue_actions_test,
|
||||
exclusive_consumer_test,
|
||||
exclusive_queue_test,
|
||||
connections_channels_pagination_test,
|
||||
exchanges_pagination_test,
|
||||
exchanges_pagination_permissions_test,
|
||||
queue_pagination_test,
|
||||
queue_pagination_columns_test,
|
||||
queues_pagination_permissions_test,
|
||||
samples_range_test,
|
||||
sorting_test,
|
||||
format_output_test,
|
||||
columns_test,
|
||||
get_test,
|
||||
get_fail_test,
|
||||
publish_test,
|
||||
publish_accept_json_test,
|
||||
publish_fail_test,
|
||||
publish_base64_test,
|
||||
publish_unrouted_test,
|
||||
if_empty_unused_test,
|
||||
parameters_test,
|
||||
global_parameters_test,
|
||||
policy_test,
|
||||
policy_permissions_test,
|
||||
issue67_test,
|
||||
extensions_test,
|
||||
cors_test,
|
||||
vhost_limits_list_test,
|
||||
vhost_limit_set_test,
|
||||
rates_test].
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
%% Testsuite setup/teardown.
|
||||
%% -------------------------------------------------------------------
|
||||
|
|
@ -146,28 +146,37 @@ merge_app_env(Config) ->
|
|||
{sample_retention_policies,
|
||||
[{global, [{605, 1}]},
|
||||
{basic, [{605, 1}]},
|
||||
{detailed, [{10, 1}]}] }]}).
|
||||
{detailed, [{10, 1}]}]
|
||||
}]}).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
start_broker(Config) ->
|
||||
Setup0 = rabbit_ct_broker_helpers:setup_steps(),
|
||||
Setup1 = rabbit_ct_client_helpers:setup_steps(),
|
||||
Steps = Setup0 ++ Setup1,
|
||||
rabbit_ct_helpers:run_setup_steps(Config, Steps).
|
||||
|
||||
finish_init(Group, Config) ->
|
||||
rabbit_ct_helpers:log_environment(),
|
||||
inets:start(),
|
||||
Config1 = rabbit_ct_helpers:set_config(Config, [
|
||||
{rmq_nodename_suffix, ?MODULE}
|
||||
]),
|
||||
Config2 = merge_app_env(Config1),
|
||||
rabbit_ct_helpers:run_setup_steps(Config2,
|
||||
rabbit_ct_broker_helpers:setup_steps() ++
|
||||
rabbit_ct_client_helpers:setup_steps()).
|
||||
end_per_suite(Config) ->
|
||||
rabbit_ct_helpers:run_teardown_steps(Config,
|
||||
rabbit_ct_client_helpers:teardown_steps() ++
|
||||
rabbit_ct_broker_helpers:teardown_steps()).
|
||||
NodeConf = [{rmq_nodename_suffix, Group}],
|
||||
Config1 = rabbit_ct_helpers:set_config(Config, NodeConf),
|
||||
merge_app_env(Config1).
|
||||
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
init_per_group(all_tests_with_prefix=Group, Config0) ->
|
||||
PathConfig = {rabbitmq_management, [{path_prefix, ?PATH_PREFIX}]},
|
||||
Config1 = rabbit_ct_helpers:merge_app_env(Config0, PathConfig),
|
||||
Config2 = finish_init(Group, Config1),
|
||||
start_broker(Config2);
|
||||
init_per_group(Group, Config0) ->
|
||||
Config1 = finish_init(Group, Config0),
|
||||
start_broker(Config1).
|
||||
|
||||
end_per_group(_, Config) ->
|
||||
Config.
|
||||
inets:stop(),
|
||||
Teardown0 = rabbit_ct_client_helpers:teardown_steps(),
|
||||
Teardown1 = rabbit_ct_broker_helpers:teardown_steps(),
|
||||
Steps = Teardown0 ++ Teardown1,
|
||||
rabbit_ct_helpers:run_teardown_steps(Config, Steps).
|
||||
|
||||
init_per_testcase(Testcase, Config) ->
|
||||
rabbit_ct_helpers:testcase_started(Config, Testcase).
|
||||
|
|
@ -200,7 +209,6 @@ end_per_testcase0(_, Config) -> Config.
|
|||
%% Testcases.
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
|
||||
overview_test(Config) ->
|
||||
%% Rather crude, but this req doesn't say much and at least this means it
|
||||
%% didn't blow up.
|
||||
|
|
@ -209,7 +217,6 @@ overview_test(Config) ->
|
|||
{tags, <<"management">>}], {group, '2xx'}),
|
||||
http_get(Config, "/overview", "myuser", "myuser", ?OK),
|
||||
http_delete(Config, "/users/myuser", {group, '2xx'}),
|
||||
|
||||
passed.
|
||||
|
||||
cluster_name_test(Config) ->
|
||||
|
|
@ -956,23 +963,26 @@ bindings_post_test(Config) ->
|
|||
http_put(Config, "/queues/%2f/myqueue", QArgs, {group, '2xx'}),
|
||||
http_post(Config, "/bindings/%2f/e/myexchange/q/badqueue", BArgs, ?NOT_FOUND),
|
||||
http_post(Config, "/bindings/%2f/e/badexchange/q/myqueue", BArgs, ?NOT_FOUND),
|
||||
|
||||
Headers1 = http_post(Config, "/bindings/%2f/e/myexchange/q/myqueue", #{}, {group, '2xx'}),
|
||||
"../../../../%2F/e/myexchange/q/myqueue/~" = pget("location", Headers1),
|
||||
Want0 = "../../../../%2F/e/myexchange/q/myqueue/~",
|
||||
?assertEqual(Want0, pget("location", Headers1)),
|
||||
|
||||
Headers2 = http_post(Config, "/bindings/%2f/e/myexchange/q/myqueue", BArgs, {group, '2xx'}),
|
||||
%% Args hash is calculated from a table, generated from args.
|
||||
Hash = table_hash([{<<"foo">>,longstr,<<"bar">>}]),
|
||||
PropertiesKey = "routing~" ++ Hash,
|
||||
|
||||
Want1 = "../../../../%2F/e/myexchange/q/myqueue/" ++ PropertiesKey,
|
||||
?assertEqual(Want1, pget("location", Headers2)),
|
||||
|
||||
PropertiesKeyBin = list_to_binary(PropertiesKey),
|
||||
"../../../../%2F/e/myexchange/q/myqueue/" ++ PropertiesKey =
|
||||
pget("location", Headers2),
|
||||
Want2 = #{arguments => #{foo => <<"bar">>}, destination => <<"myqueue">>,
|
||||
destination_type => <<"queue">>, properties_key => PropertiesKeyBin,
|
||||
routing_key => <<"routing">>, source => <<"myexchange">>,vhost => <<"/">>},
|
||||
URI = "/bindings/%2F/e/myexchange/q/myqueue/" ++ PropertiesKey,
|
||||
#{source := <<"myexchange">>,
|
||||
vhost := <<"/">>,
|
||||
destination := <<"myqueue">>,
|
||||
destination_type := <<"queue">>,
|
||||
routing_key := <<"routing">>,
|
||||
arguments := #{foo := <<"bar">>},
|
||||
properties_key := PropertiesKeyBin} = http_get(Config, URI, ?OK),
|
||||
?assertEqual(Want2, http_get(Config, URI, ?OK)),
|
||||
|
||||
http_get(Config, URI ++ "x", ?NOT_FOUND),
|
||||
http_delete(Config, URI, {group, '2xx'}),
|
||||
http_delete(Config, "/exchanges/%2f/myexchange", {group, '2xx'}),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ groups() ->
|
|||
{parallel_tests, [parallel], [
|
||||
tokenise_test,
|
||||
pack_binding_test,
|
||||
amqp_table_test
|
||||
amqp_table_test,
|
||||
path_prefix_test
|
||||
]}
|
||||
].
|
||||
|
||||
|
|
@ -81,6 +82,25 @@ assert_table(JSON, AMQP) ->
|
|||
?assertEqual(JSON, rabbit_mgmt_format:amqp_table(AMQP)),
|
||||
?assertEqual(AMQP, rabbit_mgmt_format:to_amqp_table(JSON)).
|
||||
|
||||
path_prefix_test(_Config) ->
|
||||
Got0 = rabbit_mgmt_util:get_path_prefix(),
|
||||
?assertEqual("", Got0),
|
||||
|
||||
Pfx0 = "/custom-prefix",
|
||||
application:set_env(rabbitmq_management, path_prefix, Pfx0),
|
||||
Got1 = rabbit_mgmt_util:get_path_prefix(),
|
||||
?assertEqual(Pfx0, Got1),
|
||||
|
||||
Pfx1 = "custom-prefix",
|
||||
application:set_env(rabbitmq_management, path_prefix, Pfx1),
|
||||
Got2 = rabbit_mgmt_util:get_path_prefix(),
|
||||
?assertEqual(Pfx0, Got2),
|
||||
|
||||
Pfx2 = <<"custom-prefix">>,
|
||||
application:set_env(rabbitmq_management, path_prefix, Pfx2),
|
||||
Got3 = rabbit_mgmt_util:get_path_prefix(),
|
||||
?assertEqual(Pfx0, Got3).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
assert_binding(Packed, Routing, Args) ->
|
||||
|
|
|
|||
Loading…
Reference in New Issue