Merge "Add InvalidExternalNetwork exception to display correct error"
This commit is contained in:
commit
cd4727258f
@ -249,6 +249,11 @@ class InvalidExtensionEnv(BadRequest):
|
||||
message = _("Invalid extension environment: %(reason)s")
|
||||
|
||||
|
||||
class ExternalIpAddressExhausted(BadRequest):
|
||||
message = _("Unable to find any IP address on external "
|
||||
"network %(net_id)s.")
|
||||
|
||||
|
||||
class TooManyExternalNetworks(QuantumException):
|
||||
message = _("More than one external network exists")
|
||||
|
||||
|
@ -632,50 +632,39 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
|
||||
msg = _("Network %s is not a valid external network") % f_net_id
|
||||
raise q_exc.BadRequest(resource='floatingip', msg=msg)
|
||||
|
||||
try:
|
||||
with context.session.begin(subtransactions=True):
|
||||
# This external port is never exposed to the tenant.
|
||||
# it is used purely for internal system and admin use when
|
||||
# managing floating IPs.
|
||||
external_port = self.create_port(context.elevated(), {
|
||||
'port':
|
||||
{'tenant_id': '', # tenant intentionally not set
|
||||
'network_id': f_net_id,
|
||||
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
||||
'fixed_ips': attributes.ATTR_NOT_SPECIFIED,
|
||||
'admin_state_up': True,
|
||||
'device_id': fip_id,
|
||||
'device_owner': DEVICE_OWNER_FLOATINGIP,
|
||||
'name': ''}})
|
||||
# Ensure IP addresses are allocated on external port
|
||||
if not external_port['fixed_ips']:
|
||||
msg = _("Unable to find any IP address on external "
|
||||
"network")
|
||||
raise q_exc.BadRequest(resource='floatingip', msg=msg)
|
||||
with context.session.begin(subtransactions=True):
|
||||
# This external port is never exposed to the tenant.
|
||||
# it is used purely for internal system and admin use when
|
||||
# managing floating IPs.
|
||||
external_port = self.create_port(context.elevated(), {
|
||||
'port':
|
||||
{'tenant_id': '', # tenant intentionally not set
|
||||
'network_id': f_net_id,
|
||||
'mac_address': attributes.ATTR_NOT_SPECIFIED,
|
||||
'fixed_ips': attributes.ATTR_NOT_SPECIFIED,
|
||||
'admin_state_up': True,
|
||||
'device_id': fip_id,
|
||||
'device_owner': DEVICE_OWNER_FLOATINGIP,
|
||||
'name': ''}})
|
||||
# Ensure IP addresses are allocated on external port
|
||||
if not external_port['fixed_ips']:
|
||||
raise q_exc.ExternalIpAddressExhausted(net_id=f_net_id)
|
||||
|
||||
floating_fixed_ip = external_port['fixed_ips'][0]
|
||||
floating_ip_address = floating_fixed_ip['ip_address']
|
||||
floatingip_db = FloatingIP(
|
||||
id=fip_id,
|
||||
tenant_id=tenant_id,
|
||||
floating_network_id=fip['floating_network_id'],
|
||||
floating_ip_address=floating_ip_address,
|
||||
floating_port_id=external_port['id'])
|
||||
fip['tenant_id'] = tenant_id
|
||||
# Update association with internal port
|
||||
# and define external IP address
|
||||
self._update_fip_assoc(context, fip,
|
||||
floatingip_db, external_port)
|
||||
context.session.add(floatingip_db)
|
||||
|
||||
floating_fixed_ip = external_port['fixed_ips'][0]
|
||||
floating_ip_address = floating_fixed_ip['ip_address']
|
||||
floatingip_db = FloatingIP(
|
||||
id=fip_id,
|
||||
tenant_id=tenant_id,
|
||||
floating_network_id=fip['floating_network_id'],
|
||||
floating_ip_address=floating_ip_address,
|
||||
floating_port_id=external_port['id'])
|
||||
fip['tenant_id'] = tenant_id
|
||||
# Update association with internal port
|
||||
# and define external IP address
|
||||
self._update_fip_assoc(context, fip,
|
||||
floatingip_db, external_port)
|
||||
context.session.add(floatingip_db)
|
||||
# TODO(salvatore-orlando): Avoid broad catch
|
||||
# Maybe by introducing base class for L3 exceptions
|
||||
except q_exc.BadRequest:
|
||||
LOG.exception(_("Unable to create Floating ip due to a "
|
||||
"malformed request"))
|
||||
raise
|
||||
except Exception:
|
||||
LOG.exception(_("Floating IP association failed"))
|
||||
raise
|
||||
router_id = floatingip_db['router_id']
|
||||
if router_id:
|
||||
routers = self.get_sync_data(context.elevated(), [router_id])
|
||||
|
@ -152,6 +152,10 @@ class RouterDBTestCase(test_l3_plugin.L3NatDBTestCase):
|
||||
# remove extra port created
|
||||
self._delete('ports', p2['port']['id'])
|
||||
|
||||
def test_floatingip_with_invalid_create_port(self):
|
||||
self._test_floatingip_with_invalid_create_port(
|
||||
'quantum.plugins.bigswitch.plugin.QuantumRestProxyV2')
|
||||
|
||||
def test_create_floatingip_no_ext_gateway_return_404(self):
|
||||
with self.subnet(cidr='10.0.10.0/24') as public_sub:
|
||||
self._set_net_external(public_sub['subnet']['network_id'])
|
||||
|
@ -422,6 +422,11 @@ class TestNiciraL3NatTestCase(test_l3_plugin.L3NatDBTestCase,
|
||||
'quantum.plugins.nicira.'
|
||||
'QuantumPlugin.NvpPluginV2')
|
||||
|
||||
def test_floatingip_with_invalid_create_port(self):
|
||||
self._test_floatingip_with_invalid_create_port(
|
||||
'quantum.plugins.nicira.'
|
||||
'QuantumPlugin.NvpPluginV2')
|
||||
|
||||
def _nvp_metadata_setup(self):
|
||||
cfg.CONF.set_override('metadata_mode', 'access_network', 'NVP')
|
||||
|
||||
|
@ -1193,6 +1193,43 @@ class L3NatDBTestCase(L3NatTestCaseBase):
|
||||
public_sub['subnet']['network_id'],
|
||||
port_id=private_port['port']['id'])
|
||||
self.assertEqual(res.status_int, 400)
|
||||
for p in self._list('ports')['ports']:
|
||||
if p['device_owner'] == 'network:floatingip':
|
||||
self.fail('garbage port is not deleted')
|
||||
self._remove_external_gateway_from_router(
|
||||
r['router']['id'],
|
||||
public_sub['subnet']['network_id'])
|
||||
self._router_interface_action('remove',
|
||||
r['router']['id'],
|
||||
private_sub['subnet']['id'],
|
||||
None)
|
||||
|
||||
def test_floatingip_with_assoc_fails(self):
|
||||
self._test_floatingip_with_assoc_fails(
|
||||
'quantum.db.l3_db.L3_NAT_db_mixin')
|
||||
|
||||
def _test_floatingip_with_ip_generation_failure(self, plugin_class):
|
||||
with self.subnet(cidr='200.0.0.1/24') as public_sub:
|
||||
self._set_net_external(public_sub['subnet']['network_id'])
|
||||
with self.port() as private_port:
|
||||
with self.router() as r:
|
||||
sid = private_port['port']['fixed_ips'][0]['subnet_id']
|
||||
private_sub = {'subnet': {'id': sid}}
|
||||
self._add_external_gateway_to_router(
|
||||
r['router']['id'],
|
||||
public_sub['subnet']['network_id'])
|
||||
self._router_interface_action('add', r['router']['id'],
|
||||
private_sub['subnet']['id'],
|
||||
None)
|
||||
method = plugin_class + '._update_fip_assoc'
|
||||
with mock.patch(method) as pl:
|
||||
pl.side_effect = q_exc.IpAddressGenerationFailure(
|
||||
net_id='netid')
|
||||
res = self._create_floatingip(
|
||||
self.fmt,
|
||||
public_sub['subnet']['network_id'],
|
||||
port_id=private_port['port']['id'])
|
||||
self.assertEqual(res.status_int, exc.HTTPConflict.code)
|
||||
|
||||
for p in self._list('ports')['ports']:
|
||||
if p['device_owner'] == 'network:floatingip':
|
||||
@ -1206,10 +1243,6 @@ class L3NatDBTestCase(L3NatTestCaseBase):
|
||||
private_sub['subnet']['id'],
|
||||
None)
|
||||
|
||||
def test_floatingip_with_assoc_fails(self):
|
||||
self._test_floatingip_with_assoc_fails(
|
||||
'quantum.db.l3_db.L3_NAT_db_mixin')
|
||||
|
||||
def test_floatingip_update(self):
|
||||
with self.port() as p:
|
||||
private_sub = {'subnet': {'id':
|
||||
@ -1272,6 +1305,40 @@ class L3NatDBTestCase(L3NatTestCaseBase):
|
||||
found = True
|
||||
self.assertTrue(found)
|
||||
|
||||
def _test_floatingip_with_invalid_create_port(self, plugin_class):
|
||||
with self.port() as p:
|
||||
private_sub = {'subnet': {'id':
|
||||
p['port']['fixed_ips'][0]['subnet_id']}}
|
||||
with self.subnet(cidr='12.0.0.0/24') as public_sub:
|
||||
self._set_net_external(public_sub['subnet']['network_id'])
|
||||
res = self._create_router(self.fmt, _uuid())
|
||||
r = self.deserialize(self.fmt, res)
|
||||
self._add_external_gateway_to_router(
|
||||
r['router']['id'],
|
||||
public_sub['subnet']['network_id'])
|
||||
self._router_interface_action(
|
||||
'add', r['router']['id'],
|
||||
private_sub['subnet']['id'],
|
||||
None)
|
||||
|
||||
with mock.patch(plugin_class + '.create_port') as createport:
|
||||
createport.return_value = {'fixed_ips': []}
|
||||
res = self._create_floatingip(
|
||||
self.fmt, public_sub['subnet']['network_id'],
|
||||
port_id=p['port']['id'])
|
||||
self.assertEqual(res.status_int,
|
||||
exc.HTTPBadRequest.code)
|
||||
self._router_interface_action('remove',
|
||||
r['router']['id'],
|
||||
private_sub
|
||||
['subnet']['id'],
|
||||
None)
|
||||
self._delete('routers', r['router']['id'])
|
||||
|
||||
def test_floatingip_with_invalid_create_port(self):
|
||||
self._test_floatingip_with_invalid_create_port(
|
||||
'quantum.db.db_base_plugin_v2.QuantumDbPluginV2')
|
||||
|
||||
def test_create_floatingip_no_ext_gateway_return_404(self):
|
||||
with self.subnet() as public_sub:
|
||||
self._set_net_external(public_sub['subnet']['network_id'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user