Exemplo n.º 1
0
    def remove_subports(self, context, trunk_id, subports):
        """Remove one or more subports from trunk."""
        with db_api.autonested_transaction(context.session):
            trunk = self._get_trunk(context, trunk_id)
            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)

            trunk.sub_ports = list(current_subports.values())
            registry.notify(
                constants.SUBPORTS, events.AFTER_DELETE, self,
                removed_subports=removed_subports)
            return trunk
Exemplo n.º 2
0
 def delete_trunk(self, context, trunk_id):
     """Delete the trunk port."""
     LOG.debug("Deleting trunk_id %s", trunk_id)
     deleted_from_db = False
     with db_context_writer.using(context):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if not trunk_port_validator.is_bound(context):
             trunk.delete()
             deleted_from_db = True
             payload = callbacks.TrunkPayload(context,
                                              trunk_id,
                                              original_trunk=trunk)
             registry.notify(trunk_const.TRUNK,
                             events.PRECOMMIT_DELETE,
                             self,
                             payload=payload)
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     if deleted_from_db:
         registry.notify(trunk_const.TRUNK,
                         events.AFTER_DELETE,
                         self,
                         payload=payload)
Exemplo n.º 3
0
 def delete_trunk(self, context, trunk_id):
     """Delete the specified trunk."""
     with db_api.CONTEXT_WRITER.using(context):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if trunk_port_validator.can_be_trunked_or_untrunked(context):
             # NOTE(status_police): when a trunk is deleted, the logical
             # object disappears from the datastore, therefore there is no
             # status transition involved. If PRECOMMIT failures occur,
             # the trunk remains in the status where it was.
             try:
                 trunk.delete()
             except Exception as e:
                 with excutils.save_and_reraise_exception():
                     LOG.warning('Trunk driver raised exception when '
                                 'deleting trunk port %s: %s', trunk_id,
                                 str(e))
             payload = events.DBEventPayload(context, resource_id=trunk_id,
                                             states=(trunk,))
             registry.publish(resources.TRUNK, events.PRECOMMIT_DELETE,
                              self, payload=payload)
         else:
             LOG.info('Trunk driver does not consider trunk %s '
                      'untrunkable', trunk_id)
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     registry.publish(resources.TRUNK, events.AFTER_DELETE, self,
                      payload=events.DBEventPayload(
                          context, resource_id=trunk_id,
                          states=(trunk,)))
Exemplo n.º 4
0
 def delete_trunk(self, context, trunk_id):
     """Delete the specified trunk."""
     with db_api.autonested_transaction(context.session):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if trunk_port_validator.can_be_trunked_or_untrunked(context):
             # NOTE(status_police): when a trunk is deleted, the logical
             # object disappears from the datastore, therefore there is no
             # status transition involved. If PRECOMMIT failures occur,
             # the trunk remains in the status where it was.
             trunk.delete()
             payload = callbacks.TrunkPayload(context,
                                              trunk_id,
                                              original_trunk=trunk)
             registry.notify(resources.TRUNK,
                             events.PRECOMMIT_DELETE,
                             self,
                             payload=payload)
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     registry.notify(resources.TRUNK,
                     events.AFTER_DELETE,
                     self,
                     payload=payload)
Exemplo n.º 5
0
    def add_subports(self, context, trunk_id, subports):
        """Add one or more subports to trunk."""
        # Check for basic validation since the request body here is not
        # automatically validated by the API layer.
        subports_validator = rules.SubPortsValidator(
            self._segmentation_types, subports)
        subports = subports_validator.validate(context, basic_validation=True)
        added_subports = []

        with db_api.autonested_transaction(context.session):
            trunk = self._get_trunk(context, trunk_id)
            rules.trunk_can_be_managed(context, trunk)
            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)

        registry.notify(
            constants.SUBPORTS, events.AFTER_CREATE, self,
            added_subports=added_subports)
        return trunk
Exemplo n.º 6
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
Exemplo n.º 7
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
Exemplo n.º 8
0
 def delete_trunk(self, context, trunk_id):
     """Delete the specified trunk."""
     with db_api.autonested_transaction(context.session):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if not trunk_port_validator.is_bound(context):
             trunk.delete()
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
Exemplo n.º 9
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())
            # NOTE(status_police): the trunk status should transition to
            # PENDING 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 PENDING or BUILD state (e.g. when dealing
            # with multiple concurrent requests), the status is still forced
            # to PENDING. See add_subports() for more details.
            trunk.status = constants.PENDING_STATUS
            trunk.update()
            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
Exemplo n.º 10
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(constants.SUBPORTS, events.PRECOMMIT_CREATE,
                                self, payload=payload)
        if added_subports:
            registry.notify(
                constants.SUBPORTS, events.AFTER_CREATE, self, payload=payload)
        return trunk
Exemplo n.º 11
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
Exemplo n.º 12
0
 def delete_trunk(self, context, trunk_id):
     """Delete the specified trunk."""
     with db_api.autonested_transaction(context.session):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if not trunk_port_validator.is_bound(context):
             trunk.delete()
             payload = callbacks.TrunkPayload(context, trunk_id,
                                              original_trunk=trunk)
             registry.notify(constants.TRUNK, events.PRECOMMIT_DELETE, self,
                             payload=payload)
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     registry.notify(constants.TRUNK, events.AFTER_DELETE, self,
                     payload=payload)
Exemplo n.º 13
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
Exemplo n.º 14
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
Exemplo n.º 15
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
Exemplo n.º 16
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 neutron_db_api.context_manager.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
Exemplo n.º 17
0
 def delete_trunk(self, context, trunk_id):
     """Delete the specified trunk."""
     with db_api.autonested_transaction(context.session):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if not trunk_port_validator.is_bound(context):
             # NOTE(status_police): when a trunk is deleted, the logical
             # object disappears from the datastore, therefore there is no
             # status transition involved. If PRECOMMIT failures occur,
             # the trunk remains in the status where it was.
             trunk.delete()
             payload = callbacks.TrunkPayload(context, trunk_id,
                                              original_trunk=trunk)
             registry.notify(constants.TRUNK, events.PRECOMMIT_DELETE, self,
                             payload=payload)
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     registry.notify(constants.TRUNK, events.AFTER_DELETE, self,
                     payload=payload)
Exemplo n.º 18
0
 def delete_trunk(self, context, trunk_id):
     """Delete the specified trunk."""
     with db_api.autonested_transaction(context.session):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if not trunk_port_validator.is_bound(context):
             trunk.delete()
             payload = callbacks.TrunkPayload(context,
                                              trunk_id,
                                              original_trunk=trunk)
             registry.notify(constants.TRUNK,
                             events.PRECOMMIT_DELETE,
                             self,
                             payload=payload)
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     registry.notify(constants.TRUNK,
                     events.AFTER_DELETE,
                     self,
                     payload=payload)
Exemplo n.º 19
0
    def add_subports(self, context, trunk_id, subports):
        """Add one or more subports to trunk."""
        # 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)
        subports = subports_validator.validate(context, basic_validation=True)
        added_subports = []

        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)
            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(constants.SUBPORTS,
                                events.PRECOMMIT_CREATE,
                                self,
                                payload=payload)
        if added_subports:
            registry.notify(constants.SUBPORTS,
                            events.AFTER_CREATE,
                            self,
                            payload=payload)
        return trunk
Exemplo n.º 20
0
 def delete_trunk(self, context, trunk_id):
     """Delete the trunk port."""
     LOG.debug("Deleting trunk_id %s", trunk_id)
     deleted_from_db = False
     with neutron_db_api.context_manager.writer.using(context):
         trunk = self._get_trunk(context, trunk_id)
         rules.trunk_can_be_managed(context, trunk)
         trunk_port_validator = rules.TrunkPortValidator(trunk.port_id)
         if not trunk_port_validator.is_bound(context):
             trunk.delete()
             deleted_from_db = True
             payload = callbacks.TrunkPayload(context, trunk_id,
                                              original_trunk=trunk)
             registry.notify(trunk_const.TRUNK,
                             events.PRECOMMIT_DELETE, self,
                             payload=payload)
         else:
             raise trunk_exc.TrunkInUse(trunk_id=trunk_id)
     if deleted_from_db:
         registry.notify(trunk_const.TRUNK,
                         events.AFTER_DELETE, self,
                         payload=payload)
Exemplo n.º 21
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