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)
Beispiel #2
0
 def _create_segmentation(self):
     return trunk.ChildPortSegmentation(id='cps1',
                                        topic='fake_tenant1',
                                        parent='fake_port2',
                                        port='lport2',
                                        segmentation_type='vlan',
                                        segmentation_id=7)
Beispiel #3
0
 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
Beispiel #5
0
 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)
Beispiel #6
0
 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'),
     )
Beispiel #7
0
    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)