def test_detect_nested_port(self): with self.network() as n,\ self.subnet(network=n) as s,\ self.port(subnet=s) as p1,\ self.port(subnet=s) as p2: p1 = p1['port'] p2 = p2['port'] p2_ip = p2['fixed_ips'][0]['ip_address'] aap = {"ip_address": p2_ip} if self.segmentation_type == trunk_models.TYPE_MACVLAN: aap['mac_address'] = p2['mac_address'] data = {'port': {'allowed_address_pairs': [aap]}} self.nb_api.create.reset_mock() req = self.new_update_request('ports', data, p1['id']) req.get_response(self.api) cps_id = trunk_models.get_child_port_segmentation_id( p1['id'], p2['id']) model = trunk_models.ChildPortSegmentation( id=cps_id, topic=p1['project_id'], parent=p1['id'], port=p2['id'], segmentation_type=self.segmentation_type, ) self.nb_api.create.assert_called_once_with(model)
def _create_segmentation(self): return trunk.ChildPortSegmentation(id='cps1', topic='fake_tenant1', parent='fake_port2', port='lport2', segmentation_type='vlan', segmentation_id=7)
def _delete_subport(self, trunk, subport, df_parent): """ Remove the subport that were deleted on the Neutron side from the Dragonflow NB DB """ id_ = self._get_subport_id(trunk, subport) model = trunk_models.ChildPortSegmentation(id=id_, topic=trunk.project_id) self.nb_api.delete(model)
def _get_trunk_subport_ofport(self, lport): try: cps = self.db_store.get_one( trunk.ChildPortSegmentation(port=lport.id), trunk.ChildPortSegmentation.get_index('lport_id')) if cps: return cps.parent.ofport except Exception: # Not found. Do nothing pass
def _add_subport(self, trunk, subport, df_parent): """ Create the subport that were created on the Neutron side in the Dragonflow NB DB """ model = trunk_models.ChildPortSegmentation( id=self._get_subport_id(trunk, subport), topic=trunk.project_id, parent=trunk.port_id, port=subport.port_id, segmentation_type=subport.segmentation_type, segmentation_id=subport.segmentation_id, ) self.nb_api.create(model)
def _get_all_cps_by_parent(self, lport): return self.db_store.get_all( trunk.ChildPortSegmentation(parent=lport.id), index=trunk.ChildPortSegmentation.get_index('parent_id'), )
def _detect_port_behind_port(self, a_context, updated_port, orig_port=None): """ A heuristic to detect nested ports (i.e. ports behind ports). For each allowed-address-pair modification, scan to see if there are ports with those IPs/MACs. If so, these are nested ports. Create the relevant NB objects, and update their status in Neutron. """ # TODO(oanson) We assume that the AAP is removed before the port updated_port_aaps = updated_port.get(aap.ADDRESS_PAIRS, []) orig_port_aaps = ([] if not orig_port else orig_port.get( aap.ADDRESS_PAIRS, [])) new_aaps = [ aap_ for aap_ in updated_port_aaps if aap_ not in orig_port_aaps ] removed_aaps = [ aap_ for aap_ in orig_port_aaps if aap_ not in updated_port_aaps ] remaining_aaps = [ aap_ for aap_ in updated_port_aaps if aap_ not in new_aaps ] core_plugin = directory.get_plugin() new_status = trunk_driver.get_child_port_status(updated_port) LOG.debug( '_detect_port_behind_port: id: %s ' 'updated_port_aaps: %s orig_port_aaps: %s', updated_port['id'], updated_port_aaps, orig_port_aaps) for pair in new_aaps: nested_port, segmentation_type = self._find_nested_port_and_type( a_context, pair, updated_port) if not nested_port: LOG.debug( '_detect_port_behind_port (new): ' 'Could not find port with ip pair %s', pair) continue cps_id = trunk_models.get_child_port_segmentation_id( updated_port['id'], nested_port['id']) model = trunk_models.ChildPortSegmentation( id=cps_id, topic=updated_port['project_id'], parent=updated_port['id'], port=nested_port['id'], segmentation_type=segmentation_type, ) self.nb_api.create(model) core_plugin.update_port_status(context.get_admin_context(), nested_port['id'], new_status) for pair in removed_aaps: nested_port, _segmentation_type = self._find_nested_port_and_type( a_context, pair, updated_port) if not nested_port: LOG.debug( '_detect_port_behind_port (removed): ' 'Could not find port with ip pair %s', pair) continue cps_id = trunk_models.get_child_port_segmentation_id( updated_port['id'], nested_port['id']) model = trunk_models.ChildPortSegmentation( id=cps_id, topic=updated_port['project_id'], ) self.nb_api.delete(model) core_plugin.update_port_status(context.get_admin_context(), nested_port['id'], n_constants.PORT_STATUS_DOWN) if not orig_port or updated_port['status'] == orig_port['status']: return # No status change for pair in remaining_aaps: nested_port, _segmentation_type = self._find_nested_port_and_type( a_context, pair, updated_port) if not nested_port: LOG.debug( '_detect_port_behind_port (removed): ' 'Could not find port with ip pair %s', pair) continue # We assume the CPS instance exists. core_plugin.update_port_status(context.get_admin_context(), nested_port['id'], new_status)