コード例 #1
0
def add_uuid_filter(query, value):
    if utils.is_int_like(value):
        return query.filter_by(id=value)
    elif uuidutils.is_uuid_like(value):
        return query.filter_by(uuid=value)
    else:
        raise exception.InvalidUUID(uuid=value)
コード例 #2
0
ファイル: api.py プロジェクト: luongduy/ironic
    def get_node_by_instance(self, instance):
        if not utils.is_uuid_like(instance):
            raise exception.InvalidUUID(uuid=instance)

        query = (model_query(models.Node).filter_by(instance_uuid=instance))

        try:
            result = query.one()
        except NoResultFound:
            raise exception.InstanceNotFound(instance=instance)

        return result
コード例 #3
0
ファイル: api.py プロジェクト: saintifly/Server_Manage_Plugin
    def get_node_by_instance(self, instance):
        if not uuidutils.is_uuid_like(instance):
            raise exception.InvalidUUID(uuid=instance)

        query = _get_node_query_with_tags()
        query = query.filter_by(instance_uuid=instance)

        try:
            result = query.one()
        except NoResultFound:
            raise exception.InstanceNotFound(instance=instance)

        return result
コード例 #4
0
 def validate(value):
     if not uuidutils.is_uuid_like(value):
         raise exception.InvalidUUID(uuid=value)
     return value
コード例 #5
0
    def patch(self, connector_uuid, patch):
        """Update an existing volume connector.

        :param connector_uuid: UUID of a volume connector.
        :param patch: a json PATCH document to apply to this volume connector.

        :returns: API-serializable volume connector object.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: PatchError if a given patch can not be applied.
        :raises: VolumeConnectorNotFound if no volume connector exists with
                 the specified UUID.
        :raises: InvalidParameterValue if the volume connector's UUID is being
                 changed
        :raises: NodeLocked if node is locked by another conductor
        :raises: NodeNotFound if the node associated with the connector does
                 not exist
        :raises: VolumeConnectorTypeAndIdAlreadyExists if another connector
                 already exists with the same values for type and connector_id
                 fields
        :raises: InvalidUUID if invalid node UUID is passed in the patch.
        :raises: InvalidStateRequested If a node associated with the
                 volume connector is not powered off.
        """
        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:volume:update', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        values = api_utils.get_patch_values(patch, '/node_uuid')
        for value in values:
            if not uuidutils.is_uuid_like(value):
                message = _("Expected a UUID for node_uuid, but received "
                            "%(uuid)s.") % {
                                'uuid': six.text_type(value)
                            }
                raise exception.InvalidUUID(message=message)

        rpc_connector = objects.VolumeConnector.get_by_uuid(
            context, connector_uuid)
        try:
            connector_dict = rpc_connector.as_dict()
            # NOTE(smoriya):
            # 1) Remove node_id because it's an internal value and
            #    not present in the API object
            # 2) Add node_uuid
            connector_dict['node_uuid'] = connector_dict.pop('node_id', None)
            connector = VolumeConnector(
                **api_utils.apply_jsonpatch(connector_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed.
        for field in objects.VolumeConnector.fields:
            try:
                patch_val = getattr(connector, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if rpc_connector[field] != patch_val:
                rpc_connector[field] = patch_val

        rpc_node = objects.Node.get_by_id(context, rpc_connector.node_id)
        notify.emit_start_notification(context,
                                       rpc_connector,
                                       'update',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context,
                                              rpc_connector,
                                              'update',
                                              node_uuid=rpc_node.uuid):
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
            new_connector = pecan.request.rpcapi.update_volume_connector(
                context, rpc_connector, topic)

        api_connector = VolumeConnector.convert_with_links(new_connector)
        notify.emit_end_notification(context,
                                     new_connector,
                                     'update',
                                     node_uuid=rpc_node.uuid)
        return api_connector
コード例 #6
0
    def patch(self, target_uuid, patch):
        """Update an existing volume target.

        :param target_uuid: UUID of a volume target.
        :param patch: a json PATCH document to apply to this volume target.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: PatchError if a given patch can not be applied.
        :raises: InvalidParameterValue if the volume target's UUID is being
                 changed
        :raises: NodeLocked if the node is already locked
        :raises: NodeNotFound if the node associated with the volume target
                 does not exist
        :raises: VolumeTargetNotFound if the volume target cannot be found
        :raises: VolumeTargetBootIndexAlreadyExists if a volume target already
                 exists with the same node ID and boot index values
        :raises: InvalidUUID if invalid node UUID is passed in the patch.
        :raises: InvalidStateRequested If a node associated with the
                 volume target is not powered off.
        """
        context = api.request.context
        api_utils.check_policy('baremetal:volume:update')

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        api_utils.patch_validate_allowed_fields(patch, PATCH_ALLOWED_FIELDS)

        values = api_utils.get_patch_values(patch, '/node_uuid')
        for value in values:
            if not uuidutils.is_uuid_like(value):
                message = _("Expected a UUID for node_uuid, but received "
                            "%(uuid)s.") % {
                                'uuid': str(value)
                            }
                raise exception.InvalidUUID(message=message)

        rpc_target = objects.VolumeTarget.get_by_uuid(context, target_uuid)
        target_dict = rpc_target.as_dict()
        # NOTE(smoriya):
        # 1) Remove node_id because it's an internal value and
        #    not present in the API object
        # 2) Add node_uuid
        rpc_node = api_utils.replace_node_id_with_uuid(target_dict)

        target_dict = api_utils.apply_jsonpatch(target_dict, patch)

        try:
            if target_dict['node_uuid'] != rpc_node.uuid:
                rpc_node = objects.Node.get(api.request.context,
                                            target_dict['node_uuid'])
        except exception.NodeNotFound as e:
            # Change error code because 404 (NotFound) is inappropriate
            # response for a PATCH request to change a volume target
            e.code = http_client.BAD_REQUEST  # BadRequest
            raise

        api_utils.patched_validate_with_schema(target_dict, TARGET_SCHEMA,
                                               TARGET_VALIDATOR)

        api_utils.patch_update_changed_fields(
            target_dict,
            rpc_target,
            fields=objects.VolumeTarget.fields,
            schema=TARGET_SCHEMA,
            id_map={'node_id': rpc_node.id})

        notify.emit_start_notification(context,
                                       rpc_target,
                                       'update',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context,
                                              rpc_target,
                                              'update',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            new_target = api.request.rpcapi.update_volume_target(
                context, rpc_target, topic)

        api_target = convert_with_links(new_target)
        notify.emit_end_notification(context,
                                     new_target,
                                     'update',
                                     node_uuid=rpc_node.uuid)
        return api_target
コード例 #7
0
    def patch(self, target_uuid, patch):
        """Update an existing volume target.

        :param target_uuid: UUID of a volume target.
        :param patch: a json PATCH document to apply to this volume target.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: PatchError if a given patch can not be applied.
        :raises: InvalidParameterValue if the volume target's UUID is being
                 changed
        :raises: NodeLocked if the node is already locked
        :raises: NodeNotFound if the node associated with the volume target
                 does not exist
        :raises: VolumeTargetNotFound if the volume target cannot be found
        :raises: VolumeTargetBootIndexAlreadyExists if a volume target already
                 exists with the same node ID and boot index values
        :raises: InvalidUUID if invalid node UUID is passed in the patch.
        :raises: InvalidStateRequested If a node associated with the
                 volume target is not powered off.
        """
        context = api.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:volume:update', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        values = api_utils.get_patch_values(patch, '/node_uuid')
        for value in values:
            if not uuidutils.is_uuid_like(value):
                message = _("Expected a UUID for node_uuid, but received "
                            "%(uuid)s.") % {'uuid': str(value)}
                raise exception.InvalidUUID(message=message)

        rpc_target = objects.VolumeTarget.get_by_uuid(context, target_uuid)
        target_dict = rpc_target.as_dict()
        # NOTE(smoriya):
        # 1) Remove node_id because it's an internal value and
        #    not present in the API object
        # 2) Add node_uuid
        target_dict['node_uuid'] = target_dict.pop('node_id', None)
        target = VolumeTarget(
            **api_utils.apply_jsonpatch(target_dict, patch))

        # Update only the fields that have changed.
        for field in objects.VolumeTarget.fields:
            try:
                patch_val = getattr(target, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == atypes.Unset:
                patch_val = None
            if rpc_target[field] != patch_val:
                rpc_target[field] = patch_val

        rpc_node = objects.Node.get_by_id(context, rpc_target.node_id)
        notify.emit_start_notification(context, rpc_target, 'update',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_target, 'update',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            new_target = api.request.rpcapi.update_volume_target(
                context, rpc_target, topic)

        api_target = VolumeTarget.convert_with_links(new_target)
        notify.emit_end_notification(context, new_target, 'update',
                                     node_uuid=rpc_node.uuid)
        return api_target
コード例 #8
0
    def patch(self, connector_uuid, patch):
        """Update an existing volume connector.

        :param connector_uuid: UUID of a volume connector.
        :param patch: a json PATCH document to apply to this volume connector.

        :returns: API-serializable volume connector object.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: PatchError if a given patch can not be applied.
        :raises: VolumeConnectorNotFound if no volume connector exists with
                 the specified UUID.
        :raises: InvalidParameterValue if the volume connector's UUID is being
                 changed
        :raises: NodeLocked if node is locked by another conductor
        :raises: NodeNotFound if the node associated with the connector does
                 not exist
        :raises: VolumeConnectorTypeAndIdAlreadyExists if another connector
                 already exists with the same values for type and connector_id
                 fields
        :raises: InvalidUUID if invalid node UUID is passed in the patch.
        :raises: InvalidStateRequested If a node associated with the
                 volume connector is not powered off.
        """
        context = api.request.context

        rpc_connector, rpc_node = api_utils.check_volume_policy_and_retrieve(
            'baremetal:volume:update',
            connector_uuid,
            target=False)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        api_utils.patch_validate_allowed_fields(patch, PATCH_ALLOWED_FIELDS)

        for value in api_utils.get_patch_values(patch, '/node_uuid'):
            if not uuidutils.is_uuid_like(value):
                message = _("Expected a UUID for node_uuid, but received "
                            "%(uuid)s.") % {'uuid': str(value)}
                raise exception.InvalidUUID(message=message)

        connector_dict = rpc_connector.as_dict()
        # NOTE(smoriya):
        # 1) Remove node_id because it's an internal value and
        #    not present in the API object
        # 2) Add node_uuid
        rpc_node = api_utils.replace_node_id_with_uuid(connector_dict)

        connector_dict = api_utils.apply_jsonpatch(connector_dict, patch)

        try:
            if connector_dict['node_uuid'] != rpc_node.uuid:
                rpc_node = objects.Node.get(
                    api.request.context, connector_dict['node_uuid'])
        except exception.NodeNotFound as e:
            # Change error code because 404 (NotFound) is inappropriate
            # response for a PATCH request to change a Port
            e.code = http_client.BAD_REQUEST  # BadRequest
            raise

        api_utils.patched_validate_with_schema(
            connector_dict, CONNECTOR_SCHEMA, CONNECTOR_VALIDATOR)

        api_utils.patch_update_changed_fields(
            connector_dict, rpc_connector,
            fields=objects.VolumeConnector.fields,
            schema=CONNECTOR_SCHEMA, id_map={'node_id': rpc_node.id}
        )

        notify.emit_start_notification(context, rpc_connector, 'update',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_connector, 'update',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            new_connector = api.request.rpcapi.update_volume_connector(
                context, rpc_connector, topic)

        api_connector = convert_with_links(new_connector)
        notify.emit_end_notification(context, new_connector, 'update',
                                     node_uuid=rpc_node.uuid)
        return api_connector