package org.ovirt.engine.core.utils;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.VmRngDevice;
import org.ovirt.engine.core.compat.Version;
public class RngUtils {
/**
* Checks whether it is ok to have {@code rngDevice} assigned to a VM / Template with {@code effectiveVersion}
* in {@code cluster}.
*/
public static RngValidationResult validate(Cluster cluster, VmRngDevice rngDevice, Version effectiveVersion) {
VmRngDevice.Source source = rngDevice.getSource();
if (cluster == null) {
return validateForNonClusterEntity(source);
}
// This can be dropped when we stop to support 4.0 compatibility level
if (cluster.getCompatibilityVersion() != null
&& !cluster.getCompatibilityVersion().equals(effectiveVersion)
&& EnumSet.of(VmRngDevice.Source.URANDOM, VmRngDevice.Source.RANDOM).contains(source)
&& containsAtLeastOne(cluster.getRequiredRngSources(), VmRngDevice.Source.URANDOM, VmRngDevice.Source.RANDOM)
&& !cluster.getRequiredRngSources().contains(source)) {
return RngValidationResult.UNSUPPORTED_URANDOM_OR_RANDOM;
}
final boolean valid = cluster.getRequiredRngSources().contains(source);
return valid ? RngValidationResult.VALID : RngValidationResult.INVALID;
}
/**
* Both {@link VmRngDevice.Source.URANDOM} and {@link VmRngDevice.Source.RANDOM} are encoded using
* {@link VmRngDevice.Source.URANDOM} for non-cluster entities.
*/
private static RngValidationResult validateForNonClusterEntity(
VmRngDevice.Source source) {
final EnumSet<VmRngDevice.Source> allowedSources = EnumSet.allOf(VmRngDevice.Source.class);
allowedSources.remove(VmRngDevice.Source.RANDOM);
return allowedSources.contains(source) ? RngValidationResult.VALID : RngValidationResult.INVALID;
}
@SafeVarargs
private static <T> boolean containsAtLeastOne(Set<T> collection, T... requiredItems) {
final Set<T> requiredSet = new HashSet<>(Arrays.asList(requiredItems));
requiredSet.retainAll(collection);
return !requiredSet.isEmpty();
}
public enum RngValidationResult {
VALID,
/** basically invalid, but we treat it as valid to allow users to preview urandom/random change */
UNSUPPORTED_URANDOM_OR_RANDOM,
INVALID
}
}