Example #1
0
    def test_get_volume_type(self):
        """Test if `get_volume_type` works properly."""
        # Fail to get volume type with non-existent id
        vt_id = 1134
        not_found_msg = "Volume type %s not found" % vt_id
        with self.assertRaisesMessage(faults.ItemNotFound, not_found_msg):
            util.get_volume_type(vt_id)

        # Fail to get volume type with invalid id
        vt_id = "could this BE any less int?"
        invalid_msg = "Invalid volume type id: %s" % vt_id
        with self.assertRaisesMessage(faults.BadRequest, invalid_msg):
            util.get_volume_type(vt_id)

        # Success case
        vt = mf.VolumeTypeFactory()
        self.assertEqual(vt, util.get_volume_type(vt.id))
Example #2
0
    def test_get_volume_type(self):
        """Test if `get_volume_type` works properly."""
        # Fail to get volume type with non-existent id
        vt_id = 1134
        not_found_msg = "Volume type %s not found" % vt_id
        with self.assertRaisesMessage(faults.ItemNotFound, not_found_msg):
            util.get_volume_type(vt_id)

        # Fail to get volume type with invalid id
        vt_id = "could this BE any less int?"
        invalid_msg = "Invalid volume type id: %s" % vt_id
        with self.assertRaisesMessage(faults.BadRequest, invalid_msg):
            util.get_volume_type(vt_id)

        # Success case
        vt = mf.VolumeTypeFactory()
        self.assertEqual(vt, util.get_volume_type(vt.id))
Example #3
0
def create(user_id, size, server=None, name=None, description=None,
           source_volume_id=None, source_snapshot_id=None,
           source_image_id=None, volume_type_id=None, metadata=None,
           project_id=None, shared_to_project=False):
    """Create a new volume and optionally attach it to a server.

    This function serves as the main entry-point for volume creation. It gets
    the necessary data either from the API or from an snf-manage command and
    then feeds that data to the lower-level functions that handle the actual
    creation of the volume and the server attachments.
    """
    volume_type = None

    # If given a server id, assert that it exists and that it belongs to the
    # user.
    if server:
        volume_type = server.flavor.volume_type
        # If the server's volume type conflicts with the provided volume type,
        # raise an exception.
        if volume_type_id and \
           volume_type.id != util.normalize_volume_type_id(volume_type_id):
            raise faults.BadRequest("Cannot create a volume with type '%s' to"
                                    " a server with volume type '%s'."
                                    % (volume_type_id, volume_type.id))

    # If the user has not provided a valid volume type, raise an exception.
    if volume_type is None:
        volume_type = util.get_volume_type(volume_type_id,
                                           include_deleted=False,
                                           exception=faults.BadRequest)

    # We cannot create a non-detachable volume without a server.
    if server is None:
        util.assert_detachable_volume_type(volume_type)

    volume = create_common(user_id, size, name=name,
                           description=description,
                           source_image_id=source_image_id,
                           source_snapshot_id=source_snapshot_id,
                           source_volume_id=source_volume_id,
                           volume_type=volume_type, metadata={},
                           project_id=project_id,
                           shared_to_project=shared_to_project)

    if server is not None:
        server_attachments.attach_volume(server, volume)
    else:
        quotas.issue_and_accept_commission(volume, action="BUILD")
        # If the volume has been created in the DB, consider it available.
        volume.status = "AVAILABLE"
        volume.save()

    return volume
Example #4
0
def create(user_id, size, server=None, name=None, description=None,
           source_volume_id=None, source_snapshot_id=None,
           source_image_id=None, volume_type_id=None, metadata=None,
           project_id=None, shared_to_project=False):
    """Create a new volume and optionally attach it to a server.

    This function serves as the main entry-point for volume creation. It gets
    the necessary data either from the API or from an snf-manage command and
    then feeds that data to the lower-level functions that handle the actual
    creation of the volume and the server attachments.
    """
    volume_type = None

    # If given a server id, assert that it exists and that it belongs to the
    # user.
    if server:
        volume_type = server.flavor.volume_type
        # If the server's volume type conflicts with the provided volume type,
        # raise an exception.
        if volume_type_id and \
           volume_type.id != util.normalize_volume_type_id(volume_type_id):
            raise faults.BadRequest("Cannot create a volume with type '%s' to"
                                    " a server with volume type '%s'."
                                    % (volume_type_id, volume_type.id))

    # If the user has not provided a valid volume type, raise an exception.
    if volume_type is None:
        volume_type = util.get_volume_type(volume_type_id,
                                           include_deleted=False,
                                           exception=faults.BadRequest)

    # We cannot create a non-detachable volume without a server.
    if server is None:
        util.assert_detachable_volume_type(volume_type)

    volume = create_common(user_id, size, name=name,
                           description=description,
                           source_image_id=source_image_id,
                           source_snapshot_id=source_snapshot_id,
                           source_volume_id=source_volume_id,
                           volume_type=volume_type, metadata={},
                           project_id=project_id,
                           shared_to_project=shared_to_project)

    if server is not None:
        server_attachments.attach_volume(server, volume)
    else:
        quotas.issue_and_accept_commission(volume, action="BUILD")
        # If the volume has been created in the DB, consider it available.
        volume.status = "AVAILABLE"
        volume.save()

    return volume
Example #5
0
def get_volume_type(request, volume_type_id):
    log.debug('get_volume_type volume_type_id: %s', volume_type_id)
    volume_type = util.get_volume_type(volume_type_id, include_deleted=True)
    data = json.dumps({'volume_type': volume_type_to_dict(volume_type)})
    return HttpResponse(data, content_type="application/json", status=200)
Example #6
0
def create(user_id,
           size,
           server_id,
           name=None,
           description=None,
           source_volume_id=None,
           source_snapshot_id=None,
           source_image_id=None,
           volume_type_id=None,
           metadata=None,
           project=None):

    # Currently we cannot create volumes without being attached to a server
    if server_id is None:
        raise faults.BadRequest("Volume must be attached to server")
    server = util.get_server(user_id,
                             server_id,
                             for_update=True,
                             non_deleted=True,
                             exception=faults.BadRequest)

    server_vtype = server.flavor.volume_type
    if volume_type_id is not None:
        volume_type = util.get_volume_type(volume_type_id,
                                           include_deleted=False,
                                           exception=faults.BadRequest)
        if volume_type != server_vtype:
            raise faults.BadRequest("Cannot create a volume with type '%s' to"
                                    " a server with volume type '%s'." %
                                    (volume_type.id, server_vtype.id))
    else:
        volume_type = server_vtype

    # Assert that not more than one source are used
    sources = filter(lambda x: x is not None,
                     [source_volume_id, source_snapshot_id, source_image_id])
    if len(sources) > 1:
        raise faults.BadRequest("Volume can not have more than one source!")

    if source_volume_id is not None:
        source_type = "volume"
        source_uuid = source_volume_id
    elif source_snapshot_id is not None:
        source_type = "snapshot"
        source_uuid = source_snapshot_id
    elif source_image_id is not None:
        source_type = "image"
        source_uuid = source_image_id
    else:
        source_type = "blank"
        source_uuid = None

    if project is None:
        project = user_id

    if metadata is not None and \
       len(metadata) > settings.CYCLADES_VOLUME_MAX_METADATA:
        raise faults.BadRequest("Volumes cannot have more than %s metadata "
                                "items" %
                                settings.CYCLADES_VOLUME_MAX_METADATA)

    volume = _create_volume(server,
                            user_id,
                            project,
                            size,
                            source_type,
                            source_uuid,
                            volume_type=volume_type,
                            name=name,
                            description=description,
                            index=None)

    if metadata is not None:
        for meta_key, meta_val in metadata.items():
            utils.check_name_length(meta_key, VolumeMetadata.KEY_LENGTH,
                                    "Metadata key is too long")
            utils.check_name_length(meta_val, VolumeMetadata.VALUE_LENGTH,
                                    "Metadata key is too long")
            volume.metadata.create(key=meta_key, value=meta_val)

    server_attachments.attach_volume(server, volume)

    return volume
Example #7
0
def get_volume_type(request, volume_type_id):
    log.debug('get_volume_type volume_type_id: %s', volume_type_id)
    volume_type = util.get_volume_type(volume_type_id, include_deleted=True)
    data = json.dumps({'volume_type': volume_type_to_dict(volume_type)})
    return HttpResponse(data, content_type="application/json", status=200)
Example #8
0
def create(user_id, size, server_id, name=None, description=None,
           source_volume_id=None, source_snapshot_id=None,
           source_image_id=None, volume_type_id=None, metadata=None,
           project=None):

    # Currently we cannot create volumes without being attached to a server
    if server_id is None:
        raise faults.BadRequest("Volume must be attached to server")
    server = util.get_server(user_id, server_id, for_update=True,
                             non_deleted=True,
                             exception=faults.BadRequest)

    server_vtype = server.flavor.volume_type
    if volume_type_id is not None:
        volume_type = util.get_volume_type(volume_type_id,
                                           include_deleted=False,
                                           exception=faults.BadRequest)
        if volume_type != server_vtype:
            raise faults.BadRequest("Cannot create a volume with type '%s' to"
                                    " a server with volume type '%s'."
                                    % (volume_type.id, server_vtype.id))
    else:
        volume_type = server_vtype

    # Assert that not more than one source are used
    sources = filter(lambda x: x is not None,
                     [source_volume_id, source_snapshot_id, source_image_id])
    if len(sources) > 1:
        raise faults.BadRequest("Volume can not have more than one source!")

    if source_volume_id is not None:
        source_type = "volume"
        source_uuid = source_volume_id
    elif source_snapshot_id is not None:
        source_type = "snapshot"
        source_uuid = source_snapshot_id
    elif source_image_id is not None:
        source_type = "image"
        source_uuid = source_image_id
    else:
        source_type = "blank"
        source_uuid = None

    if project is None:
        project = user_id

    if metadata is not None and \
       len(metadata) > settings.CYCLADES_VOLUME_MAX_METADATA:
        raise faults.BadRequest("Volumes cannot have more than %s metadata "
                                "items" %
                                settings.CYCLADES_VOLUME_MAX_METADATA)

    volume = _create_volume(server, user_id, project, size,
                            source_type, source_uuid,
                            volume_type=volume_type, name=name,
                            description=description, index=None)

    if metadata is not None:
        for meta_key, meta_val in metadata.items():
            utils.check_name_length(meta_key, VolumeMetadata.KEY_LENGTH,
                                    "Metadata key is too long")
            utils.check_name_length(meta_val, VolumeMetadata.VALUE_LENGTH,
                                    "Metadata key is too long")
            volume.metadata.create(key=meta_key, value=meta_val)

    server_attachments.attach_volume(server, volume)

    return volume