Create segment_host mapping after new network
This adds logic to add segment to host mappings for agents after a network with one or more segments is created. The previous logic was doing this only after an agent initially reported after the server started. This meant that any segmented networks created after the agent was running would not get mappings to the agent's host. Change-Id: Ie265500639b1119f0448ed272d235fb709db36f6 Partially-Implements: blueprint routed-networks
This commit is contained in:
parent
4ed9a3e56c
commit
040d740d20
|
@ -16,6 +16,9 @@ import sqlalchemy as sa
|
||||||
from sqlalchemy.orm import exc
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from neutron._i18n import _LI
|
from neutron._i18n import _LI
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
from neutron.callbacks import resources
|
||||||
from neutron.db import model_base
|
from neutron.db import model_base
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -60,9 +63,9 @@ def _make_segment_dict(record):
|
||||||
SEGMENTATION_ID: record.segmentation_id}
|
SEGMENTATION_ID: record.segmentation_id}
|
||||||
|
|
||||||
|
|
||||||
def add_network_segment(session, network_id, segment, segment_index=0,
|
def add_network_segment(context, network_id, segment, segment_index=0,
|
||||||
is_dynamic=False):
|
is_dynamic=False):
|
||||||
with session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
record = NetworkSegment(
|
record = NetworkSegment(
|
||||||
id=uuidutils.generate_uuid(),
|
id=uuidutils.generate_uuid(),
|
||||||
network_id=network_id,
|
network_id=network_id,
|
||||||
|
@ -72,7 +75,12 @@ def add_network_segment(session, network_id, segment, segment_index=0,
|
||||||
segment_index=segment_index,
|
segment_index=segment_index,
|
||||||
is_dynamic=is_dynamic
|
is_dynamic=is_dynamic
|
||||||
)
|
)
|
||||||
session.add(record)
|
context.session.add(record)
|
||||||
|
registry.notify(resources.SEGMENT,
|
||||||
|
events.PRECOMMIT_CREATE,
|
||||||
|
trigger=add_network_segment,
|
||||||
|
context=context,
|
||||||
|
segment=record)
|
||||||
segment['id'] = record.id
|
segment['id'] = record.id
|
||||||
LOG.info(_LI("Added segment %(id)s of type %(network_type)s for network "
|
LOG.info(_LI("Added segment %(id)s of type %(network_type)s for network "
|
||||||
"%(network_id)s"),
|
"%(network_id)s"),
|
||||||
|
|
|
@ -259,7 +259,7 @@ class PortContext(MechanismDriverContext, api.PortContext):
|
||||||
network_id = self._network_context.current['id']
|
network_id = self._network_context.current['id']
|
||||||
|
|
||||||
return self._plugin.type_manager.allocate_dynamic_segment(
|
return self._plugin.type_manager.allocate_dynamic_segment(
|
||||||
self._plugin_context.session, network_id, segment)
|
self._plugin_context, network_id, segment)
|
||||||
|
|
||||||
def release_dynamic_segment(self, segment_id):
|
def release_dynamic_segment(self, segment_id):
|
||||||
return self._plugin.type_manager.release_dynamic_segment(
|
return self._plugin.type_manager.release_dynamic_segment(
|
||||||
|
|
|
@ -182,10 +182,10 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
||||||
LOG.info(_LI("Initializing driver for type '%s'"), network_type)
|
LOG.info(_LI("Initializing driver for type '%s'"), network_type)
|
||||||
driver.obj.initialize()
|
driver.obj.initialize()
|
||||||
|
|
||||||
def _add_network_segment(self, session, network_id, segment, mtu,
|
def _add_network_segment(self, context, network_id, segment, mtu,
|
||||||
segment_index=0):
|
segment_index=0):
|
||||||
segments_db.add_network_segment(
|
segments_db.add_network_segment(
|
||||||
session, network_id, segment, segment_index)
|
context, network_id, segment, segment_index)
|
||||||
if segment.get(api.MTU, 0) > 0:
|
if segment.get(api.MTU, 0) > 0:
|
||||||
mtu.append(segment[api.MTU])
|
mtu.append(segment[api.MTU])
|
||||||
|
|
||||||
|
@ -200,15 +200,15 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
||||||
for segment_index, segment in enumerate(segments):
|
for segment_index, segment in enumerate(segments):
|
||||||
segment = self.reserve_provider_segment(
|
segment = self.reserve_provider_segment(
|
||||||
session, segment)
|
session, segment)
|
||||||
self._add_network_segment(session, network_id, segment,
|
self._add_network_segment(context, network_id, segment,
|
||||||
mtu, segment_index)
|
mtu, segment_index)
|
||||||
elif (cfg.CONF.ml2.external_network_type and
|
elif (cfg.CONF.ml2.external_network_type and
|
||||||
self._get_attribute(network, external_net.EXTERNAL)):
|
self._get_attribute(network, external_net.EXTERNAL)):
|
||||||
segment = self._allocate_ext_net_segment(session)
|
segment = self._allocate_ext_net_segment(session)
|
||||||
self._add_network_segment(session, network_id, segment, mtu)
|
self._add_network_segment(context, network_id, segment, mtu)
|
||||||
else:
|
else:
|
||||||
segment = self._allocate_tenant_net_segment(session)
|
segment = self._allocate_tenant_net_segment(session)
|
||||||
self._add_network_segment(session, network_id, segment, mtu)
|
self._add_network_segment(context, network_id, segment, mtu)
|
||||||
network[api.MTU] = min(mtu) if mtu else 0
|
network[api.MTU] = min(mtu) if mtu else 0
|
||||||
|
|
||||||
def is_partial_segment(self, segment):
|
def is_partial_segment(self, segment):
|
||||||
|
@ -265,18 +265,19 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
||||||
LOG.error(_LE("Failed to release segment '%s' because "
|
LOG.error(_LE("Failed to release segment '%s' because "
|
||||||
"network type is not supported."), segment)
|
"network type is not supported."), segment)
|
||||||
|
|
||||||
def allocate_dynamic_segment(self, session, network_id, segment):
|
def allocate_dynamic_segment(self, context, network_id, segment):
|
||||||
"""Allocate a dynamic segment using a partial or full segment dict."""
|
"""Allocate a dynamic segment using a partial or full segment dict."""
|
||||||
dynamic_segment = segments_db.get_dynamic_segment(
|
dynamic_segment = segments_db.get_dynamic_segment(
|
||||||
session, network_id, segment.get(api.PHYSICAL_NETWORK),
|
context.session, network_id, segment.get(api.PHYSICAL_NETWORK),
|
||||||
segment.get(api.SEGMENTATION_ID))
|
segment.get(api.SEGMENTATION_ID))
|
||||||
|
|
||||||
if dynamic_segment:
|
if dynamic_segment:
|
||||||
return dynamic_segment
|
return dynamic_segment
|
||||||
|
|
||||||
driver = self.drivers.get(segment.get(api.NETWORK_TYPE))
|
driver = self.drivers.get(segment.get(api.NETWORK_TYPE))
|
||||||
dynamic_segment = driver.obj.reserve_provider_segment(session, segment)
|
dynamic_segment = driver.obj.reserve_provider_segment(context.session,
|
||||||
segments_db.add_network_segment(session, network_id, dynamic_segment,
|
segment)
|
||||||
|
segments_db.add_network_segment(context, network_id, dynamic_segment,
|
||||||
is_dynamic=True)
|
is_dynamic=True)
|
||||||
return dynamic_segment
|
return dynamic_segment
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ from oslo_utils import uuidutils
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
from neutron.callbacks import resources
|
||||||
from neutron import context
|
from neutron import context
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
from neutron.db import db_base_plugin_v2
|
from neutron.db import db_base_plugin_v2
|
||||||
|
@ -189,6 +192,22 @@ class TestSegment(SegmentTestCase):
|
||||||
self.assertEqual(2, len(res['segments']))
|
self.assertEqual(2, len(res['segments']))
|
||||||
|
|
||||||
|
|
||||||
|
class TestSegmentML2(SegmentTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSegmentML2, self).setUp(
|
||||||
|
plugin='neutron.plugins.ml2.plugin.Ml2Plugin')
|
||||||
|
|
||||||
|
def test_segment_notification_on_create_network(self):
|
||||||
|
with mock.patch.object(registry, 'notify') as notify:
|
||||||
|
with self.network():
|
||||||
|
pass
|
||||||
|
notify.assert_any_call(resources.SEGMENT,
|
||||||
|
events.PRECOMMIT_CREATE,
|
||||||
|
context=mock.ANY,
|
||||||
|
segment=mock.ANY,
|
||||||
|
trigger=mock.ANY)
|
||||||
|
|
||||||
|
|
||||||
class TestSegmentSubnetAssociation(SegmentTestCase):
|
class TestSegmentSubnetAssociation(SegmentTestCase):
|
||||||
def test_basic_association(self):
|
def test_basic_association(self):
|
||||||
with self.network() as network:
|
with self.network() as network:
|
||||||
|
@ -259,7 +278,7 @@ class TestSegmentSubnetAssociation(SegmentTestCase):
|
||||||
segment = {segments_db.NETWORK_TYPE: 'phys_net',
|
segment = {segments_db.NETWORK_TYPE: 'phys_net',
|
||||||
segments_db.PHYSICAL_NETWORK: 'net_type',
|
segments_db.PHYSICAL_NETWORK: 'net_type',
|
||||||
segments_db.SEGMENTATION_ID: 200}
|
segments_db.SEGMENTATION_ID: 200}
|
||||||
segments_db.add_network_segment(cxt.session,
|
segments_db.add_network_segment(cxt,
|
||||||
network_id=net['id'],
|
network_id=net['id'],
|
||||||
segment=segment,
|
segment=segment,
|
||||||
is_dynamic=True)
|
is_dynamic=True)
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Ml2DBTestCase(testlib_api.SqlTestCase):
|
||||||
self._setup_neutron_network(network_id)
|
self._setup_neutron_network(network_id)
|
||||||
for segment in segments:
|
for segment in segments:
|
||||||
segments_db.add_network_segment(
|
segments_db.add_network_segment(
|
||||||
self.ctx.session, network_id, segment,
|
self.ctx, network_id, segment,
|
||||||
is_dynamic=is_seg_dynamic)
|
is_dynamic=is_seg_dynamic)
|
||||||
|
|
||||||
net_segments = segments_db.get_network_segments(
|
net_segments = segments_db.get_network_segments(
|
||||||
|
|
|
@ -1367,7 +1367,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
||||||
driver_api.PHYSICAL_NETWORK: 'physnet1'}
|
driver_api.PHYSICAL_NETWORK: 'physnet1'}
|
||||||
network_id = network['network']['id']
|
network_id = network['network']['id']
|
||||||
self.driver.type_manager.allocate_dynamic_segment(
|
self.driver.type_manager.allocate_dynamic_segment(
|
||||||
self.context.session, network_id, segment)
|
self.context, network_id, segment)
|
||||||
dynamic_segment = segments_db.get_dynamic_segment(
|
dynamic_segment = segments_db.get_dynamic_segment(
|
||||||
self.context.session, network_id, 'physnet1')
|
self.context.session, network_id, 'physnet1')
|
||||||
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
||||||
|
@ -1378,7 +1378,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
||||||
driver_api.SEGMENTATION_ID: 1234,
|
driver_api.SEGMENTATION_ID: 1234,
|
||||||
driver_api.PHYSICAL_NETWORK: 'physnet3'}
|
driver_api.PHYSICAL_NETWORK: 'physnet3'}
|
||||||
self.driver.type_manager.allocate_dynamic_segment(
|
self.driver.type_manager.allocate_dynamic_segment(
|
||||||
self.context.session, network_id, segment2)
|
self.context, network_id, segment2)
|
||||||
dynamic_segment = segments_db.get_dynamic_segment(
|
dynamic_segment = segments_db.get_dynamic_segment(
|
||||||
self.context.session, network_id, segmentation_id='1234')
|
self.context.session, network_id, segmentation_id='1234')
|
||||||
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
||||||
|
@ -1396,7 +1396,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
||||||
driver_api.PHYSICAL_NETWORK: 'physnet1'}
|
driver_api.PHYSICAL_NETWORK: 'physnet1'}
|
||||||
network_id = network['network']['id']
|
network_id = network['network']['id']
|
||||||
self.driver.type_manager.allocate_dynamic_segment(
|
self.driver.type_manager.allocate_dynamic_segment(
|
||||||
self.context.session, network_id, segment)
|
self.context, network_id, segment)
|
||||||
dynamic_segment = segments_db.get_dynamic_segment(
|
dynamic_segment = segments_db.get_dynamic_segment(
|
||||||
self.context.session, network_id, 'physnet1')
|
self.context.session, network_id, 'physnet1')
|
||||||
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
||||||
|
@ -1411,7 +1411,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
||||||
segment2 = {driver_api.NETWORK_TYPE: 'vlan',
|
segment2 = {driver_api.NETWORK_TYPE: 'vlan',
|
||||||
driver_api.PHYSICAL_NETWORK: 'physnet2'}
|
driver_api.PHYSICAL_NETWORK: 'physnet2'}
|
||||||
self.driver.type_manager.allocate_dynamic_segment(
|
self.driver.type_manager.allocate_dynamic_segment(
|
||||||
self.context.session, network_id, segment2)
|
self.context, network_id, segment2)
|
||||||
dynamic_segment2 = segments_db.get_dynamic_segment(
|
dynamic_segment2 = segments_db.get_dynamic_segment(
|
||||||
self.context.session, network_id, 'physnet2')
|
self.context.session, network_id, 'physnet2')
|
||||||
dynamic_segmentation2_id = dynamic_segment2[driver_api.SEGMENTATION_ID]
|
dynamic_segmentation2_id = dynamic_segment2[driver_api.SEGMENTATION_ID]
|
||||||
|
@ -1427,7 +1427,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
||||||
driver_api.PHYSICAL_NETWORK: 'physnet1'}
|
driver_api.PHYSICAL_NETWORK: 'physnet1'}
|
||||||
network_id = network['network']['id']
|
network_id = network['network']['id']
|
||||||
self.driver.type_manager.allocate_dynamic_segment(
|
self.driver.type_manager.allocate_dynamic_segment(
|
||||||
self.context.session, network_id, segment)
|
self.context, network_id, segment)
|
||||||
dynamic_segment = segments_db.get_dynamic_segment(
|
dynamic_segment = segments_db.get_dynamic_segment(
|
||||||
self.context.session, network_id, 'physnet1')
|
self.context.session, network_id, 'physnet1')
|
||||||
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
||||||
|
@ -1564,7 +1564,7 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
||||||
segment = {driver_api.NETWORK_TYPE: 'vlan',
|
segment = {driver_api.NETWORK_TYPE: 'vlan',
|
||||||
driver_api.PHYSICAL_NETWORK: 'physnet2'}
|
driver_api.PHYSICAL_NETWORK: 'physnet2'}
|
||||||
self.driver.type_manager.allocate_dynamic_segment(
|
self.driver.type_manager.allocate_dynamic_segment(
|
||||||
self.context.session, network_id, segment)
|
self.context, network_id, segment)
|
||||||
dynamic_segment = segments_db.get_dynamic_segment(
|
dynamic_segment = segments_db.get_dynamic_segment(
|
||||||
self.context.session, network_id, 'physnet2')
|
self.context.session, network_id, 'physnet2')
|
||||||
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
self.assertEqual('vlan', dynamic_segment[driver_api.NETWORK_TYPE])
|
||||||
|
|
Loading…
Reference in New Issue