diff --git a/neutron/callbacks/resources.py b/neutron/callbacks/resources.py index 410809dc9c7..028cc715376 100644 --- a/neutron/callbacks/resources.py +++ b/neutron/callbacks/resources.py @@ -24,6 +24,7 @@ ROUTER_GATEWAY = 'router_gateway' ROUTER_INTERFACE = 'router_interface' SECURITY_GROUP = 'security_group' SECURITY_GROUP_RULE = 'security_group_rule' +SEGMENT = 'segment' SUBNET = 'subnet' SUBNETS = 'subnets' SUBNET_GATEWAY = 'subnet_gateway' diff --git a/neutron/services/segments/db.py b/neutron/services/segments/db.py index a6dae924487..2ac39e1eb7d 100644 --- a/neutron/services/segments/db.py +++ b/neutron/services/segments/db.py @@ -33,6 +33,7 @@ from neutron.db import common_db_mixin from neutron.db import model_base from neutron.db import segments_db as db from neutron.extensions import segment as extension +from neutron import manager from neutron.services.segments import exceptions @@ -110,6 +111,8 @@ class SegmentDbMixin(common_db_mixin.CommonDbMixin): db.SEGMENTATION_ID: segmentation_id} new_segment = db.NetworkSegment(**args) context.session.add(new_segment) + registry.notify(resources.SEGMENT, events.PRECOMMIT_CREATE, self, + context=context, segment=new_segment) return self._make_segment_dict(new_segment) @@ -221,6 +224,24 @@ def _update_segment_host_mapping_for_agent(resource, event, trigger, update_segment_host_mapping(context, host, current_segment_ids) +def _add_segment_host_mapping_for_segment(resource, event, trigger, + context, segment): + if not segment.physical_network: + return + cp = manager.NeutronManager.get_plugin() + check_segment_for_agent = getattr(cp, 'check_segment_for_agent', None) + if not hasattr(cp, 'get_agents') or not check_segment_for_agent: + # not an agent-supporting plugin + registry.unsubscribe(_add_segment_host_mapping_for_segment, + resources.SEGMENT, events.PRECOMMIT_CREATE) + return + hosts = {agent['host'] for agent in cp.get_agents(context) + if check_segment_for_agent(segment, agent)} + for host in hosts: + context.session.add(SegmentHostMapping(segment_id=segment.id, + host=host)) + + def subscribe(): registry.subscribe(_update_segment_host_mapping_for_agent, resources.AGENT, @@ -228,5 +249,7 @@ def subscribe(): registry.subscribe(_update_segment_host_mapping_for_agent, resources.AGENT, events.AFTER_UPDATE) + registry.subscribe(_add_segment_host_mapping_for_segment, + resources.SEGMENT, events.PRECOMMIT_CREATE) subscribe() diff --git a/neutron/tests/unit/extensions/test_segment.py b/neutron/tests/unit/extensions/test_segment.py index a150a89cb1f..113e673d7b9 100644 --- a/neutron/tests/unit/extensions/test_segment.py +++ b/neutron/tests/unit/extensions/test_segment.py @@ -392,6 +392,19 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase): segments_host_db[segment['id']]['segment_id']) self.assertEqual(host2, segments_host_db[segment['id']]['host']) + def test_new_segment_after_host_reg(self): + host1 = 'host1' + physical_network = 'phys_net1' + segment = self._test_one_segment_one_host(host1) + with self.network() as network: + network = network['network'] + segment2 = self._test_create_segment( + network_id=network['id'], physical_network=physical_network, + segmentation_id=200, network_type=p_constants.TYPE_VLAN)['segment'] + segments_host_db = self._get_segments_for_host(host1) + self.assertEqual(set((segment['id'], segment2['id'])), + set(segments_host_db)) + def test_segment_deletion_removes_host_mapping(self): host = 'host1' segment = self._test_one_segment_one_host(host)