From d66690fe828ea10848892feb239a1f2f3f02cb4e Mon Sep 17 00:00:00 2001 From: Nicolas Vazquez Date: Tue, 7 Jul 2020 04:13:41 -0300 Subject: [PATCH] vmware: Explicitly controlling VMware VM hardware version (#4117) Set the VM hardware version on new VM deployments as set by the administrator on vCenter at cluster or datacenter level by the 'Edit Default VM Compatibility' action. On VM deployments: - Check cluster level VM hardware version If it is set, then is used as the new VM hardware version - If cluster level VM hardware version not set, check the datacenter VM hardware version. If it is set, then it is used as the new VM hardware version. - If both cluster or datacenter VM hardware version not set, then VM hardware version not set for the new VM --- .../cloud/hypervisor/vmware/mo/ClusterMO.java | 2 +- .../hypervisor/vmware/mo/DatacenterMO.java | 6 +++ .../vmware/mo/HypervisorHostHelper.java | 28 ++++++++++++ .../vmware/mo/HypervisorHostHelperTest.java | 44 ++++++++++++++++++- 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java index 4b378664622..b8afdc84cfd 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java @@ -94,7 +94,7 @@ public class ClusterMO extends BaseMO implements VmwareHypervisorHost { return null; } - private ClusterConfigInfoEx getClusterConfigInfo() throws Exception { + public ClusterConfigInfoEx getClusterConfigInfo() throws Exception { ClusterConfigInfoEx configInfo = (ClusterConfigInfoEx)_context.getVimClient().getDynamicProperty(_mor, "configurationEx"); return configInfo; } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index 38b1565ca20..b0b91fb7d5b 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -24,6 +24,7 @@ import java.util.List; import org.apache.log4j.Logger; import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.DatacenterConfigInfo; import com.vmware.vim25.DVPortgroupConfigInfo; import com.vmware.vim25.DistributedVirtualSwitchPortConnection; import com.vmware.vim25.DynamicProperty; @@ -508,4 +509,9 @@ public class DatacenterMO extends BaseMO { CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager()); return cfmMo.ensureCustomFieldDef("Datacenter", fieldName) > 0; } + + public DatacenterConfigInfo getDatacenterConfigInfo() throws Exception { + DatacenterConfigInfo configInfo = (DatacenterConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "configuration"); + return configInfo; + } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index 7826bb136a8..d9604ac01e2 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -73,6 +73,8 @@ import com.vmware.vim25.OvfCreateDescriptorResult; import com.vmware.vim25.AlreadyExistsFaultMsg; import com.vmware.vim25.BoolPolicy; import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.ClusterConfigInfoEx; +import com.vmware.vim25.DatacenterConfigInfo; import com.vmware.vim25.DVPortSetting; import com.vmware.vim25.DVPortgroupConfigInfo; import com.vmware.vim25.DVPortgroupConfigSpec; @@ -1520,6 +1522,10 @@ public class HypervisorHostHelper { vmConfig.getDeviceChange().add(videoDeviceSpec); + ClusterMO clusterMo = new ClusterMO(host.getContext(), host.getHyperHostCluster()); + DatacenterMO dataCenterMo = new DatacenterMO(host.getContext(), host.getHyperHostDatacenter()); + setVMHardwareVersion(vmConfig, clusterMo, dataCenterMo); + if (host.createVm(vmConfig)) { // Here, when attempting to find the VM, we need to use the name // with which we created it. This is the only such place where @@ -1548,6 +1554,28 @@ public class HypervisorHostHelper { return false; } + /** + * Set the VM hardware version based on the information retrieved by the cluster and datacenter: + * - If the cluster hardware version is set, then it is set to this hardware version on vmConfig + * - If the cluster hardware version is not set, check datacenter hardware version. If it is set, then it is set to vmConfig + * - In case both cluster and datacenter hardware version are not set, hardware version is not set to vmConfig + */ + protected static void setVMHardwareVersion(VirtualMachineConfigSpec vmConfig, ClusterMO clusterMO, DatacenterMO datacenterMO) throws Exception { + ClusterConfigInfoEx clusterConfigInfo = clusterMO != null ? clusterMO.getClusterConfigInfo() : null; + String clusterHardwareVersion = clusterConfigInfo != null ? clusterConfigInfo.getDefaultHardwareVersionKey() : null; + if (StringUtils.isNotBlank(clusterHardwareVersion)) { + s_logger.debug("Cluster hardware version found: " + clusterHardwareVersion + ". Creating VM with this hardware version"); + vmConfig.setVersion(clusterHardwareVersion); + } else { + DatacenterConfigInfo datacenterConfigInfo = datacenterMO != null ? datacenterMO.getDatacenterConfigInfo() : null; + String datacenterHardwareVersion = datacenterConfigInfo != null ? datacenterConfigInfo.getDefaultHardwareVersionKey() : null; + if (StringUtils.isNotBlank(datacenterHardwareVersion)) { + s_logger.debug("Datacenter hardware version found: " + datacenterHardwareVersion + ". Creating VM with this hardware version"); + vmConfig.setVersion(datacenterHardwareVersion); + } + } + } + private static VirtualDeviceConfigSpec getControllerSpec(String diskController, int busNum) { VirtualDeviceConfigSpec controllerSpec = new VirtualDeviceConfigSpec(); VirtualController controller = null; diff --git a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java index 545104d91fc..bcd1febe872 100644 --- a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java +++ b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java @@ -23,6 +23,8 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; import java.util.HashMap; import java.util.Map; @@ -39,6 +41,9 @@ import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.offering.NetworkOffering; import com.vmware.vim25.AboutInfo; import com.vmware.vim25.BoolPolicy; +import com.vmware.vim25.ClusterConfigInfoEx; +import com.vmware.vim25.DatacenterConfigInfo; +import com.vmware.vim25.VirtualMachineConfigSpec; import com.vmware.vim25.DVPortgroupConfigInfo; import com.vmware.vim25.DVPortgroupConfigSpec; import com.vmware.vim25.DVSSecurityPolicy; @@ -62,6 +67,16 @@ public class HypervisorHostHelperTest { ServiceContent serviceContent; @Mock AboutInfo aboutInfo; + @Mock + private VirtualMachineConfigSpec vmSpec; + @Mock + private ClusterMO clusterMO; + @Mock + private DatacenterMO datacenterMO; + @Mock + private ClusterConfigInfoEx clusterConfigInfo; + @Mock + private DatacenterConfigInfo datacenterConfigInfo; String vSwitchName; Integer networkRateMbps; @@ -70,10 +85,12 @@ public class HypervisorHostHelperTest { String svlanId = null; @Before - public void setup() { + public void setup() throws Exception { MockitoAnnotations.initMocks(this); when(context.getServiceContent()).thenReturn(serviceContent); when(serviceContent.getAbout()).thenReturn(aboutInfo); + when(clusterMO.getClusterConfigInfo()).thenReturn(clusterConfigInfo); + when(datacenterMO.getDatacenterConfigInfo()).thenReturn(datacenterConfigInfo); } @BeforeClass @@ -883,4 +900,29 @@ public class HypervisorHostHelperTest { assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getStart() == 0); assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getEnd() == 0); } + + @Test + public void testSetVMHardwareVersionClusterLevel() throws Exception { + when(clusterConfigInfo.getDefaultHardwareVersionKey()).thenReturn("vmx-11"); + when(datacenterConfigInfo.getDefaultHardwareVersionKey()).thenReturn("vmx-9"); + HypervisorHostHelper.setVMHardwareVersion(vmSpec, clusterMO, datacenterMO); + verify(vmSpec).setVersion("vmx-11"); + verify(vmSpec, never()).setVersion("vmx-9"); + } + + @Test + public void testSetVMHardwareVersionDatacenterLevel() throws Exception { + when(clusterConfigInfo.getDefaultHardwareVersionKey()).thenReturn(null); + when(datacenterConfigInfo.getDefaultHardwareVersionKey()).thenReturn("vmx-9"); + HypervisorHostHelper.setVMHardwareVersion(vmSpec, clusterMO, datacenterMO); + verify(vmSpec).setVersion("vmx-9"); + } + + @Test + public void testSetVMHardwareVersionUnset() throws Exception { + when(clusterConfigInfo.getDefaultHardwareVersionKey()).thenReturn(null); + when(datacenterConfigInfo.getDefaultHardwareVersionKey()).thenReturn(null); + HypervisorHostHelper.setVMHardwareVersion(vmSpec, clusterMO, datacenterMO); + verify(vmSpec, never()).setVersion(any()); + } }