# 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"
- # remove the external port
- self.delete_port(context.elevated(), external_port['id'],
- l3_port_check=False)
- raise q_exc.BadRequest(resource='floatingip', msg=msg)
-
- floating_ip_address = external_port['fixed_ips'][0]['ip_address']
try:
with context.session.begin(subtransactions=True):
+ 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"
+ # remove the external port
+ raise q_exc.BadRequest(resource='floatingip', msg=msg)
+
+ 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,
except Exception:
LOG.exception("Floating IP association failed")
# Remove the port created for internal purposes
- self.delete_port(context.elevated(), external_port['id'],
- l3_port_check=False)
raise
return self._make_floatingip_dict(floatingip_db)
from quantum.api.v2 import attributes
from quantum.common import config
+from quantum.common import exceptions as q_exc
from quantum.common.test_lib import test_config
from quantum.common import utils
from quantum import context
self._show('floatingips', fip['floatingip']['id'],
expected_code=exc.HTTPNotFound.code)
+ def test_floatingip_with_assoc_fails(self):
+ fmt = 'json'
+ with self.subnet() 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)
+ PLUGIN_CLASS = 'quantum.db.l3_db.L3_NAT_db_mixin'
+ METHOD = PLUGIN_CLASS + '._update_fip_assoc'
+ with mock.patch(METHOD) as pl:
+ pl.side_effect = q_exc.BadRequest(
+ resource='floatingip',
+ msg='fake_error')
+ res = self._create_floatingip(
+ fmt,
+ 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_update(self):
with self.port() as p:
private_sub = {'subnet': {'id':