package org.ovirt.engine.api.restapi.resource; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.ovirt.engine.api.model.BootDevice; import org.ovirt.engine.api.model.BootDevices; import org.ovirt.engine.api.model.BootProtocol; import org.ovirt.engine.api.model.BootProtocols; import org.ovirt.engine.api.model.CPU; import org.ovirt.engine.api.model.CPUs; import org.ovirt.engine.api.model.Capabilities; import org.ovirt.engine.api.model.CreationStates; import org.ovirt.engine.api.model.CreationStatus; import org.ovirt.engine.api.model.CustomProperties; import org.ovirt.engine.api.model.CustomProperty; import org.ovirt.engine.api.model.DataCenterStates; import org.ovirt.engine.api.model.DataCenterStatus; import org.ovirt.engine.api.model.DiskFormat; import org.ovirt.engine.api.model.DiskFormats; import org.ovirt.engine.api.model.DiskInterface; import org.ovirt.engine.api.model.DiskInterfaces; import org.ovirt.engine.api.model.DiskStates; import org.ovirt.engine.api.model.DiskStatus; import org.ovirt.engine.api.model.DiskType; import org.ovirt.engine.api.model.DiskTypes; import org.ovirt.engine.api.model.DisplayType; import org.ovirt.engine.api.model.DisplayTypes; import org.ovirt.engine.api.model.Features; import org.ovirt.engine.api.model.FenceType; import org.ovirt.engine.api.model.FenceTypes; import org.ovirt.engine.api.model.HostNICStates; import org.ovirt.engine.api.model.HostNonOperationalDetails; import org.ovirt.engine.api.model.HostStates; import org.ovirt.engine.api.model.HostStatus; import org.ovirt.engine.api.model.NetworkStates; import org.ovirt.engine.api.model.NetworkStatus; import org.ovirt.engine.api.model.NicInterface; import org.ovirt.engine.api.model.NicInterfaces; import org.ovirt.engine.api.model.NicStatus; import org.ovirt.engine.api.model.OsType; import org.ovirt.engine.api.model.OsTypes; import org.ovirt.engine.api.model.Permit; import org.ovirt.engine.api.model.PermitType; import org.ovirt.engine.api.model.Permits; import org.ovirt.engine.api.model.PowerManagement; import org.ovirt.engine.api.model.PowerManagementStates; import org.ovirt.engine.api.model.PowerManagementStatus; import org.ovirt.engine.api.model.PowerManagers; import org.ovirt.engine.api.model.SchedulingPolicyType; import org.ovirt.engine.api.model.SchedulingPolicies; import org.ovirt.engine.api.model.StorageDomainStates; import org.ovirt.engine.api.model.StorageDomainStatus; import org.ovirt.engine.api.model.StorageDomainType; import org.ovirt.engine.api.model.StorageDomainTypes; import org.ovirt.engine.api.model.TemplateStates; import org.ovirt.engine.api.model.TemplateStatus; import org.ovirt.engine.api.model.VmPauseDetails; import org.ovirt.engine.api.model.VmStates; import org.ovirt.engine.api.model.VmStatus; import org.ovirt.engine.api.restapi.model.StorageFormat; import org.ovirt.engine.api.model.StorageFormats; import org.ovirt.engine.api.model.StorageType; import org.ovirt.engine.api.model.StorageTypes; import org.ovirt.engine.api.model.TransparentHugePages; import org.ovirt.engine.api.model.Version; import org.ovirt.engine.api.model.VersionCaps; import org.ovirt.engine.api.model.VmAffinities; import org.ovirt.engine.api.model.VmAffinity; import org.ovirt.engine.api.model.VmType; import org.ovirt.engine.api.model.VmTypes; import org.ovirt.engine.api.resource.CapabilitiesResource; import org.ovirt.engine.core.common.businessentities.ServerCpu; import org.ovirt.engine.core.common.queries.ConfigurationValues; import org.ovirt.engine.core.common.businessentities.NonOperationalReason; import org.ovirt.engine.api.restapi.types.MappingLocator; import org.ovirt.engine.api.restapi.util.FencingOptionsParser; import org.ovirt.engine.api.restapi.util.ServerCpuParser; import org.ovirt.engine.api.restapi.util.VersionHelper; import org.ovirt.engine.api.restapi.utils.CustomPropertiesParser; import org.ovirt.engine.api.restapi.utils.VersionUtils; import org.ovirt.engine.core.common.businessentities.VmPauseStatus; import org.ovirt.engine.api.model.MigrateOnError; public class BackendCapabilitiesResource extends BackendResource implements CapabilitiesResource { private MappingLocator mappingLocator; public void setMappingLocator(MappingLocator mappingLocator) { this.mappingLocator = mappingLocator; } private static final Version VERSION_3_0 = new Version() {{ major = 3; minor = 0; }}; private static Version currentVersion = null; public Capabilities get() { Capabilities caps = new Capabilities(); VersionCaps current = null; for (Version v : getSupportedClusterLevels()) { VersionCaps version = new VersionCaps(); version.setMajor(v.getMajor()); version.setMinor(v.getMinor()); version.setCPUs(new CPUs()); for (ServerCpu sc : getServerCpuList(v)) { CPU cpu = new CPU(); cpu.setId(sc.getCpuName()); cpu.setLevel(sc.getLevel()); version.getCPUs().getCPUs().add(cpu); } addPowerManagers(version, getPowerManagers(v)); addVmTypes(version, VmType.values()); addStorageTypes(version, getStorageTypes(v)); addStorageDomainTypes(version, StorageDomainType.values()); addFenceTypes(version, FenceType.values()); addBootDevices(version, BootDevice.values()); addDisplayTypes(version, DisplayType.values()); addNicInterfaces(version, NicInterface.values()); addDiskTypes(version, DiskType.values()); addDiskFormats(version, DiskFormat.values()); addDiskInterfaces(version, DiskInterface.values()); addCustomProperties(version, getVmHooksEnvs(v)); addVmAffinities(version, VmAffinity.values()); addnetworkBootProtocols(version, BootProtocol.values()); addMigrateOnErrorOptions(version, MigrateOnError.values()); addStorageFormatOptions(version, StorageFormat.values()); addOsTypes(version, OsType.values()); //Add States. User can't update States, but he still needs to know which exist. addCreationStates(version, CreationStatus.values()); addStorageDomaintStates(version, StorageDomainStatus.values()); addPowerManagementStateses(version, PowerManagementStatus.values()); addHostStates(version, HostStatus.values()); addHostNonOperationalDetails(version, NonOperationalReason.values()); addNetworkStates(version, NetworkStatus.values()); addTemplateStates(version, TemplateStatus.values()); addVmStates(version, VmStatus.values()); addVmPauseDetails(version, VmPauseStatus.values()); addDiskStates(version, DiskStatus.values()); addHostNICStates(version, NicStatus.values()); addDataCenterStates(version, DataCenterStatus.values()); version.setFeatures(getFeatures(v)); caps.getVersions().add(version); if (current == null && VersionHelper.equals(v, getCurrentVersion())) { current = version; current.setCurrent(true); } else { version.setCurrent(false); } } caps.setPermits(getPermits()); caps.setSchedulingPolicies(getSchedulingPolicies()); return caps; } private Version getCurrentVersion() { if (currentVersion == null) { currentVersion = VersionHelper.parseVersion(getConfigurationValue(String.class, ConfigurationValues.VdcVersion, null)); } return currentVersion; } private void addOsTypes(VersionCaps version, OsType[] types) { version.setOsTypes(new OsTypes()); for (OsType type : types) { version.getOsTypes().getOsTypes().add(type.value()); } } private void addnetworkBootProtocols(VersionCaps version, BootProtocol[] values) { version.setBootProtocols(new BootProtocols()); for (BootProtocol bootProtocol : values) { version.getBootProtocols().getBootProtocols().add(bootProtocol.value()); } } private void addVmAffinities(VersionCaps version, VmAffinity[] values) { if (VersionUtils.greaterOrEqual(version, VERSION_3_0)) { version.setVmAffinities(new VmAffinities()); for (VmAffinity affinity : values) { version.getVmAffinities().getVmAffinities().add(affinity.value()); } } } private void addPowerManagers(VersionCaps version, List<PowerManagement> powerManagers) { version.setPowerManagers(new PowerManagers()); version.getPowerManagers().getPowerManagers().addAll(powerManagers); } private void addVmTypes(VersionCaps version, VmType... types) { version.setVmTypes(new VmTypes()); for (VmType type : types) { version.getVmTypes().getVmTypes().add(type.value()); } } private void addStorageTypes(VersionCaps version, List<StorageType> types) { version.setStorageTypes(new StorageTypes()); for (StorageType type : types) { version.getStorageTypes().getStorageTypes().add(type.value()); } } private void addStorageDomainTypes(VersionCaps version, StorageDomainType... types) { version.setStorageDomainTypes(new StorageDomainTypes()); for (StorageDomainType type : types) { version.getStorageDomainTypes().getStorageDomainTypes().add(type.value()); } } private void addFenceTypes(VersionCaps version, FenceType... types) { version.setFenceTypes(new FenceTypes()); for (FenceType type : types) { version.getFenceTypes().getFenceTypes().add(type.value()); } } private void addBootDevices(VersionCaps version, BootDevice... devs) { version.setBootDevices(new BootDevices()); for (BootDevice dev : devs) { version.getBootDevices().getBootDevices().add(dev.value()); } } private void addDisplayTypes(VersionCaps version, DisplayType... types) { version.setDisplayTypes(new DisplayTypes()); for (DisplayType type : types) { version.getDisplayTypes().getDisplayTypes().add(type.value()); } } private void addNicInterfaces(VersionCaps version, NicInterface... types) { version.setNicInterfaces(new NicInterfaces()); for (NicInterface type : types) { version.getNicInterfaces().getNicInterfaces().add(type.value()); } } private void addDiskTypes(VersionCaps version, DiskType... types) { version.setDiskTypes(new DiskTypes()); for (DiskType type : types) { version.getDiskTypes().getDiskTypes().add(type.value()); } } private void addDiskFormats(VersionCaps version, DiskFormat... types) { version.setDiskFormats(new DiskFormats()); for (DiskFormat type : types) { version.getDiskFormats().getDiskFormats().add(type.value()); } } private void addDiskInterfaces(VersionCaps version, DiskInterface... interfaces) { version.setDiskInterfaces(new DiskInterfaces()); for (DiskInterface iface : interfaces) { version.getDiskInterfaces().getDiskInterfaces().add(iface.value()); } } private void addCustomProperties(VersionCaps version, List<CustomProperty> envs) { version.setCustomProperties(new CustomProperties()); version.getCustomProperties().getCustomProperty().addAll(envs); } private List<PowerManagement> getPowerManagers(Version version) { return FencingOptionsParser.parse(getConfigurationValue(String.class, ConfigurationValues.VdsFenceOptionMapping, version), getConfigurationValue(String.class, ConfigurationValues.VdsFenceOptionTypes, version), true); } private List<StorageType> getStorageTypes(Version version) { List<StorageType> ret = new ArrayList<StorageType>(); ret.add(StorageType.ISCSI); ret.add(StorageType.FCP); ret.add(StorageType.NFS); if (localStorageEnabled(version)) { ret.add(StorageType.LOCALFS); } return ret; } private boolean localStorageEnabled(Version version) { return getConfigurationValue(Boolean.class, ConfigurationValues.LocalStorageEnabled, version); } private List<CustomProperty> getVmHooksEnvs(Version version) { List<CustomProperty> ret = new ArrayList<CustomProperty>(); ret.addAll(CustomPropertiesParser.parse(getConfigurationValue(String.class, ConfigurationValues.PredefinedVMProperties, version), true)); ret.addAll(CustomPropertiesParser.parse(getConfigurationValue(String.class, ConfigurationValues.UserDefinedVMProperties, version), true)); return ret; } private Features getFeatures(Version version) { Features ret = new Features(); if (VersionUtils.greaterOrEqual(version, VERSION_3_0)) { ret.setTransparentHugepages(new TransparentHugePages()); } return ret; } private List<ServerCpu> getServerCpuList(Version version) { return ServerCpuParser.parseCpus(getConfigurationValue(String.class, ConfigurationValues.ServerCPUList, version)); } private List<Version> getSupportedClusterLevels() { List<Version> versions = new ArrayList<Version>(); for (org.ovirt.engine.core.compat.Version v : (Set<org.ovirt.engine.core.compat.Version>)getConfigurationValue(Set.class, ConfigurationValues.SupportedClusterLevels, null)){ Version version = new Version(); version.setMajor(v.getMajor()); version.setMinor(v.getMinor()); versions.add(version); } return versions; } private Permit map(PermitType entity) { return mappingLocator.getMapper(PermitType.class, Permit.class).map(entity, null); } private Permits getPermits() { Permits permits = new Permits(); for (PermitType permit : PermitType.values()) { permits.getPermits().add(map(permit)); } return permits; } private SchedulingPolicies getSchedulingPolicies() { SchedulingPolicies policies = new SchedulingPolicies(); for (SchedulingPolicyType policy : SchedulingPolicyType.values()) { policies.getPolicy().add(policy.value()); } return policies; } private void addMigrateOnErrorOptions(VersionCaps version, MigrateOnError[] values) { if (VersionUtils.greaterOrEqual(version, VERSION_3_0)) { version.setErrorHandling(new org.ovirt.engine.api.model.ErrorHandlingOptions()); for (MigrateOnError option : values) { version.getErrorHandling().getErrorHandling().add(option.value()); } } } private void addStorageFormatOptions(VersionCaps version, StorageFormat... formats) { if (VersionUtils.greaterOrEqual(version, VERSION_3_0)) { version.setStorageFormats(new StorageFormats()); for (StorageFormat format : formats) { version.getStorageFormats().getStorageFormats().add(format.value()); } } } private void addCreationStates(VersionCaps version, CreationStatus[] values) { version.setCreationStates(new CreationStates()); for (CreationStatus status : values) { version.getCreationStates().getCreationStates().add(status.value()); } } private void addDataCenterStates(VersionCaps version, DataCenterStatus[] values) { version.setDataCenterStates(new DataCenterStates()); for (DataCenterStatus status : values) { version.getDataCenterStates().getDataCenterStates().add(status.value()); } } private void addHostNICStates(VersionCaps version, NicStatus[] values) { version.setHostNicStates(new HostNICStates()); for (NicStatus status : values) { version.getHostNicStates().getHostNICStates().add(status.value()); } } private void addDiskStates(VersionCaps version, DiskStatus[] values) { version.setDiskStates(new DiskStates()); for (DiskStatus status : values) { version.getDiskStates().getDiskStates().add(status.value()); } } private void addVmStates(VersionCaps version, VmStatus[] values) { version.setVmStates(new VmStates()); for (VmStatus status : values) { version.getVmStates().getVmStates().add(status.value()); } } private void addVmPauseDetails(VersionCaps version, VmPauseStatus[] values) { version.setVmPauseDetails(new VmPauseDetails()); for (VmPauseStatus detail : values) { version.getVmPauseDetails().getVmPauseDetails().add(detail.name().toLowerCase()); } } private void addTemplateStates(VersionCaps version, TemplateStatus[] values) { version.setTemplateStates(new TemplateStates()); for (TemplateStatus status : values) { version.getTemplateStates().getTemplateStates().add(status.value()); } } private void addNetworkStates(VersionCaps version, NetworkStatus[] values) { version.setNetworkStates(new NetworkStates()); for (NetworkStatus status : values) { version.getNetworkStates().getNetworkStates().add(status.value()); } } private void addHostStates(VersionCaps version, HostStatus[] values) { version.setHostStates(new HostStates()); for (HostStatus status : values) { version.getHostStates().getHostStates().add(status.value()); } } private void addHostNonOperationalDetails(VersionCaps version, NonOperationalReason[] values) { version.setHostNonOperationalDetails(new HostNonOperationalDetails()); for (NonOperationalReason reason : values) { version.getHostNonOperationalDetails().getHostNonOperationalDetails().add(reason.name().toLowerCase()); } } private void addPowerManagementStateses(VersionCaps version, PowerManagementStatus[] values) { version.setPowerManagementStates(new PowerManagementStates()); for (PowerManagementStatus status : values) { version.getPowerManagementStates().getPowerManagementStates().add(status.value()); } } private void addStorageDomaintStates(VersionCaps version, StorageDomainStatus[] values) { version.setStorageDomainStates(new StorageDomainStates()); for (StorageDomainStatus status : values) { version.getStorageDomainStates().getStorageDomainStates().add(status.value()); } } private static final String VERSION_FORMAT = "{0}.{1}"; private String asString(Version version) { return MessageFormat.format(VERSION_FORMAT, version.getMajor(), version.getMinor()); } }