Fix handling of missing external network

When an external network can't be found, project/routers/index.html will
result in a type error caused by calling exceptions.handle when no
exception is present.  In this case, an error message should be
displayed, and the missing-network should be indicated to the user.

Also added tests for this case.

Change-Id: I3aaa64de28738051ad84cc587fbb6cfd546f4662
Closes-Bug: 1220345
This commit is contained in:
woodm1979 2014-02-24 10:32:36 -07:00 committed by Matthew D. Wood
parent 59e410eb24
commit d9ecd8d157
3 changed files with 52 additions and 5 deletions

View File

@ -59,3 +59,21 @@ class RouterTests(test.BaseAdminViewTests, r_test.RouterTests):
self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
self.assertEqual(len(res.context['table'].data), 0)
self.assertMessageCount(res, error=1)
@test.create_stubs({api.neutron: ('router_list', 'network_list')})
def test_set_external_network_empty(self):
router = self.routers.first()
api.neutron.router_list(
IsA(http.HttpRequest),
search_opts=None).AndReturn([router])
self._mock_external_network_list(alter_ids=True)
self.mox.ReplayAll()
res = self.client.get(self.INDEX_URL)
table_data = res.context['table'].data
self.assertEqual(len(table_data), 1)
self.assertIn('(Not Found)',
table_data[0]['external_gateway_info']['network'])
self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
self.assertMessageCount(res, error=2)

View File

@ -15,6 +15,7 @@ import copy
from django.core.urlresolvers import reverse
from django import http
from mox import IsA # noqa
from openstack_dashboard import api
@ -28,9 +29,12 @@ class RouterTests(test.TestCase):
INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD)
DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD
def _mock_external_network_list(self):
def _mock_external_network_list(self, alter_ids=False):
search_opts = {'router:external': True}
ext_nets = [n for n in self.networks.list() if n['router:external']]
if alter_ids:
for ext_net in ext_nets:
ext_net.id += 'some extra garbage'
api.neutron.network_list(
IsA(http.HttpRequest),
**search_opts).AndReturn(ext_nets)
@ -71,6 +75,25 @@ class RouterTests(test.TestCase):
self.assertEqual(len(res.context['table'].data), 0)
self.assertMessageCount(res, error=1)
@test.create_stubs({api.neutron: ('router_list', 'network_list')})
def test_set_external_network_empty(self):
router = self.routers.first()
api.neutron.router_list(
IsA(http.HttpRequest),
tenant_id=self.tenant.id,
search_opts=None).AndReturn([router])
self._mock_external_network_list(alter_ids=True)
self.mox.ReplayAll()
res = self.client.get(self.INDEX_URL)
table_data = res.context['table'].data
self.assertEqual(len(table_data), 1)
self.assertIn('(Not Found)',
table_data[0]['external_gateway_info']['network'])
self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
self.assertMessageCount(res, error=1)
@test.create_stubs({api.neutron: ('router_get', 'port_list',
'network_get')})
def test_router_detail(self):

View File

@ -23,6 +23,7 @@ from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon import tables
from horizon import tabs
from horizon.utils import memoized
@ -80,8 +81,13 @@ class IndexView(tables.DataTableView):
if ext_net_id in ext_net_dict:
gateway_info['network'] = ext_net_dict[ext_net_id]
else:
msg = _('External network "%s" not found.') % (ext_net_id)
exceptions.handle(self.request, msg)
msg_params = {'ext_net_id': ext_net_id, 'router_id': router.id}
msg = _('External network "%(ext_net_id)s" expected but not '
'found for router "%(router_id)s".') % msg_params
messages.error(self.request, msg)
# gateway_info['network'] is just the network name, so putting
# in a smallish error message in the table is reasonable.
gateway_info['network'] = _('%s (Not Found)') % ext_net_id
class DetailView(tabs.TabbedTableView):
@ -97,7 +103,7 @@ class DetailView(tabs.TabbedTableView):
router.set_id_as_name_if_empty(length=0)
except Exception:
msg = _('Unable to retrieve details for router "%s".') \
% (router_id)
% router_id
exceptions.handle(self.request, msg, redirect=self.failure_url)
if router.external_gateway_info:
ext_net_id = router.external_gateway_info['network_id']
@ -108,7 +114,7 @@ class DetailView(tabs.TabbedTableView):
router.external_gateway_info['network'] = ext_net.name
except Exception:
msg = _('Unable to retrieve an external network "%s".') \
% (ext_net_id)
% ext_net_id
exceptions.handle(self.request, msg)
router.external_gateway_info['network'] = ext_net_id
return router