From 4ed9a3e56c33f2ef4fa140953b34e0863d296bbd Mon Sep 17 00:00:00 2001 From: "Mr. Bojangles" Date: Tue, 14 Jun 2016 02:04:27 -0600 Subject: [PATCH] Create segment_host mapping after new segment This adds logic to add segment to host mappings for agents after a segment is created. The previous logic was doing this only after an agent initially reported after the server started. This meant that any segments created after the agent was running would not get mappings to the agent's host. Partially-Implements: blueprint routed-networks Change-Id: Ibcd9964afb1c7ac3926447f90b3fd364fd4835ca --- neutron/callbacks/resources.py | 1 + neutron/services/segments/db.py | 23 +++++++++++++++++++ neutron/tests/unit/extensions/test_segment.py | 13 +++++++++++ 3 files changed, 37 insertions(+) diff --git a/neutron/callbacks/resources.py b/neutron/callbacks/resources.py index 753d7a51151..9a349b29760 100644 --- a/neutron/callbacks/resources.py +++ b/neutron/callbacks/resources.py @@ -21,6 +21,7 @@ ROUTER_GATEWAY = 'router_gateway' ROUTER_INTERFACE = 'router_interface' SECURITY_GROUP = 'security_group' SECURITY_GROUP_RULE = 'security_group_rule' +SEGMENT = 'segment' SUBNET = 'subnet' SUBNET_GATEWAY = 'subnet_gateway' SUBNETPOOL_ADDRESS_SCOPE = 'subnetpool_address_scope' diff --git a/neutron/services/segments/db.py b/neutron/services/segments/db.py index 84a65ffc5f3..0a1f70eeabb 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 @@ -108,6 +109,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) @@ -219,6 +222,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, @@ -226,5 +247,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 42269c698a7..6d2994b3ca2 100644 --- a/neutron/tests/unit/extensions/test_segment.py +++ b/neutron/tests/unit/extensions/test_segment.py @@ -389,6 +389,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)