Management part for internal shovels. Experimenting with owner linking
This commit is contained in:
parent
7a34bf8053
commit
f13f99303a
|
@ -1094,3 +1094,15 @@ function fmt_deprecation_phase(phase, deprecation_phases){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fmt_resource(res) {
|
||||
return `${res.kind} '${res.name}' in vhost '${res.virtual_host}'`;
|
||||
}
|
||||
|
||||
function fmt_resource_link(res) {
|
||||
if (res.kind == "queue") {
|
||||
return `${res.kind} '${link_queue(res.virtual_host, res.name, {})}' in vhost '${link_vhost(res.virtual_host)}'`;
|
||||
} else if (res.kind == "exchange") {
|
||||
return `${res.kind} '${link_exchange(res.virtual_host, res.name, {})}' in vhost '${link_vhost(res.virtual_host)}'`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,6 +206,27 @@ function fmt_shovel_endpoint(prefix, shovel) {
|
|||
return txt;
|
||||
}
|
||||
|
||||
function is_internal_shovel(shovel) {
|
||||
if (!shovel.hasOwnProperty('internal')) {
|
||||
return false;
|
||||
} else {
|
||||
return shovel['internal'];
|
||||
}
|
||||
}
|
||||
|
||||
function shovel_has_internal_owner(shovel) {
|
||||
if (!shovel.hasOwnProperty('internal_owner')) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function shovel_internal_owner(shovel) {
|
||||
return shovel.internal_owner;
|
||||
}
|
||||
|
||||
|
||||
function fallback_value(shovel, key1, key2) {
|
||||
var v = shovel.value[key1];
|
||||
return (v !== undefined ? v : shovel.value[key2]);
|
||||
|
|
|
@ -44,14 +44,23 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-hidden">
|
||||
|
||||
<div class="section-hidden">
|
||||
<h2>Delete this shovel</h2>
|
||||
<div class="hider">
|
||||
<form action="#/shovel-parameters" method="delete" class="confirm">
|
||||
<input type="hidden" name="component" value="shovel"/>
|
||||
<input type="hidden" name="vhost" value="<%= fmt_string(shovel.vhost) %>"/>
|
||||
<input type="hidden" name="name" value="<%= fmt_string(shovel.name) %>"/>
|
||||
<input type="submit" value="Delete this shovel"/>
|
||||
</form>
|
||||
<% if (!is_internal_shovel(shovel.value)) { %>
|
||||
<form action="#/shovel-parameters" method="delete" class="confirm">
|
||||
<input type="hidden" name="component" value="shovel"/>
|
||||
<input type="hidden" name="vhost" value="<%= fmt_string(shovel.vhost) %>"/>
|
||||
<input type="hidden" name="name" value="<%= fmt_string(shovel.name) %>"/>
|
||||
<input type="submit" value="Delete this shovel"/>
|
||||
</form>
|
||||
<% } else { %>
|
||||
<% if (shovel_has_internal_owner(shovel.value)) { %>
|
||||
<span>This shovel is internal and owned by <%= fmt_resource_link(shovel_internal_owner(shovel.value)) %>. Could be deleted only via CLI command with --force.</span>
|
||||
<% } else { %>
|
||||
<span>This shovel is internal. Could be deleted only via CLI command with '--force'.</span>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -79,45 +79,60 @@ is_authorized(ReqData, Context) ->
|
|||
|
||||
delete_resource(ReqData, #context{user = #user{username = Username}}=Context) ->
|
||||
VHost = rabbit_mgmt_util:id(vhost, ReqData),
|
||||
Reply = case rabbit_mgmt_util:id(name, ReqData) of
|
||||
none ->
|
||||
false;
|
||||
Name ->
|
||||
case get_shovel_node(VHost, Name, ReqData, Context) of
|
||||
undefined -> rabbit_log:error("Could not find shovel data for shovel '~ts' in vhost: '~ts'", [Name, VHost]),
|
||||
case is_restart(ReqData) of
|
||||
true ->
|
||||
false;
|
||||
%% this is a deletion attempt
|
||||
false ->
|
||||
%% if we do not know the node, use the local one
|
||||
try_delete(node(), VHost, Name, Username),
|
||||
true
|
||||
case rabbit_mgmt_util:id(name, ReqData) of
|
||||
none ->
|
||||
{false, ReqData, Context};
|
||||
Name ->
|
||||
case get_shovel_node(VHost, Name, ReqData, Context) of
|
||||
undefined -> rabbit_log:error("Could not find shovel data for shovel '~ts' in vhost: '~ts'", [Name, VHost]),
|
||||
case is_restart(ReqData) of
|
||||
true ->
|
||||
{false, ReqData, Context};
|
||||
%% this is a deletion attempt
|
||||
false ->
|
||||
%% if we do not know the node, use the local one
|
||||
case try_delete(node(), VHost, Name, Username) of
|
||||
true -> {true, ReqData, Context};
|
||||
%% NOTE: that how it was before, try_delete return was ignored and true returned ¯\_(ツ)_/¯
|
||||
false -> {true, ReqData, Context};
|
||||
locked -> Reply = cowboy_req:reply(405, #{<<"content-type">> => <<"text/plain">>},
|
||||
"Protected", ReqData),
|
||||
{halt, Reply, Context};
|
||||
%% NOTE: that how it was before, try_delete return was ignored and true returned ¯\_(ツ)_/¯
|
||||
error -> {true, ReqData, Context}
|
||||
end
|
||||
end;
|
||||
Node ->
|
||||
%% We must distinguish between a delete and a restart
|
||||
case is_restart(ReqData) of
|
||||
true ->
|
||||
rabbit_log:info("Asked to restart shovel '~ts' in vhost '~ts' on node '~s'", [Name, VHost, Node]),
|
||||
try erpc:call(Node, rabbit_shovel_util, restart_shovel, [VHost, Name], ?SHOVEL_CALLS_TIMEOUT_MS) of
|
||||
ok -> {true, ReqData, Context};
|
||||
{error, not_found} ->
|
||||
rabbit_log:error("Could not find shovel data for shovel '~s' in vhost: '~s'", [Name, VHost]),
|
||||
{false, ReqData, Context}
|
||||
catch _:Reason ->
|
||||
rabbit_log:error("Failed to restart shovel '~s' on vhost '~s', reason: ~p",
|
||||
[Name, VHost, Reason]),
|
||||
{false, ReqData, Context}
|
||||
end;
|
||||
Node ->
|
||||
%% We must distinguish between a delete and a restart
|
||||
case is_restart(ReqData) of
|
||||
true ->
|
||||
rabbit_log:info("Asked to restart shovel '~ts' in vhost '~ts' on node '~s'", [Name, VHost, Node]),
|
||||
try erpc:call(Node, rabbit_shovel_util, restart_shovel, [VHost, Name], ?SHOVEL_CALLS_TIMEOUT_MS) of
|
||||
ok -> true;
|
||||
{error, not_found} ->
|
||||
rabbit_log:error("Could not find shovel data for shovel '~s' in vhost: '~s'", [Name, VHost]),
|
||||
false
|
||||
catch _:Reason ->
|
||||
rabbit_log:error("Failed to restart shovel '~s' on vhost '~s', reason: ~p",
|
||||
[Name, VHost, Reason]),
|
||||
false
|
||||
end;
|
||||
|
||||
_ ->
|
||||
try_delete(Node, VHost, Name, Username),
|
||||
true
|
||||
|
||||
_ ->
|
||||
case try_delete(Node, VHost, Name, Username) of
|
||||
true -> {true, ReqData, Context};
|
||||
%% NOTE: that how it was before, try_delete return was ignored and true returned ¯\_(ツ)_/¯
|
||||
false -> {true, ReqData, Context};
|
||||
locked -> Reply = cowboy_req:reply(405, #{<<"content-type">> => <<"text/plain">>},
|
||||
"Protected", ReqData),
|
||||
{halt, Reply, Context};
|
||||
%% NOTE: that how it was before, try_delete return was ignored and true returned ¯\_(ツ)_/¯
|
||||
error -> {true, ReqData, Context}
|
||||
end
|
||||
|
||||
end
|
||||
end,
|
||||
{Reply, ReqData, Context}.
|
||||
end
|
||||
end.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
|
@ -168,7 +183,7 @@ find_matching_shovel(VHost, Name, Shovels) ->
|
|||
undefined
|
||||
end.
|
||||
|
||||
-spec try_delete(node(), vhost:name(), any(), rabbit_types:username()) -> boolean().
|
||||
-spec try_delete(node(), vhost:name(), any(), rabbit_types:username()) -> true | false | locked | error.
|
||||
try_delete(Node, VHost, Name, Username) ->
|
||||
rabbit_log:info("Asked to delete shovel '~ts' in vhost '~ts' on node '~s'", [Name, VHost, Node]),
|
||||
%% this will clear the runtime parameter, the ultimate way of deleting a dynamic Shovel eventually. MK.
|
||||
|
@ -177,8 +192,13 @@ try_delete(Node, VHost, Name, Username) ->
|
|||
{error, not_found} ->
|
||||
rabbit_log:error("Could not find shovel data for shovel '~s' in vhost: '~s'", [Name, VHost]),
|
||||
false
|
||||
catch _:Reason ->
|
||||
catch
|
||||
_:{exception, {amqp_error, resource_locked, Reason, _}} ->
|
||||
rabbit_log:error("Failed to delete shovel '~s' on vhost '~s', reason: ~p",
|
||||
[Name, VHost, Reason]),
|
||||
false
|
||||
locked;
|
||||
_:Reason ->
|
||||
rabbit_log:error("Failed to delete shovel '~s' on vhost '~s', reason: ~p",
|
||||
[Name, VHost, Reason]),
|
||||
error
|
||||
end.
|
||||
|
|
Loading…
Reference in New Issue