package org.ovirt.engine.core.bll.profiles; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import org.ovirt.engine.core.bll.ValidationResult; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.businessentities.ActionGroup; import org.ovirt.engine.core.common.businessentities.aaa.DbUser; import org.ovirt.engine.core.common.businessentities.profiles.DiskProfile; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.PermissionDao; import org.ovirt.engine.core.dao.profiles.DiskProfileDao; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton public class DiskProfileHelper { private static final Logger log = LoggerFactory.getLogger(DiskProfileHelper.class); @Inject private DiskProfileDao diskProfileDao; @Inject private PermissionDao permissionDao; public DiskProfile createDiskProfile(Guid storageDomainId, String name) { DiskProfile profile = new DiskProfile(); profile.setId(Guid.newGuid()); profile.setName(name); profile.setStorageDomainId(storageDomainId); return profile; } public ValidationResult setAndValidateDiskProfiles(Map<DiskImage, Guid> map, DbUser user) { if (map == null) { return ValidationResult.VALID; } Map<Guid, List<DiskProfile>> storageDiskProfilesMap = new HashMap<>(); // caching disk profile ids that was already checked. Set<Guid> permittedDiskProfilesIds = new HashSet<>(); for (Entry<DiskImage, Guid> entry : map.entrySet()) { DiskImage diskImage = entry.getKey(); Guid storageDomainId = entry.getValue(); if (diskImage.getDiskStorageType() != DiskStorageType.IMAGE) { log.info("Disk profiles is not supported for storage type '{}' (Disk '{}')", diskImage.getDiskStorageType(), diskImage.getDiskAlias()); continue; } if (diskImage.getDiskProfileId() == null && storageDomainId != null) { List<DiskProfile> diskProfilesList = storageDiskProfilesMap.get(storageDomainId); if (diskProfilesList == null) { diskProfilesList = diskProfileDao.getAllForStorageDomain(storageDomainId); storageDiskProfilesMap.put(storageDomainId, diskProfilesList); } // Set Disk Profile according to permissions if (!updateDiskProfileForBackwardCompatibility(diskImage, diskProfilesList, permittedDiskProfilesIds, user)) { return new ValidationResult(EngineMessage.USER_NOT_AUTHORIZED_TO_ATTACH_DISK_PROFILE); } } else { DiskProfile diskProfile = updateDiskImageProfilesList(diskImage, storageDomainId); if (diskProfile == null) { return new ValidationResult(EngineMessage.ACTION_TYPE_DISK_PROFILE_NOT_FOUND_FOR_STORAGE_DOMAIN, String.format("$storageDomainId %s", storageDomainId)); } ValidationResult result = isDiskProfileParentEntityValid(diskProfile, storageDomainId); if (result != ValidationResult.VALID) { return result; } if (!isDiskProfilePermitted(diskProfile, permittedDiskProfilesIds, user)) { return new ValidationResult(EngineMessage.USER_NOT_AUTHORIZED_TO_ATTACH_DISK_PROFILE); } } } return ValidationResult.VALID; } public ValidationResult isDiskProfileParentEntityValid(DiskProfile diskProfile, Guid storageDomainId) { return new DiskProfileValidator(diskProfile).isParentEntityValid(storageDomainId); } /** * Updates the disk profiles list of the given disk image according to the storageDomainID. * The disk profiles list will be set with the first disk profile that matches the storage domain id. * * @param diskImage disk image to be updated with the relevant disk profiles list * @param storageDomainId storage domain id to match a disk profile with * @return valid disk profile in case there is a match with the given storage domain ID. otherwise return an * invalid disk profile. */ private DiskProfile updateDiskImageProfilesList(DiskImage diskImage, Guid storageDomainId) { DiskProfile diskProfile = null; if (storageDomainId != null) { List<Guid> diskProfileIds = diskImage.getDiskProfileIds(); List<DiskProfile> diskProfilesListByStorageDomain = diskProfileDao.getAllForStorageDomain(storageDomainId); Optional<DiskProfile> match = diskProfilesListByStorageDomain.stream() .filter(profile -> diskProfileIds.contains(profile.getId())) .findFirst(); if (match.isPresent()) { diskProfile = match.get(); diskImage.setDiskProfileIds(new ArrayList<Guid>(Arrays.asList(diskProfile.getId()))); } } return diskProfile; } private boolean updateDiskProfileForBackwardCompatibility(DiskImage diskImage, List<DiskProfile> diskProfilesList, Set<Guid> permittedDiskProfilesIds, DbUser user) { for (DiskProfile diskProfile : diskProfilesList) { if (isDiskProfilePermitted(diskProfile, permittedDiskProfilesIds, user)) { permittedDiskProfilesIds.add(diskProfile.getId()); diskImage.setDiskProfileId(diskProfile.getId()); return true; } } return false; } private boolean isDiskProfilePermitted(DiskProfile diskProfile, Set<Guid> permittedDiskProfilesIds, DbUser user) { return user == null || permittedDiskProfilesIds.contains(diskProfile.getId()) || permissionDao.getEntityPermissions(user.getId(), ActionGroup.ATTACH_DISK_PROFILE, diskProfile.getId(), VdcObjectType.DiskProfile) != null; } }