Merge "BigSwitch: Fixes floating IP backend updates"
This commit is contained in:
commit
dd3141f2bc
@ -1032,12 +1032,9 @@ class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
new_fl_ip = super(NeutronRestProxyV2,
|
||||
self).create_floatingip(context, floatingip)
|
||||
|
||||
net_id = new_fl_ip['floating_network_id']
|
||||
orig_net = super(NeutronRestProxyV2, self).get_network(context,
|
||||
net_id)
|
||||
# create floatingip on the network controller
|
||||
try:
|
||||
self._send_update_network(orig_net, context)
|
||||
self._send_floatingip_update(context)
|
||||
except RemoteRestError as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(
|
||||
@ -1054,32 +1051,27 @@ class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
new_fl_ip = super(NeutronRestProxyV2,
|
||||
self).update_floatingip(context, id, floatingip)
|
||||
|
||||
net_id = new_fl_ip['floating_network_id']
|
||||
orig_net = super(NeutronRestProxyV2, self).get_network(context,
|
||||
net_id)
|
||||
# update network on network controller
|
||||
self._send_update_network(orig_net, context)
|
||||
self._send_floatingip_update(context)
|
||||
return new_fl_ip
|
||||
|
||||
def delete_floatingip(self, context, id):
|
||||
LOG.debug(_("NeutronRestProxyV2: delete_floatingip() called"))
|
||||
|
||||
orig_fl_ip = super(NeutronRestProxyV2, self).get_floatingip(context,
|
||||
id)
|
||||
with context.session.begin(subtransactions=True):
|
||||
# delete floating IP in DB
|
||||
net_id = orig_fl_ip['floating_network_id']
|
||||
super(NeutronRestProxyV2, self).delete_floatingip(context, id)
|
||||
|
||||
orig_net = super(NeutronRestProxyV2, self).get_network(context,
|
||||
net_id)
|
||||
# update network on network controller
|
||||
self._send_update_network(orig_net, context)
|
||||
self._send_floatingip_update(context)
|
||||
|
||||
def disassociate_floatingips(self, context, port_id):
|
||||
LOG.debug(_("NeutronRestProxyV2: diassociate_floatingips() called"))
|
||||
super(NeutronRestProxyV2, self).disassociate_floatingips(context,
|
||||
port_id)
|
||||
self._send_floatingip_update(context)
|
||||
|
||||
def _send_floatingip_update(self, context):
|
||||
try:
|
||||
ext_net_id = self.get_external_network_id(context)
|
||||
if ext_net_id:
|
||||
|
@ -17,6 +17,12 @@
|
||||
# @author: Kevin Benton, <kevin.benton@bigswitch.com>
|
||||
#
|
||||
|
||||
import json
|
||||
|
||||
from neutron.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HTTPResponseMock():
|
||||
status = 200
|
||||
@ -50,7 +56,7 @@ class HTTPResponseMock500(HTTPResponseMock):
|
||||
return "{'status': '%s'}" % self.errmsg
|
||||
|
||||
|
||||
class HTTPConnectionMock():
|
||||
class HTTPConnectionMock(object):
|
||||
|
||||
def __init__(self, server, port, timeout):
|
||||
self.response = None
|
||||
@ -62,6 +68,10 @@ class HTTPConnectionMock():
|
||||
self.response = HTTPResponseMock500(None, errmsg=errmsg)
|
||||
|
||||
def request(self, action, uri, body, headers):
|
||||
LOG.debug(_("Request: action=%(action)s, uri=%(uri)r, "
|
||||
"body=%(body)s, headers=%(headers)s"),
|
||||
{'action': action, 'uri': uri,
|
||||
'body': body, 'headers': headers})
|
||||
if self.broken and "ExceptOnBadServer" in uri:
|
||||
raise Exception("Broken server got an unexpected request")
|
||||
if self.response:
|
||||
@ -94,3 +104,27 @@ class HTTPConnectionMock500(HTTPConnectionMock):
|
||||
def __init__(self, server, port, timeout):
|
||||
self.response = HTTPResponseMock500(None)
|
||||
self.broken = True
|
||||
|
||||
|
||||
class VerifyMultiTenantFloatingIP(HTTPConnectionMock):
|
||||
|
||||
def request(self, action, uri, body, headers):
|
||||
# Only handle network update requests
|
||||
if 'network' in uri and 'tenant' in uri and 'ports' not in uri:
|
||||
req = json.loads(body)
|
||||
if 'network' not in req or 'floatingips' not in req['network']:
|
||||
msg = _("No floating IPs in request"
|
||||
"uri=%(uri)s, body=%(body)s") % {'uri': uri,
|
||||
'body': body}
|
||||
raise Exception(msg)
|
||||
distinct_tenants = []
|
||||
for flip in req['network']['floatingips']:
|
||||
if flip['tenant_id'] not in distinct_tenants:
|
||||
distinct_tenants.append(flip['tenant_id'])
|
||||
if len(distinct_tenants) < 2:
|
||||
msg = _("Expected floating IPs from multiple tenants."
|
||||
"uri=%(uri)s, body=%(body)s") % {'uri': uri,
|
||||
'body': body}
|
||||
raise Exception(msg)
|
||||
super(VerifyMultiTenantFloatingIP,
|
||||
self).request(action, uri, body, headers)
|
||||
|
@ -18,6 +18,7 @@
|
||||
# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com
|
||||
#
|
||||
|
||||
import contextlib
|
||||
import copy
|
||||
import os
|
||||
|
||||
@ -31,6 +32,7 @@ from neutron.extensions import l3
|
||||
from neutron.manager import NeutronManager
|
||||
from neutron.openstack.common.notifier import api as notifier_api
|
||||
from neutron.openstack.common.notifier import test_notifier
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.bigswitch.extensions import routerrule
|
||||
from neutron.tests.unit.bigswitch import fake_server
|
||||
from neutron.tests.unit.bigswitch import test_base
|
||||
@ -39,6 +41,9 @@ from neutron.tests.unit import test_extension_extradhcpopts as test_extradhcp
|
||||
from neutron.tests.unit import test_l3_plugin
|
||||
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
|
||||
def new_L3_setUp(self):
|
||||
test_config['plugin_name_v2'] = (
|
||||
'neutron.plugins.bigswitch.plugin.NeutronRestProxyV2')
|
||||
@ -141,6 +146,70 @@ class RouterDBTestCase(test_base.BigSwitchTestBase,
|
||||
# remove extra port created
|
||||
self._delete('ports', p2['port']['id'])
|
||||
|
||||
def test_multi_tenant_flip_alllocation(self):
|
||||
tenant1_id = _uuid()
|
||||
tenant2_id = _uuid()
|
||||
with contextlib.nested(
|
||||
self.network(tenant_id=tenant1_id),
|
||||
self.network(tenant_id=tenant2_id)) as (n1, n2):
|
||||
with contextlib.nested(
|
||||
self.subnet(network=n1, cidr='11.0.0.0/24'),
|
||||
self.subnet(network=n2, cidr='12.0.0.0/24'),
|
||||
self.subnet(cidr='13.0.0.0/24')) as (s1, s2, psub):
|
||||
with contextlib.nested(
|
||||
self.router(tenant_id=tenant1_id),
|
||||
self.router(tenant_id=tenant2_id),
|
||||
self.port(subnet=s1, tenant_id=tenant1_id),
|
||||
self.port(subnet=s2, tenant_id=tenant2_id)) as (r1, r2,
|
||||
p1, p2):
|
||||
self._set_net_external(psub['subnet']['network_id'])
|
||||
s1id = p1['port']['fixed_ips'][0]['subnet_id']
|
||||
s2id = p2['port']['fixed_ips'][0]['subnet_id']
|
||||
s1 = {'subnet': {'id': s1id}}
|
||||
s2 = {'subnet': {'id': s2id}}
|
||||
self._add_external_gateway_to_router(
|
||||
r1['router']['id'],
|
||||
psub['subnet']['network_id'])
|
||||
self._add_external_gateway_to_router(
|
||||
r2['router']['id'],
|
||||
psub['subnet']['network_id'])
|
||||
self._router_interface_action(
|
||||
'add', r1['router']['id'],
|
||||
s1['subnet']['id'], None)
|
||||
self._router_interface_action(
|
||||
'add', r2['router']['id'],
|
||||
s2['subnet']['id'], None)
|
||||
fl1 = self._make_floatingip_for_tenant_port(
|
||||
net_id=psub['subnet']['network_id'],
|
||||
port_id=p1['port']['id'],
|
||||
tenant_id=tenant1_id)
|
||||
multiFloatPatch = patch(
|
||||
'httplib.HTTPConnection',
|
||||
create=True,
|
||||
new=fake_server.VerifyMultiTenantFloatingIP)
|
||||
multiFloatPatch.start()
|
||||
fl2 = self._make_floatingip_for_tenant_port(
|
||||
net_id=psub['subnet']['network_id'],
|
||||
port_id=p2['port']['id'],
|
||||
tenant_id=tenant2_id)
|
||||
multiFloatPatch.stop()
|
||||
self._delete('floatingips', fl1['floatingip']['id'])
|
||||
self._delete('floatingips', fl2['floatingip']['id'])
|
||||
self._router_interface_action(
|
||||
'remove', r1['router']['id'],
|
||||
s1['subnet']['id'], None)
|
||||
self._router_interface_action(
|
||||
'remove', r2['router']['id'],
|
||||
s2['subnet']['id'], None)
|
||||
|
||||
def _make_floatingip_for_tenant_port(self, net_id, port_id, tenant_id):
|
||||
data = {'floatingip': {'floating_network_id': net_id,
|
||||
'tenant_id': tenant_id,
|
||||
'port_id': port_id}}
|
||||
floatingip_req = self.new_create_request('floatingips', data, self.fmt)
|
||||
res = floatingip_req.get_response(self.ext_api)
|
||||
return self.deserialize(self.fmt, res)
|
||||
|
||||
def test_floatingip_with_invalid_create_port(self):
|
||||
self._test_floatingip_with_invalid_create_port(
|
||||
'neutron.plugins.bigswitch.plugin.NeutronRestProxyV2')
|
||||
|
Loading…
Reference in New Issue
Block a user