Merge "Improve exception message in network related Batch/DeleteAction"

This commit is contained in:
Zuul 2018-01-25 11:49:14 +00:00 committed by Gerrit Code Review
commit e499c08881
6 changed files with 74 additions and 176 deletions

View File

@ -17,7 +17,6 @@ import logging
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from horizon import exceptions
from horizon import tables
@ -33,38 +32,6 @@ from openstack_dashboard.usage import quotas
LOG = logging.getLogger(__name__)
class DeleteSubnet(proj_tables.SubnetPolicyTargetMixin, tables.DeleteAction):
@staticmethod
def action_present(count):
return ungettext_lazy(
u"Delete Subnet",
u"Delete Subnets",
count
)
@staticmethod
def action_past(count):
return ungettext_lazy(
u"Deleted Subnet",
u"Deleted Subnets",
count
)
policy_rules = (("network", "delete_subnet"),)
def delete(self, request, obj_id):
try:
api.neutron.subnet_delete(request, obj_id)
except Exception as e:
LOG.info('Failed to delete subnet %(id)s: %(exc)s',
{'id': obj_id, 'exc': e})
msg = _('Failed to delete subnet %s') % obj_id
network_id = self.table.kwargs['network_id']
redirect = reverse('horizon:admin:networks:detail',
args=[network_id])
exceptions.handle(request, msg, redirect=redirect)
class CreateSubnet(proj_tables.SubnetPolicyTargetMixin, tables.LinkAction):
name = "create"
verbose_name = _("Create Subnet")
@ -149,8 +116,9 @@ class SubnetsTable(tables.DataTable):
class Meta(object):
name = "subnets"
verbose_name = _("Subnets")
table_actions = (CreateSubnet, DeleteSubnet, tables.FilterAction,)
row_actions = (UpdateSubnet, DeleteSubnet,)
table_actions = (CreateSubnet, proj_tables.DeleteSubnet,
tables.FilterAction,)
row_actions = (UpdateSubnet, proj_tables.DeleteSubnet,)
hidden_title = False
def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):

View File

@ -14,11 +14,9 @@
import logging
from django.core.urlresolvers import reverse
from django.template import defaultfilters as filters
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from horizon import exceptions
from horizon import tables
@ -32,36 +30,6 @@ from openstack_dashboard.usage import quotas
LOG = logging.getLogger(__name__)
class DeleteNetwork(policy.PolicyTargetMixin, tables.DeleteAction):
@staticmethod
def action_present(count):
return ungettext_lazy(
u"Delete Network",
u"Delete Networks",
count
)
@staticmethod
def action_past(count):
return ungettext_lazy(
u"Deleted Network",
u"Deleted Networks",
count
)
policy_rules = (("network", "delete_network"),)
def delete(self, request, obj_id):
try:
api.neutron.network_delete(request, obj_id)
except Exception as e:
LOG.info('Failed to delete network %(id)s: %(exc)s',
{'id': obj_id, 'exc': e})
msg = _('Failed to delete network %s') % obj_id
redirect = reverse('horizon:admin:networks:index')
exceptions.handle(request, msg, redirect=redirect)
class CreateNetwork(tables.LinkAction):
name = "create"
verbose_name = _("Create Network")
@ -147,9 +115,9 @@ class NetworksTable(tables.DataTable):
class Meta(object):
name = "networks"
verbose_name = _("Networks")
table_actions = (CreateNetwork, DeleteNetwork,
table_actions = (CreateNetwork, project_tables.DeleteNetwork,
AdminNetworksFilterAction)
row_actions = (EditNetwork, CreateSubnet, DeleteNetwork)
row_actions = (EditNetwork, CreateSubnet, project_tables.DeleteNetwork)
def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
super(NetworksTable, self).__init__(

View File

@ -14,6 +14,8 @@
import logging
from neutronclient.common import exceptions as neutron_exceptions
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
@ -21,6 +23,7 @@ from django.utils.translation import ungettext_lazy
from horizon import exceptions
from horizon import tables
from horizon.tables import actions
from horizon.utils import memoized
from openstack_dashboard import api
@ -73,17 +76,20 @@ class DeleteSubnet(SubnetPolicyTargetMixin, tables.DeleteAction):
policy_rules = (("network", "delete_subnet"),)
@actions.handle_exception_with_detail_message(
# normal_log_message
'Failed to delete subnet %(id)s: %(exc)s',
# target_exception
neutron_exceptions.Conflict,
# target_log_message
'Unable to delete subnet %(id)s with 409 Conflict: %(exc)s',
# target_user_message
_('Unable to delete subnet %(name)s. Most possible reason is because '
'one or more ports have an IP allocation from this subnet.'),
# logger_name
__name__)
def delete(self, request, obj_id):
try:
api.neutron.subnet_delete(request, obj_id)
except Exception as e:
LOG.info('Failed to delete subnet %(id)s: %(exc)s',
{'id': obj_id, 'exc': e})
msg = _('Failed to delete subnet %s') % obj_id
network_id = self.table.kwargs['network_id']
redirect = reverse('horizon:project:networks:detail',
args=[network_id])
exceptions.handle(request, msg, redirect=redirect)
class CreateSubnet(SubnetPolicyTargetMixin, tables.LinkAction):

View File

@ -13,7 +13,6 @@
# under the License.
import logging
from django.core.urlresolvers import reverse_lazy
from django import template
from django.template import defaultfilters as filters
from django.utils.translation import pgettext_lazy
@ -23,6 +22,7 @@ from neutronclient.common import exceptions as neutron_exceptions
from horizon import exceptions
from horizon import tables
from horizon.tables import actions
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.networks.subnets import tables \
@ -53,34 +53,24 @@ class DeleteNetwork(policy.PolicyTargetMixin, tables.DeleteAction):
policy_rules = (("network", "delete_network"),)
@actions.handle_exception_with_detail_message(
# normal_log_message
'Failed to delete network %(id)s: %(exc)s',
# target_exception
neutron_exceptions.Conflict,
# target_log_message
'Unable to delete network %(id)s with 409 Conflict: %(exc)s',
# target_user_message
_('Unable to delete network %(name)s. Most possible reason is because '
'one or more ports still exist on the requested network.'),
# logger_name
__name__)
def delete(self, request, network_id):
network_name = network_id
redirect_url = reverse_lazy("horizon:project:networks:index")
try:
# Retrieve the network list.
network = api.neutron.network_get(request, network_id,
expand_subnet=False)
network_name = network.name
network = self.table.get_object_by_id(network_id)
LOG.debug('Network %(network_id)s has subnets: %(subnets)s',
{'network_id': network_id, 'subnets': network.subnets})
for subnet_id in network.subnets:
api.neutron.subnet_delete(request, subnet_id)
LOG.debug('Deleted subnet %s', subnet_id)
api.neutron.network_delete(request, network_id)
LOG.debug('Deleted network %s successfully', network_id)
except neutron_exceptions.Conflict as e:
LOG.info('Failed to delete network %(id)s with 409 Conflict: '
'%(exc)s', {'id': network_id, 'exc': e})
msg = (_('Failed to delete network %(network_name)s. '
'Most possible case is that one or more ports still '
'exist on the requested network.') %
{"network_name": network_name, "subnet_id": subnet_id})
exceptions.handle(request, msg, redirect=redirect_url)
except Exception as e:
LOG.info('Failed to delete network %(id)s: %(exc)s',
{'id': network_id, 'exc': e})
msg = _('Failed to delete network %s') % network_name
exceptions.handle(request, msg, redirect=redirect_url)
class CreateNetwork(tables.LinkAction):

View File

@ -1011,10 +1011,6 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
def test_delete_network_no_subnet(self):
network = self.networks.first()
network.subnets = []
api.neutron.network_get(IsA(http.HttpRequest),
network.id,
expand_subnet=False)\
.AndReturn(network)
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'network_availability_zone')\
.MultipleTimes().AndReturn(True)
@ -1030,23 +1026,13 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
@test.create_stubs({api.neutron: ('network_get',
'network_list',
'network_delete',
'subnet_delete',
'is_extension_supported')})
def test_delete_network_with_subnet(self):
network = self.networks.first()
network.subnets = [subnet.id for subnet in network.subnets]
subnet_id = network.subnets[0]
subnetv6_id = network.subnets[1]
api.neutron.network_get(IsA(http.HttpRequest),
network.id,
expand_subnet=False)\
.AndReturn(network)
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'network_availability_zone')\
.MultipleTimes().AndReturn(True)
self._stub_net_list()
api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
api.neutron.network_delete(IsA(http.HttpRequest), network.id)
self.mox.ReplayAll()
@ -1059,23 +1045,13 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
@test.create_stubs({api.neutron: ('network_get',
'network_list',
'network_delete',
'subnet_delete',
'is_extension_supported')})
def test_delete_network_exception(self):
network = self.networks.first()
network.subnets = [subnet.id for subnet in network.subnets]
subnet_id = network.subnets[0]
subnetv6_id = network.subnets[1]
api.neutron.network_get(IsA(http.HttpRequest),
network.id,
expand_subnet=False)\
.AndReturn(network)
api.neutron.is_extension_supported(
IsA(http.HttpRequest), 'network_availability_zone')\
.MultipleTimes().AndReturn(True)
self._stub_net_list()
api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
.AndRaise(self.exceptions.neutron)

View File

@ -19,11 +19,11 @@ from django.template import defaultfilters as filters
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from neutronclient.common import exceptions as q_ext
from neutronclient.common import exceptions as neutron_exceptions
from horizon import exceptions
from horizon import messages
from horizon import tables
from horizon.tables import actions
from openstack_dashboard import api
from openstack_dashboard import policy
@ -53,8 +53,18 @@ class DeleteRouter(policy.PolicyTargetMixin, tables.DeleteAction):
redirect_url = "horizon:project:routers:index"
policy_rules = (("network", "delete_router"),)
@actions.handle_exception_with_detail_message(
# normal_log_message
'Failed to delete router %(id)s: %(exc)s',
# target_exception
neutron_exceptions.NeutronClientException,
# target_log_message
'Unable to delete router %(id)s: %(exc)s',
# target_user_message
_('Unable to delete router %(name)s: %(exc)s'),
# logger_name
__name__)
def delete(self, request, obj_id):
try:
# detach all interfaces before attempting to delete the router
search_opts = {'device_owner': 'network:router_interface',
'device_id': obj_id}
@ -63,28 +73,6 @@ class DeleteRouter(policy.PolicyTargetMixin, tables.DeleteAction):
api.neutron.router_remove_interface(request, obj_id,
port_id=port.id)
api.neutron.router_delete(request, obj_id)
except q_ext.NeutronClientException as e:
# TODO(amotoki): Revisit why Http302 needs to be raised.
# We have this pattern ONLY HERE.
# Can't we merge two except clauses?
LOG.info('Unable to delete router %(id)s: %(exc)s',
{'id': obj_id, 'exc': e})
obj = self.table.get_object_by_id(obj_id)
name = self.table.get_object_display(obj)
msg = _('Unable to delete router "%s"') % name
messages.error(request, msg)
redirect = reverse(self.redirect_url)
raise exceptions.Http302(redirect, message=msg)
except Exception as e:
LOG.info('Unable to delete router %(id)s: %(exc)s',
{'id': obj_id, 'exc': e})
obj = self.table.get_object_by_id(obj_id)
name = self.table.get_object_display(obj)
msg = _('Unable to delete router "%s"') % name
exceptions.handle(request, msg)
def allowed(self, request, router=None):
return True
class CreateRouter(tables.LinkAction):
@ -159,19 +147,21 @@ class ClearGateway(policy.PolicyTargetMixin, tables.BatchAction):
policy_rules = (("network", "update_router"),)
action_type = "danger"
@actions.handle_exception_with_detail_message(
# normal_log_message
'Unable to clear gateway for router %(id)s: %(exc)s',
# target_exception
neutron_exceptions.Conflict,
# target_log_message
'Unable to clear gateway for router %(id)s: %(exc)s',
# target_user_message
_('Unable to clear gateway for router %(name)s. '
'Most possible reason is because the gateway is required '
'by one or more floating IPs'),
# logger_name
__name__)
def action(self, request, obj_id):
obj = self.table.get_object_by_id(obj_id)
name = self.table.get_object_display(obj)
try:
api.neutron.router_remove_gateway(request, obj_id)
except Exception as e:
LOG.info('Unable to clear gateway for router %(id)s: %(exc)s',
{'id': obj_id, 'exc': e})
msg = (_('Unable to clear gateway for router '
'"%(name)s": "%(msg)s"')
% {"name": name, "msg": e})
redirect = reverse(self.redirect_url)
exceptions.handle(request, msg, redirect=redirect)
def get_success_url(self, request):
return reverse(self.redirect_url)