[Urgent] Adapt new enginefacade of Neutron

1. What is the problem
As reported in the bug page, creating external network will
fail with the recent updated Neutron codes.

2. What is the solution for the problem
After debugging, I find that the bug is caused by a recent
Neutron patch[1] that uses new enginefacade for network and
subnet operation. We need to update our central plugin to
adapt the change.

3. What features need to be implemented to the Tricircle to
realize the solution
No new features

[1] b8d4f81b8e
Closes-Bug: #1682315

Change-Id: Ia4e652c74d5ee32c10a907730a1eea5464a5b328
This commit is contained in:
zhiyuan_cai 2017-04-13 16:10:09 +08:00
parent ccd0dec4ca
commit 85c9a896e2
2 changed files with 28 additions and 15 deletions

View File

@ -26,6 +26,7 @@ from neutron.api.v2 import attributes
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.db import api as q_db_api
from neutron.db.availability_zone import router as router_az
from neutron.db import common_db_mixin
from neutron.db import db_base_plugin_v2
@ -289,8 +290,11 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
if az_ext.AZ_HINTS in net_data:
self._validate_availability_zones(context,
net_data[az_ext.AZ_HINTS])
with context.session.begin(subtransactions=True):
res = super(TricirclePlugin, self).create_network(context, network)
with q_db_api.context_manager.writer.using(context):
net_db = self.create_network_db(context, network)
res = self._make_network_dict(net_db, process_extensions=False,
context=context)
self._process_l3_create(context, res, net_data)
net_data['id'] = res['id']
self.type_manager.create_network_segments(context, net_data,
tenant_id)
@ -298,11 +302,8 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
if az_ext.AZ_HINTS in net_data:
az_hints = az_ext.convert_az_list_to_string(
net_data[az_ext.AZ_HINTS])
update_res = super(TricirclePlugin, self).update_network(
context, res['id'],
{'network': {az_ext.AZ_HINTS: az_hints}})
res[az_ext.AZ_HINTS] = update_res[az_ext.AZ_HINTS]
self._process_l3_create(context, res, net_data)
net_db[az_ext.AZ_HINTS] = az_hints
res[az_ext.AZ_HINTS] = net_data[az_ext.AZ_HINTS]
# put inside a session so when bottom operations fails db can
# rollback
if is_external:

View File

@ -1133,6 +1133,21 @@ class FakePlugin(plugin.TricirclePlugin):
def _get_client(self, region_name):
return FakeClient(region_name)
def create_network(self, context, network):
# neutron has been updated to use the new enginefacade, we no longer
# call update_network in TricirclePlugin.create_network to update AZ
# info. new context manager will update AZ info after context exits,
# but since we don't simulate such process, we override this method to
# insert AZ info
net = super(FakePlugin, self).create_network(context, network)
if 'availability_zone_hints' not in network['network']:
return net
for _net in TOP_NETS:
if _net['id'] == net['id']:
_net['availability_zone_hints'] = jsonutils.dumps(
network['network']['availability_zone_hints'])
return net
def _make_network_dict(self, network, fields=None,
process_extensions=True, context=None):
network = _transform_az(network)
@ -1449,9 +1464,8 @@ class PluginTest(unittest.TestCase,
mock_client_method.assert_has_calls(client_calls)
@patch.object(context, 'get_context_from_neutron_context')
@patch.object(db_base_plugin_v2.NeutronDbPluginV2, 'update_network')
@patch.object(db_base_plugin_v2.NeutronDbPluginV2, 'create_network')
def test_network_az_region(self, mock_create, mock_update, mock_context):
def test_network_az_region(self, mock_create, mock_context):
self._basic_pod_route_setup()
fake_plugin = FakePlugin()
@ -1461,14 +1475,12 @@ class PluginTest(unittest.TestCase,
network = {'network': {
'id': 'net_id', 'name': 'net_az', 'tenant_id': TEST_TENANT_ID,
'admin_state_up': True, 'shared': False,
'availability_zone_hints': ['az_name_1', 'pod_2']}}
mock_create.return_value = {'id': 'net_id', 'name': 'net_az'}
mock_update.return_value = network['network']
fake_plugin.create_network(neutron_context, network)
mock_update.assert_called_once_with(
neutron_context, 'net_id',
{'network': {
'availability_zone_hints': '["az_name_1", "pod_2"]'}})
ret_net = fake_plugin.create_network(neutron_context, network)
self.assertEqual(['az_name_1', 'pod_2'],
ret_net['availability_zone_hints'])
err_network = {'network': {
'id': 'net_id', 'name': 'net_az', 'tenant_id': TEST_TENANT_ID,