Ejemplo n.º 1
0
    def remove_subports(self, context, trunk_id, subports):
        """Remove one or more subports from trunk."""
        subports = subports['sub_ports']
        with db_api.CONTEXT_WRITER.using(context):
            trunk = self._get_trunk(context, trunk_id)
            original_trunk = copy.deepcopy(trunk)
            rules.trunk_can_be_managed(context, trunk)

            subports_validator = rules.SubPortsValidator(
                self._segmentation_types, subports)
            # the subports are being removed, therefore we do not need to
            # enforce any specific trunk rules, other than basic validation
            # of the request body.
            subports = subports_validator.validate(
                context, basic_validation=True,
                trunk_validation=False)

            current_subports = {p.port_id: p for p in trunk.sub_ports}
            removed_subports = []

            for subport in subports:
                subport_obj = current_subports.pop(subport['port_id'], None)

                if not subport_obj:
                    raise trunk_exc.SubPortNotFound(trunk_id=trunk_id,
                                                    port_id=subport['port_id'])
                subport_obj.delete()
                removed_subports.append(subport_obj)

            del trunk.sub_ports[:]
            trunk.sub_ports.extend(current_subports.values())
            # NOTE(status_police): the trunk status should transition to
            # DOWN irrespective of the status in which it is in to allow
            # the user to resolve potential conflicts due to prior add_subports
            # operations.
            # Should a trunk be in DOWN or BUILD state (e.g. when dealing
            # with multiple concurrent requests), the status is still forced
            # to DOWN. See add_subports() for more details.
            trunk.update(status=constants.TRUNK_DOWN_STATUS)
            payload = events.DBEventPayload(context, resource_id=trunk_id,
                                            states=(original_trunk, trunk,),
                                            metadata={
                                                'subports': removed_subports
                                            })
            if removed_subports:
                registry.publish(resources.SUBPORTS, events.PRECOMMIT_DELETE,
                                 self, payload=payload)
        if removed_subports:
            payload = events.DBEventPayload(context, resource_id=trunk_id,
                                            states=(original_trunk, trunk,),
                                            metadata={
                                                'subports': removed_subports
                                            })
            registry.publish(
                resources.SUBPORTS, events.AFTER_DELETE, self, payload=payload)
        return trunk
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    def remove_subports(self, context, trunk_id, subports):
        """Remove one or more subports from trunk."""
        subports = subports['sub_ports']
        with db_api.autonested_transaction(context.session):
            trunk = self._get_trunk(context, trunk_id)
            original_trunk = copy.deepcopy(trunk)
            rules.trunk_can_be_managed(context, trunk)

            subports_validator = rules.SubPortsValidator(
                self._segmentation_types, subports)
            # the subports are being removed, therefore we do not need to
            # enforce any specific trunk rules, other than basic validation
            # of the request body.
            subports = subports_validator.validate(context,
                                                   basic_validation=True,
                                                   trunk_validation=False)

            current_subports = {p.port_id: p for p in trunk.sub_ports}
            removed_subports = []

            for subport in subports:
                subport_obj = current_subports.pop(subport['port_id'], None)

                if not subport_obj:
                    raise trunk_exc.SubPortNotFound(trunk_id=trunk_id,
                                                    port_id=subport['port_id'])
                subport_obj.delete()
                removed_subports.append(subport_obj)

            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)
            if removed_subports:
                registry.notify(constants.SUBPORTS,
                                events.PRECOMMIT_DELETE,
                                self,
                                payload=payload)
        if removed_subports:
            registry.notify(constants.SUBPORTS,
                            events.AFTER_DELETE,
                            self,
                            payload=payload)
        return trunk
Ejemplo n.º 4
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