Beispiel #1
0
    def add_subports(self, context, trunk_id, subports):
        """Add one or more subports to trunk."""
        with db_api.autonested_transaction(context.session):
            trunk = self._get_trunk(context, trunk_id)

            # Check for basic validation since the request body here is not
            # automatically validated by the API layer.
            subports = subports['sub_ports']
            subports_validator = rules.SubPortsValidator(
                self._segmentation_types, subports, trunk['port_id'])
            subports = subports_validator.validate(context,
                                                   basic_validation=True)
            added_subports = []

            rules.trunk_can_be_managed(context, trunk)
            original_trunk = copy.deepcopy(trunk)
            # NOTE(status_police): the trunk status should transition to
            # DOWN (and finally in ACTIVE or ERROR), only if it is not in
            # ERROR status already. A user should attempt to resolve the ERROR
            # condition before adding more subports to the trunk. Should a
            # trunk be in DOWN or BUILD state (e.g. when dealing with
            # multiple concurrent requests), the status is still forced to
            # DOWN and thus can potentially overwrite an interleaving state
            # change to ACTIVE. Eventually the driver should bring the status
            # back to ACTIVE or ERROR.
            if trunk.status == constants.ERROR_STATUS:
                raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id)
            else:
                trunk.update(status=constants.DOWN_STATUS)

            for subport in subports:
                obj = trunk_objects.SubPort(
                    context=context,
                    trunk_id=trunk_id,
                    port_id=subport['port_id'],
                    segmentation_type=subport['segmentation_type'],
                    segmentation_id=subport['segmentation_id'])
                obj.create()
                trunk['sub_ports'].append(obj)
                added_subports.append(obj)
            payload = callbacks.TrunkPayload(context,
                                             trunk_id,
                                             current_trunk=trunk,
                                             original_trunk=original_trunk,
                                             subports=added_subports)
            if added_subports:
                registry.notify(resources.SUBPORTS,
                                events.PRECOMMIT_CREATE,
                                self,
                                payload=payload)
        if added_subports:
            registry.notify(resources.SUBPORTS,
                            events.AFTER_CREATE,
                            self,
                            payload=payload)
        return trunk
Beispiel #2
0
 def _unset_trunk(self, trunk):
     _vsdclient = self.plugin_driver.vsdclient
     ctx = n_ctx.get_admin_context()
     try:
         subnet_mapping = db.get_subnet_l2dom_by_port_id(
             ctx.session, trunk.port_id)
         _vsdclient.delete_trunk(trunk, subnet_mapping)
     except Exception as ex:
         LOG.error("Failed to delete trunk: %s", ex)
         trunk.update(status=t_consts.TRUNK_ERROR_STATUS)
         raise t_exc.TrunkInErrorState(trunk_id=trunk.id)
 def remove_subports(self, context, trunk_id, subports):
     """Remove one or more subports from the trunk."""
     LOG.debug("Removing subports %s from trunk %s", subports, trunk_id)
     trunk = self._get_trunk(context, trunk_id)
     original_trunk = copy.deepcopy(trunk)
     subports = subports['sub_ports']
     subports = self.validate_subports(context,
                                       subports,
                                       trunk,
                                       basic_validation=True,
                                       trunk_validation=False)
     removed_subports = []
     rules.trunk_can_be_managed(context, trunk)
     # The trunk should not be in the ERROR_STATUS
     if trunk.status == trunk_const.ERROR_STATUS:
         raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id)
     else:
         # The trunk will transition to DOWN and subsequently to ACTIVE
         # when a subport is removed.
         trunk.update(status=trunk_const.DOWN_STATUS)
     current_subports = {p.port_id: p for p in trunk.sub_ports}
     # Ensure that all sub-ports to be removed are actually present
     for subport in subports:
         if subport['port_id'] not in current_subports:
             raise trunk_exc.SubPortNotFound(trunk_id=trunk_id,
                                             port_id=subport['port_id'])
     with neutron_db_api.context_manager.writer.using(context):
         for subport in subports:
             subport_obj = current_subports.pop(subport['port_id'])
             subport_obj.delete()
             removed_subports.append(subport_obj)
         if removed_subports:
             del trunk.sub_ports[:]
             trunk.sub_ports.extend(current_subports.values())
             payload = callbacks.TrunkPayload(context,
                                              trunk_id,
                                              current_trunk=trunk,
                                              original_trunk=original_trunk,
                                              subports=removed_subports)
             registry.notify(trunk_const.SUBPORTS,
                             events.PRECOMMIT_DELETE,
                             self,
                             payload=payload)
             self.send_subport_update_to_etcd(context, trunk)
     if removed_subports:
         registry.notify(trunk_const.SUBPORTS,
                         events.AFTER_DELETE,
                         self,
                         payload=payload)
     return trunk
Beispiel #4
0
 def add_subports(self, context, trunk_id, subports):
     """Add one or more subports to a trunk."""
     LOG.debug("Adding subports %s to trunk %s", subports, trunk_id)
     trunk = self._get_trunk(context, trunk_id)
     subports = subports['sub_ports']
     subports = self.validate_subports(context,
                                       subports,
                                       trunk,
                                       basic_validation=True)
     added_subports = []
     rules.trunk_can_be_managed(context, trunk)
     original_trunk = copy.deepcopy(trunk)
     # The trunk should not be in the ERROR_STATUS
     if trunk.status == trunk_const.ERROR_STATUS:
         raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id)
     else:
         # The trunk will transition to DOWN and subsequently to ACTIVE
         # when a subport is added.
         trunk.update(status=trunk_const.DOWN_STATUS)
     with db_context_writer.using(context):
         for subport in subports:
             subport_obj = trunk_objects.SubPort(
                 context=context,
                 trunk_id=trunk_id,
                 port_id=subport['port_id'],
                 segmentation_type=subport['segmentation_type'],
                 segmentation_id=subport['segmentation_id'])
             subport_obj.create()
             trunk['sub_ports'].append(subport_obj)
             added_subports.append(subport_obj)
         payload = callbacks.TrunkPayload(context,
                                          trunk_id,
                                          current_trunk=trunk,
                                          original_trunk=original_trunk,
                                          subports=added_subports)
         if added_subports:
             registry.notify(trunk_const.SUBPORTS,
                             events.PRECOMMIT_CREATE,
                             self,
                             payload=payload)
             self.send_subport_update_to_etcd(context, trunk)
     if added_subports:
         registry.notify(trunk_const.SUBPORTS,
                         events.AFTER_CREATE,
                         self,
                         payload=payload)
     return trunk
Beispiel #5
0
    def remove_subports(self, context, trunk_id, subports):
        """Remove one or more subports from the trunk.

        param: subports:
        {u'sub_ports': [{u'port_id': u'fa006724-dbca-4e7f-bb6b-ec70162eb681'}]}
        """
        LOG.debug("Removing subports %s from trunk %s", subports, trunk_id)
        trunk = self._get_trunk(context, trunk_id)
        original_trunk = copy.deepcopy(trunk)
        # key-value data corresponding to original trunk
        original_trunk_data = self._get_trunk_data(trunk)
        # ID's of subports to remove
        subports_to_remove = [pid['port_id'] for pid in subports['sub_ports']]
        LOG.debug('trunk subports to remove: %s', subports_to_remove)
        subports = subports['sub_ports']
        subports = self.validate_subports(context,
                                          subports,
                                          trunk,
                                          basic_validation=True,
                                          trunk_validation=False)
        removed_subports = []
        rules.trunk_can_be_managed(context, trunk)
        # The trunk should not be in the ERROR_STATUS
        if trunk.status == trunk_const.ERROR_STATUS:
            raise trunk_exc.TrunkInErrorState(trunk_id=trunk_id)
        else:
            # The trunk will transition to DOWN and subsequently to ACTIVE
            # when a subport is removed.
            trunk.update(status=trunk_const.DOWN_STATUS)
        current_subports = {p.port_id: p for p in trunk.sub_ports}
        # Ensure that all sub-ports to be removed are actually present
        for subport in subports:
            if subport['port_id'] not in current_subports:
                raise trunk_exc.SubPortNotFound(trunk_id=trunk_id,
                                                port_id=subport['port_id'])
        with db_context_writer.using(context):
            for subport in subports:
                subport_obj = current_subports.pop(subport['port_id'])
                subport_obj.delete()
                removed_subports.append(subport_obj)
            if removed_subports:
                del trunk.sub_ports[:]
                trunk.sub_ports.extend(current_subports.values())
                payload = callbacks.TrunkPayload(context,
                                                 trunk_id,
                                                 current_trunk=trunk,
                                                 original_trunk=original_trunk,
                                                 subports=removed_subports)
                registry.notify(trunk_const.SUBPORTS,
                                events.PRECOMMIT_DELETE,
                                self,
                                payload=payload)
                self.send_subport_update_to_etcd(context, trunk)
                # Subport data to remove
                subports = [
                    subport for subport in original_trunk_data['sub_ports']
                    if subport['port_id'] in subports_to_remove
                ]
                original_trunk_data['sub_ports'] = subports
                trunk_data = self.add_data_to_subports(context,
                                                       original_trunk_data)
                # Remove all remote-group subport keys from etcd
                LOG.debug('trunk data with subports to remove: %s', trunk_data)
                for subport_data in trunk_data['sub_ports']:
                    self._write_remote_group_journal(context,
                                                     subport_data,
                                                     remove_key=True)
        if removed_subports:
            registry.notify(trunk_const.SUBPORTS,
                            events.AFTER_DELETE,
                            self,
                            payload=payload)
        return trunk