package io.cattle.platform.iaas.api.volume;
import static io.cattle.platform.core.model.tables.StorageDriverTable.*;
import static io.cattle.platform.core.model.tables.VolumeTable.*;
import io.cattle.platform.api.auth.Policy;
import io.cattle.platform.core.constants.StorageDriverConstants;
import io.cattle.platform.core.constants.VolumeConstants;
import io.cattle.platform.core.model.StorageDriver;
import io.cattle.platform.core.model.Volume;
import io.cattle.platform.iaas.api.filter.common.AbstractDefaultResourceManagerFilter;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.meta.ObjectMetaDataManager;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.util.type.CollectionUtils;
import io.github.ibuildthecloud.gdapi.context.ApiContext;
import io.github.ibuildthecloud.gdapi.exception.ClientVisibleException;
import io.github.ibuildthecloud.gdapi.exception.ValidationErrorException;
import io.github.ibuildthecloud.gdapi.request.ApiRequest;
import io.github.ibuildthecloud.gdapi.request.resource.ResourceManager;
import io.github.ibuildthecloud.gdapi.util.ResponseCodes;
import io.github.ibuildthecloud.gdapi.validation.ValidationErrorCodes;
import java.util.HashSet;
import java.util.Map;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
public class VolumeCreateValidationFilter extends AbstractDefaultResourceManagerFilter {
@Inject
ObjectManager objectManager;
@Override
public Class<?>[] getTypeClasses() {
return new Class<?>[] { Volume.class };
}
@Override
public Object create(String type, ApiRequest request, ResourceManager next) {
Map<String, Object> data = CollectionUtils.toMap(request.getRequestObject());
if (data.get(VolumeConstants.FIELD_VOLUME_DRIVER) == null &&
data.get(VolumeConstants.FIELD_STORAGE_DRIVER_ID) == null) {
throw new ClientVisibleException(ResponseCodes.UNPROCESSABLE_ENTITY, ValidationErrorCodes.MISSING_REQUIRED,
String.format("Either %s or %s is required", VolumeConstants.FIELD_VOLUME_DRIVER,
VolumeConstants.FIELD_STORAGE_DRIVER_ID), null);
}
Volume volume = request.proxyRequestObject(Volume.class);
long accountId = ((Policy) ApiContext.getContext().getPolicy()).getAccountId();
Object d = data.get(VolumeConstants.FIELD_VOLUME_DRIVER);
String driver = d != null ? d.toString() : null;
Long driverId = volume.getStorageDriverId();
StorageDriver storageDriver = objectManager.loadResource(StorageDriver.class, driverId);
if (storageDriver != null) {
Volume existingVolume = objectManager.findAny(Volume.class,
VOLUME.NAME, volume.getName(),
VOLUME.REMOVED, null,
VOLUME.STORAGE_DRIVER_ID, storageDriver.getId());
if (existingVolume != null) {
throw new ValidationErrorException(ValidationErrorCodes.NOT_UNIQUE, ObjectMetaDataManager.NAME_FIELD);
}
}
if (volume.getSizeMb() != null) {
if (storageDriver == null && StringUtils.isNotBlank(driver)) {
storageDriver = objectManager.findAny(StorageDriver.class,
STORAGE_DRIVER.ACCOUNT_ID, accountId,
STORAGE_DRIVER.REMOVED, null,
STORAGE_DRIVER.NAME, driver);
}
if (storageDriver == null
|| !new HashSet<String>(DataAccessor.fieldStringList(storageDriver, ObjectMetaDataManager.CAPABILITIES_FIELD))
.contains(StorageDriverConstants.CAPABILITY_SCHEDULE_SIZE)) {
throw new ClientVisibleException(ResponseCodes.UNPROCESSABLE_ENTITY, ValidationErrorCodes.INVALID_OPTION,
String.format("Volume driver %s does not support specifying a size.", driver), null);
}
}
return super.create(type, request, next);
}
}