diff --git a/deps/rabbitmq_management/priv/www/doc/stats.html b/deps/rabbitmq_management/priv/www/doc/stats.html
index 6df64004f5..bd6a42c603 100644
--- a/deps/rabbitmq_management/priv/www/doc/stats.html
+++ b/deps/rabbitmq_management/priv/www/doc/stats.html
@@ -532,6 +532,82 @@
List of network partitions this node is seeing.
+
proc_total |
diff --git a/deps/rabbitmq_management/priv/www/js/charts.js b/deps/rabbitmq_management/priv/www/js/charts.js
index 6fa177d6c0..afe7cee6a2 100644
--- a/deps/rabbitmq_management/priv/www/js/charts.js
+++ b/deps/rabbitmq_management/priv/www/js/charts.js
@@ -12,22 +12,22 @@ function message_rates(id, stats) {
['Get', 'get'], ['Deliver (noack)', 'deliver_no_ack'],
['Get (noack)', 'get_no_ack'],
['Return', 'return_unroutable']];
- return rates_chart_or_text(id, stats, items, fmt_rate, fmt_rate_large, fmt_rate_axis, true, 'Message rates', 'message-rates');
+ return rates_chart_or_text(id, stats, items, fmt_rate, fmt_rate_axis, true, 'Message rates', 'message-rates');
}
function queue_lengths(id, stats) {
var items = [['Ready', 'messages_ready'],
['Unacked', 'messages_unacknowledged'],
['Total', 'messages']];
- return rates_chart_or_text(id, stats, items, fmt_msgs, fmt_msgs_large, fmt_num_axis, false, 'Queued messages', 'queued-messages');
+ return rates_chart_or_text(id, stats, items, fmt_num_thousands, fmt_plain_axis, false, 'Queued messages', 'queued-messages');
}
function data_rates(id, stats) {
var items = [['From client', 'recv_oct'], ['To client', 'send_oct']];
- return rates_chart_or_text(id, stats, items, fmt_rate_bytes, fmt_rate_bytes_large, fmt_rate_bytes_axis, true, 'Data rates');
+ return rates_chart_or_text(id, stats, items, fmt_rate_bytes, fmt_rate_bytes_axis, true, 'Data rates');
}
-function rates_chart_or_text(id, stats, items, chart_fmt, text_fmt, axis_fmt, chart_rates,
+function rates_chart_or_text(id, stats, items, fmt, axis_fmt, chart_rates,
heading, heading_help) {
var mode = get_pref('rate-mode-' + id);
var range = get_pref('chart-range');
@@ -37,10 +37,10 @@ function rates_chart_or_text(id, stats, items, chart_fmt, text_fmt, axis_fmt, ch
if (keys(stats).length > 0) {
if (mode == 'chart') {
res = rates_chart(
- id, id, items, stats, chart_fmt, axis_fmt, 'full', chart_rates);
+ id, id, items, stats, fmt, axis_fmt, 'full', chart_rates);
}
else {
- res = rates_text(items, stats, mode, text_fmt);
+ res = rates_text(items, stats, mode, fmt, chart_rates);
}
if (res == "") res = ' Waiting for data... ';
}
@@ -79,7 +79,7 @@ function node_stat_count(used_key, limit_key, stats, thresholds) {
var limit = stats[limit_key];
if (typeof used == 'number') {
return node_stat(used_key, 'Used', limit_key, 'available', stats,
- fmt_num_obj, fmt_num_axis,
+ fmt_plain, fmt_plain_axis,
fmt_color(used / limit, thresholds));
} else {
return used;
@@ -91,19 +91,20 @@ function node_stat_count_bar(used_key, limit_key, stats, thresholds) {
var limit = stats[limit_key];
if (typeof used == 'number') {
return node_stat_bar(used_key, limit_key, 'available', stats,
- fmt_num_axis, fmt_color(used / limit, thresholds));
+ fmt_plain_axis,
+ fmt_color(used / limit, thresholds));
} else {
return used;
}
}
-function node_stat(used_key, used_name, limit_key, suffix, stats, rate_fmt,
+function node_stat(used_key, used_name, limit_key, suffix, stats, fmt,
axis_fmt, colour, help, invert) {
if (get_pref('rate-mode-node-stats') == 'chart') {
var items = [[used_name, used_key], ['Limit', limit_key]];
add_fake_limit_details(used_key, limit_key, stats);
return rates_chart('node-stats', 'node-stats-' + used_key, items, stats,
- rate_fmt, axis_fmt, 'node', false);
+ fmt, axis_fmt, 'node', false);
} else {
return node_stat_bar(used_key, limit_key, suffix, stats, axis_fmt,
colour, help, invert);
@@ -156,7 +157,7 @@ function node_stats_prefs() {
return chart_h3('node-stats', 'Node statistics');
}
-function rates_chart(type_id, id, items, stats, rate_fmt, axis_fmt, type,
+function rates_chart(type_id, id, items, stats, fmt, axis_fmt, type,
chart_rates) {
function show(key) {
return get_pref('chart-line-' + id + key) === 'true';
@@ -177,9 +178,11 @@ function rates_chart(type_id, id, items, stats, rate_fmt, axis_fmt, type,
chart_data[id]['data'][name] = stats[key_details];
chart_data[id]['data'][name].ix = ix;
}
+ var value = chart_rates ? pick_rate(fmt, stats, key) :
+ pick_abs(fmt, stats, key);
legend.push({name: name,
key: key,
- value: rate_fmt(stats, key),
+ value: value,
show: show(key)});
ix++;
}
@@ -201,7 +204,7 @@ function rates_chart(type_id, id, items, stats, rate_fmt, axis_fmt, type,
return legend.length > 0 ? html : '';
}
-function rates_text(items, stats, mode, rate_fmt) {
+function rates_text(items, stats, mode, fmt, chart_rates) {
var res = '';
for (var i in items) {
var name = items[i][0];
@@ -209,9 +212,10 @@ function rates_text(items, stats, mode, rate_fmt) {
var key_details = key + '_details';
if (key_details in stats) {
var details = stats[key_details];
- res += '' + name;
- res += rate_fmt(stats, key, mode);
- res += ' ';
+ res += '' + name + '';
+ res += chart_rates ? pick_rate(fmt, stats, key, mode) :
+ pick_abs(fmt, stats, key, mode);
+ res += ' ';
}
}
return res == '' ? '' : '' + res + ' ';
diff --git a/deps/rabbitmq_management/priv/www/js/formatters.js b/deps/rabbitmq_management/priv/www/js/formatters.js
index b076a73afe..8528f4b2c5 100644
--- a/deps/rabbitmq_management/priv/www/js/formatters.js
+++ b/deps/rabbitmq_management/priv/www/js/formatters.js
@@ -12,11 +12,6 @@ function fmt_string(str, unknown) {
return fmt_escape_html("" + str);
}
-function fmt_bytes(bytes) {
- if (bytes == undefined) return UNKNOWN_REPR;
- return fmt_si_prefix(bytes, bytes, 1024, false) + 'B';
-}
-
function fmt_si_prefix(num0, max0, thousand, allow_fractions) {
if (num == 0) return 0;
@@ -228,71 +223,51 @@ function fmt_percent(num) {
}
}
-function fmt_rate(obj, name, mode) {
- var raw = fmt_rate0(obj, name, mode, fmt_rate_num);
- return raw == '' ? '' : (raw + '/s');
-}
-
-function fmt_rate_bytes(obj, name, mode) {
- var raw = fmt_rate0(obj, name, mode, fmt_bytes);
- return raw == '' ? '' : (raw + '/s' +
- '(' + fmt_bytes(obj[name]) + ' total)');
-}
-
-function fmt_bytes_obj(obj, name, mode) {
- return fmt_bytes(obj[name]);
-}
-
-function fmt_num_obj(obj, name, mode) {
- return obj[name];
-}
-
-function fmt_rate_large(obj, name, mode) {
- return '' + fmt_rate0(obj, name, mode, fmt_rate_num) +
- 'msg/s';
-}
-
-function fmt_rate_bytes_large(obj, name, mode) {
- return '' + fmt_rate0(obj, name, mode, fmt_bytes) + '/s' +
- '(' + fmt_bytes(obj[name]) + ' total)';
-}
-
-function fmt_rate0(obj, name, mode, fmt) {
+function pick_rate(fmt, obj, name, mode) {
if (obj == undefined || obj[name] == undefined ||
obj[name + '_details'] == undefined) return '';
var details = obj[name + '_details'];
return fmt(mode == 'avg' ? details.avg_rate : details.rate);
}
-function fmt_msgs(obj, name, mode) {
- return fmt_msgs0(obj, name, mode) + ' msg';
-}
-
-function fmt_msgs_large(obj, name, mode) {
- return '' + fmt_msgs0(obj, name, mode) + '' +
- fmt_rate0(obj, name, mode, fmt_msgs_rate);
-}
-
-function fmt_msgs0(obj, name, mode) {
+function pick_abs(fmt, obj, name, mode) {
if (obj == undefined || obj[name] == undefined ||
obj[name + '_details'] == undefined) return '';
var details = obj[name + '_details'];
- return mode == 'avg' ? fmt_rate_num(details.avg) :
- fmt_num_thousands(obj[name]);
+ return fmt(mode == 'avg' ? details.avg : obj[name]);
}
-function fmt_msgs_rate(num) {
- if (num > 0) return '+' + fmt_rate_num(num) + ' msg/s';
- else if (num < 0) return '-' + fmt_rate_num(-num) + ' msg/s';
- else return ' ';
+function fmt_detail_rate(obj, name, mode) {
+ return pick_rate(fmt_rate, name, mode);
+}
+
+function fmt_detail_rate_bytes(obj, name, mode) {
+ return pick_rate(fmt_rate_bytes, name, mode);
+}
+
+// ---------------------------------------------------------------------
+
+// These are pluggable for charts etc
+
+function fmt_plain(num) {
+ return num;
+}
+
+function fmt_plain_axis(num, max) {
+ return fmt_si_prefix(num, max, 1000, true);
+}
+
+function fmt_rate(num) {
+ return fmt_rate_num(num) + '/s';
}
function fmt_rate_axis(num, max) {
- return fmt_si_prefix(num, max, 1000, true) + '/s';
+ return fmt_plain_axis(num, max) + '/s';
}
-function fmt_num_axis(num, max) {
- return fmt_si_prefix(num, max, 1000, true);
+function fmt_bytes(bytes) {
+ if (bytes == undefined) return UNKNOWN_REPR;
+ return fmt_si_prefix(bytes, bytes, 1024, false) + 'B';
}
function fmt_bytes_axis(num, max) {
@@ -300,11 +275,20 @@ function fmt_bytes_axis(num, max) {
return fmt_bytes(isNaN(num) ? 0 : num);
}
+function fmt_rate_bytes(num) {
+ return fmt_bytes(num) + '/s';
+}
function fmt_rate_bytes_axis(num, max) {
return fmt_bytes_axis(num, max) + '/s';
}
+function fmt_ms(num) {
+ return fmt_rate_num(num) + 'ms';
+}
+
+// ---------------------------------------------------------------------
+
function fmt_maybe_vhost(name) {
return vhosts_interesting ?
' in virtual host ' + fmt_escape_html(name) + ''
diff --git a/deps/rabbitmq_management/priv/www/js/global.js b/deps/rabbitmq_management/priv/www/js/global.js
index d60602ca42..a1612fb52f 100644
--- a/deps/rabbitmq_management/priv/www/js/global.js
+++ b/deps/rabbitmq_management/priv/www/js/global.js
@@ -137,6 +137,7 @@ var COLUMNS =
// All these are to do with hiding UI elements if
var rates_mode; // ...there are no fine stats
var user_administrator; // ...user is not an admin
+var user_policymaker; // ...user is not a policymaker
var user_monitor; // ...user cannot monitor
var nodes_interesting; // ...we are not in a cluster
var vhosts_interesting; // ...there is only one vhost
@@ -164,6 +165,7 @@ function setup_global_vars() {
rates_mode = overview.rates_mode;
user_tags = expand_user_tags(user.tags.split(","));
user_administrator = jQuery.inArray("administrator", user_tags) != -1;
+ user_policymaker = jQuery.inArray("policymaker", user_tags) != -1;
user_monitor = jQuery.inArray("monitoring", user_tags) != -1;
replace_content('login-details',
'User: ' + user.name + ' ' +
diff --git a/deps/rabbitmq_management/priv/www/js/help.js b/deps/rabbitmq_management/priv/www/js/help.js
index 191246bf87..003df912b7 100644
--- a/deps/rabbitmq_management/priv/www/js/help.js
+++ b/deps/rabbitmq_management/priv/www/js/help.js
@@ -251,6 +251,28 @@ HELP = {
'plugins' :
'Note that only plugins which are both explicitly enabled and running are shown here.',
+ 'io-operations':
+ 'Rate of I/O operations. Only operations performed by the message \
+ persister are shown here (e.g. metadata changes in Mnesia or writes \
+ to the log files are not shown).\
+ \
+ - Read
\
+ - Rate at which data is read from the disk.
\
+ - Write
\
+ - Rate at which data is written to the disk.
\
+ - Seek
\
+ - Rate at which the broker switches position while reading or \
+ writing to disk.
\
+ - Sync
\
+ - Rate at which the broker invokes
fsync() to ensure \
+ data is flushed to disk. \
+ - Reopen
\
+ - Rate at which the broker recycles file handles in order to support \
+ more queues than it has file handles. If this operation is occurring \
+ frequently you may get a performance boost from increasing the number \
+ of file handles available.
\
+ ',
+
'foo': 'foo' // No comma.
};
diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/channels-list.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/channels-list.ejs
index 96442b9167..591a7c04b2 100644
--- a/deps/rabbitmq_management/priv/www/js/tmpl/channels-list.ejs
+++ b/deps/rabbitmq_management/priv/www/js/tmpl/channels-list.ejs
@@ -167,22 +167,22 @@
<% } %>
<% if (rates_mode != 'none') { %>
<% if (show_column('channels', 'rate-publish')) { %>
- | <%= fmt_rate(channel.message_stats, 'publish') %> |
+ <%= fmt_detail_rate(channel.message_stats, 'publish') %> |
<% } %>
<% if (show_column('channels', 'rate-confirm')) { %>
- <%= fmt_rate(channel.message_stats, 'confirm') %> |
+ <%= fmt_detail_rate(channel.message_stats, 'confirm') %> |
<% } %>
<% if (show_column('channels', 'rate-return')) { %>
- <%= fmt_rate(channel.message_stats, 'return_unroutable') %> |
+ <%= fmt_detail_rate(channel.message_stats, 'return_unroutable') %> |
<% } %>
<% if (show_column('channels', 'rate-deliver')) { %>
- <%= fmt_rate(channel.message_stats, 'deliver_get') %> |
+ <%= fmt_detail_rate(channel.message_stats, 'deliver_get') %> |
<% } %>
<% if (show_column('channels', 'rate-redeliver')) { %>
- <%= fmt_rate(channel.message_stats, 'redeliver') %> |
+ <%= fmt_detail_rate(channel.message_stats, 'redeliver') %> |
<% } %>
<% if (show_column('channels', 'rate-ack')) { %>
- <%= fmt_rate(channel.message_stats, 'ack') %> |
+ <%= fmt_detail_rate(channel.message_stats, 'ack') %> |
<% } %>
<% } %>
diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs
index af5120f814..317328185e 100644
--- a/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs
+++ b/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs
@@ -115,10 +115,10 @@
-
Statistics
+
Process Statistics
<% if (!node.running) { %>
Node not running
@@ -106,7 +106,7 @@
<% if (node.mem_limit != 'memory_monitoring_disabled') { %>
<%= node_stat('mem_used', 'Used', 'mem_limit', 'high watermark', node,
- fmt_bytes_obj, fmt_bytes_axis,
+ fmt_bytes, fmt_bytes_axis,
node.mem_alarm ? 'red' : 'green',
node.mem_alarm ? 'memory-alarm' : null) %>
<% } else { %>
@@ -121,7 +121,7 @@
|
<% if (node.disk_free_limit != 'disk_free_monitoring_disabled') { %>
<%= node_stat('disk_free', 'Free', 'disk_free_limit', 'low watermark', node,
- fmt_bytes_obj, fmt_bytes_axis,
+ fmt_bytes, fmt_bytes_axis,
node.disk_free_alarm ? 'red' : 'green',
node.disk_free_alarm ? 'disk_free-alarm' : null,
true) %>
@@ -137,6 +137,25 @@
+
+ I/O Statistics
+
+<% if (!node.running) { %>
+ Node not running
+<% } else if (node.os_pid == undefined) { %>
+ Node statistics not available
+<% } else { %>
+ <%= rates_chart_or_text('persister-stats-count', node, [['Read', 'persister_read_count'], ['Write', 'persister_write_count'], ['Seek', 'persister_seek_count'], ['Sync', 'persister_sync_count'], ['Reopen', 'persister_reopen_count']], fmt_rate, fmt_rate_axis, true, 'Operations', 'io-operations') %>
+
+ <%= rates_chart_or_text('persister-stats-bytes', node, [['Read', 'persister_read_bytes'], ['Write', 'persister_write_bytes']], fmt_rate_bytes, fmt_rate_bytes_axis, true, 'Data rates') %>
+
+ <%= rates_chart_or_text('persister-stats-time', node, [['Read', 'persister_read_avg_time'], ['Write', 'persister_write_avg_time'], ['Seek', 'persister_seek_avg_time'], ['Sync', 'persister_sync_avg_time']], fmt_ms, fmt_ms, false, 'Average time per operation') %>
+
+<% } %>
+
+
+
+
Memory details
diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/queue.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/queue.ejs
index 272440a061..b43be0c62e 100644
--- a/deps/rabbitmq_management/priv/www/js/tmpl/queue.ejs
+++ b/deps/rabbitmq_management/priv/www/js/tmpl/queue.ejs
@@ -245,6 +245,51 @@
+<% if (user_policymaker) { %>
+
+ Move messages
+
+ <% if (NAVIGATION['Admin'][0]['Shovel Management'] == undefined) { %>
+ To move messages, the shovel plugin must be enabled, try:
+ $ rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management
+ <% } else { %>
+
+ The shovel plugin can be used to move messages from this queue
+ to another one. The form below will create a temporary shovel to
+ move messages to another queue on the same virtual host, with
+ default settings.
+
+
+ For more options see the shovel
+ interface.
+
+
+ <% } %>
+
+
+<% } %>
+
Delete / purge
diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/queues.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/queues.ejs
index 3dc65c8e56..3f3b3472cf 100644
--- a/deps/rabbitmq_management/priv/www/js/tmpl/queues.ejs
+++ b/deps/rabbitmq_management/priv/www/js/tmpl/queues.ejs
@@ -160,16 +160,16 @@
<% } %>
<% if (rates_mode != 'none') { %>
<% if (show_column('queues', 'rate-incoming')) { %>
- <%= fmt_rate(queue.message_stats, 'publish') %> |
+ <%= fmt_detail_rate(queue.message_stats, 'publish') %> |
<% } %>
<% if (show_column('queues', 'rate-deliver')) { %>
- <%= fmt_rate(queue.message_stats, 'deliver_get') %> |
+ <%= fmt_detail_rate(queue.message_stats, 'deliver_get') %> |
<% } %>
<% if (show_column('queues', 'rate-redeliver')) { %>
- <%= fmt_rate(queue.message_stats, 'redeliver') %> |
+ <%= fmt_detail_rate(queue.message_stats, 'redeliver') %> |
<% } %>
<% if (show_column('queues', 'rate-ack')) { %>
- <%= fmt_rate(queue.message_stats, 'ack') %> |
+ <%= fmt_detail_rate(queue.message_stats, 'ack') %> |
<% } %>
<% } %>
diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/vhosts.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/vhosts.ejs
index 285af23edd..a6cbe9faf5 100644
--- a/deps/rabbitmq_management/priv/www/js/tmpl/vhosts.ejs
+++ b/deps/rabbitmq_management/priv/www/js/tmpl/vhosts.ejs
@@ -64,17 +64,17 @@
<%= fmt_num_thousands(vhost.messages) %> |
<% } %>
<% if (show_column('vhosts', 'from_client')) { %>
- <%= fmt_rate_bytes(vhost, 'recv_oct') %> |
+ <%= fmt_detail_rate_bytes(vhost, 'recv_oct') %> |
<% } %>
<% if (show_column('vhosts', 'to_client')) { %>
- <%= fmt_rate_bytes(vhost, 'send_oct') %> |
+ <%= fmt_detail_rate_bytes(vhost, 'send_oct') %> |
<% } %>
<% if (rates_mode != 'none') { %>
<% if (show_column('vhosts', 'rate-publish')) { %>
- <%= fmt_rate(vhost.message_stats, 'publish') %> |
+ <%= fmt_detail_rate(vhost.message_stats, 'publish') %> |
<% } %>
<% if (show_column('vhosts', 'rate-deliver')) { %>
- <%= fmt_rate(vhost.message_stats, 'deliver_get') %> |
+ <%= fmt_detail_rate(vhost.message_stats, 'deliver_get') %> |
<% } %>
<% } %>
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_db.erl b/deps/rabbitmq_management/src/rabbit_mgmt_db.erl
index 61696883e0..8dd1c4ae1e 100644
--- a/deps/rabbitmq_management/src/rabbit_mgmt_db.erl
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_db.erl
@@ -159,7 +159,19 @@
[messages, messages_ready, messages_unacknowledged]).
-define(COARSE_NODE_STATS,
- [mem_used, fd_used, sockets_used, proc_used, disk_free]).
+ [mem_used, fd_used, sockets_used, proc_used, disk_free,
+ persister_read_count, persister_read_bytes, persister_read_avg_time,
+ persister_write_count, persister_write_bytes, persister_write_avg_time,
+ persister_sync_count, persister_sync_avg_time,
+ persister_seek_count, persister_seek_avg_time,
+ persister_reopen_count]).
+
+%% Normally 0 and no history means "has never happened, don't
+%% report". But for these things we do want to report even at 0 with
+%% no history.
+-define(ALWAYS_REPORT_STATS,
+ [persister_read_avg_time, persister_write_avg_time,
+ persister_sync_avg_time | ?COARSE_QUEUE_STATS]).
-define(COARSE_CONN_STATS, [recv_oct, send_oct]).
@@ -572,8 +584,10 @@ handle_event(#event{type = consumer_deleted, props = Props}, State) ->
%% TODO: we don't clear up after dead nodes here - this is a very tiny
%% leak every time a node is permanently removed from the cluster. Do
%% we care?
-handle_event(#event{type = node_stats, props = Stats, timestamp = Timestamp},
+handle_event(#event{type = node_stats, props = Stats0, timestamp = Timestamp},
State) ->
+ Stats = proplists:delete(persister_stats, Stats0) ++
+ pget(persister_stats, Stats0),
handle_stats(node_stats, Stats, Timestamp, [], ?COARSE_NODE_STATS, State);
handle_event(_Event, State) ->
@@ -965,7 +979,7 @@ format_detail_id(#resource{name = Name, virtual_host = Vhost, kind = Kind},
format_samples(Ranges, ManyStats, #state{interval = Interval}) ->
lists:append(
[case rabbit_mgmt_stats:is_blank(Stats) andalso
- not lists:member(K, ?COARSE_QUEUE_STATS) of
+ not lists:member(K, ?ALWAYS_REPORT_STATS) of
true -> [];
false -> {Details, Counter} = rabbit_mgmt_stats:format(
pick_range(K, Ranges),
@@ -1095,7 +1109,7 @@ gc_batch(State = #state{aggregated_stats = ETS}) ->
gc_batch(0, _Policies, State) ->
State;
gc_batch(Rows, Policies, State = #state{aggregated_stats = ETS,
- gc_next_key = Key0}) ->
+ gc_next_key = Key0}) ->
Key = case Key0 of
undefined -> ets:first(ETS);
_ -> ets:next(ETS, Key0)
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_format.erl b/deps/rabbitmq_management/src/rabbit_mgmt_format.erl
index de19e62668..2613dcc1da 100644
--- a/deps/rabbitmq_management/src/rabbit_mgmt_format.erl
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_format.erl
@@ -157,9 +157,8 @@ internal_user(User) ->
{tags, tags(User#internal_user.tags)}].
user(User) ->
- [{name, User#user.username},
- {tags, tags(User#user.tags)},
- {auth_backend, User#user.auth_backend}].
+ [{name, User#user.username},
+ {tags, tags(User#user.tags)}].
tags(Tags) ->
list_to_binary(string:join([atom_to_list(T) || T <- Tags], ",")).
diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_util.erl b/deps/rabbitmq_management/src/rabbit_mgmt_util.erl
index 0cadb66b29..ba6cd257a7 100644
--- a/deps/rabbitmq_management/src/rabbit_mgmt_util.erl
+++ b/deps/rabbitmq_management/src/rabbit_mgmt_util.erl
@@ -28,7 +28,7 @@
-export([with_channel/4, with_channel/5]).
-export([props_to_method/2, props_to_method/4]).
-export([all_or_one_vhost/2, http_to_amqp/5, reply/3, filter_vhost/3]).
--export([filter_conn_ch_list/3, filter_user/2, list_login_vhosts/1]).
+-export([filter_conn_ch_list/3, filter_user/2, list_login_vhosts/2]).
-export([with_decode/5, decode/1, decode/2, redirect/2, set_resp_header/3,
args/1]).
-export([reply_list/3, reply_list/4, sort_list/2, destination_type/1]).
@@ -77,7 +77,7 @@ user_matches_vhost(ReqData, User) ->
case vhost(ReqData) of
not_found -> true;
none -> true;
- V -> lists:member(V, list_login_vhosts(User))
+ V -> lists:member(V, list_login_vhosts(User, peersock(ReqData)))
end.
%% Used for connections / channels. A normal user can only see / delete
@@ -143,12 +143,15 @@ is_authorized(ReqData, Context, Username, Password, ErrorMsg, Fun) ->
not_authorised(<<"Login failed">>, ReqData, Context)
end.
-%% We can't use wrq:peer/1 because that trusts X-Forwarded-For.
peer(ReqData) ->
- WMState = ReqData#wm_reqdata.wm_state,
- {ok, {IP,_Port}} = peername(WMState#wm_reqstate.socket),
+ {ok, {IP,_Port}} = peername(peersock(ReqData)),
IP.
+%% We can't use wrq:peer/1 because that trusts X-Forwarded-For.
+peersock(ReqData) ->
+ WMState = ReqData#wm_reqdata.wm_state,
+ WMState#wm_reqstate.socket.
+
%% Like the one in rabbit_net, but we and webmachine have a different
%% way of wrapping
peername(Sock) when is_port(Sock) -> inet:peername(Sock);
@@ -452,6 +455,8 @@ with_channel(VHost, ReqData,
end;
{error, {auth_failure, Msg}} ->
not_authorised(Msg, ReqData, Context);
+ {error, access_refused} ->
+ not_authorised(<<"Access refused.">>, ReqData, Context);
{error, {nodedown, N}} ->
bad_request(
list_to_binary(
@@ -470,8 +475,8 @@ all_or_one_vhost(ReqData, Fun) ->
VHost -> Fun(VHost)
end.
-filter_vhost(List, _ReqData, Context) ->
- VHosts = list_login_vhosts(Context#context.user),
+filter_vhost(List, ReqData, Context) ->
+ VHosts = list_login_vhosts(Context#context.user, peersock(ReqData)),
[I || I <- List, lists:member(pget(vhost, I), VHosts)].
filter_user(List, _ReqData, #context{user = User}) ->
@@ -533,12 +538,12 @@ intersects(A, B) -> lists:any(fun(I) -> lists:member(I, B) end, A).
list_visible_vhosts(User = #user{tags = Tags}) ->
case is_monitor(Tags) of
true -> rabbit_vhost:list();
- false -> list_login_vhosts(User)
+ false -> list_login_vhosts(User, undefined)
end.
-list_login_vhosts(User) ->
+list_login_vhosts(User, Sock) ->
[V || V <- rabbit_vhost:list(),
- case catch rabbit_access_control:check_vhost_access(User, V) of
+ case catch rabbit_access_control:check_vhost_access(User, V, Sock) of
ok -> true;
_ -> false
end].
|