| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| package com.cloud.hypervisor.vmware.mo; |
| |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| import org.apache.commons.collections.CollectionUtils; |
| import org.apache.commons.lang3.StringUtils; |
| |
| import com.google.gson.Gson; |
| import com.vmware.vim25.ArrayOfHostIpRouteEntry; |
| import com.vmware.vim25.ArrayUpdateOperation; |
| import com.vmware.vim25.ClusterComputeResourceSummary; |
| import com.vmware.vim25.ClusterConfigInfoEx; |
| import com.vmware.vim25.ClusterDasConfigInfo; |
| import com.vmware.vim25.ClusterDasVmSettingsRestartPriority; |
| import com.vmware.vim25.ClusterHostRecommendation; |
| import com.vmware.vim25.ComputeResourceSummary; |
| import com.vmware.vim25.CustomFieldStringValue; |
| import com.vmware.vim25.DasVmPriority; |
| import com.vmware.vim25.DatastoreInfo; |
| import com.vmware.vim25.DynamicProperty; |
| import com.vmware.vim25.GuestOsDescriptor; |
| import com.vmware.vim25.HostHardwareSummary; |
| import com.vmware.vim25.HostIpRouteEntry; |
| import com.vmware.vim25.HostRuntimeInfo; |
| import com.vmware.vim25.HostSystemConnectionState; |
| import com.vmware.vim25.ManagedObjectReference; |
| import com.vmware.vim25.NasDatastoreInfo; |
| import com.vmware.vim25.ObjectContent; |
| import com.vmware.vim25.ObjectSpec; |
| import com.vmware.vim25.OptionValue; |
| import com.vmware.vim25.PropertyFilterSpec; |
| import com.vmware.vim25.PropertySpec; |
| import com.vmware.vim25.TraversalSpec; |
| import com.vmware.vim25.VirtualMachineConfigOption; |
| import com.vmware.vim25.VirtualMachineConfigSpec; |
| import com.vmware.vim25.ClusterDasVmConfigInfo; |
| import com.vmware.vim25.ClusterDasVmConfigSpec; |
| import com.vmware.vim25.ClusterDasVmSettings; |
| import com.vmware.vim25.ClusterConfigSpecEx; |
| |
| import com.cloud.hypervisor.vmware.util.VmwareContext; |
| import com.cloud.hypervisor.vmware.util.VmwareHelper; |
| import com.cloud.utils.Pair; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| |
| // |
| // interface. This has changed as ClusterMO no longer works as a special host anymore. Need to refactor accordingly |
| // |
| public class ClusterMO extends BaseMO implements VmwareHypervisorHost { |
| protected ManagedObjectReference _environmentBrowser = null; |
| |
| public ClusterMO(VmwareContext context, ManagedObjectReference morCluster) { |
| super(context, morCluster); |
| } |
| |
| public ClusterMO(VmwareContext context, String morType, String morValue) { |
| super(context, morType, morValue); |
| } |
| |
| @Override |
| public String getHyperHostName() throws Exception { |
| return getName(); |
| } |
| |
| @Override |
| public ClusterDasConfigInfo getDasConfig() throws Exception { |
| ClusterConfigInfoEx configInfo = getClusterConfigInfo(); |
| if (configInfo != null) { |
| // Note getDynamicProperty() with "configurationEx.dasConfig" does not work here because of that dasConfig is a property in subclass |
| return configInfo.getDasConfig(); |
| } |
| |
| return null; |
| } |
| |
| public ClusterConfigInfoEx getClusterConfigInfo() throws Exception { |
| ClusterConfigInfoEx configInfo = (ClusterConfigInfoEx)_context.getVimClient().getDynamicProperty(_mor, "configurationEx"); |
| return configInfo; |
| } |
| |
| @Override |
| public boolean isHAEnabled() throws Exception { |
| ClusterDasConfigInfo dasConfig = getDasConfig(); |
| if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| private String getRestartPriorityForVM(VirtualMachineMO vmMo) throws Exception { |
| if (vmMo == null) { |
| logger.debug("Failed to get restart priority for VM, invalid VM object reference"); |
| return null; |
| } |
| |
| ManagedObjectReference vmMor = vmMo.getMor(); |
| if (vmMor == null || !vmMor.getType().equals("VirtualMachine")) { |
| logger.debug("Failed to get restart priority for VM: " + vmMo.getName() + ", invalid VM object reference"); |
| return null; |
| } |
| |
| ClusterConfigInfoEx configInfo = getClusterConfigInfo(); |
| if (configInfo == null) { |
| logger.debug("Failed to get restart priority for VM: " + vmMo.getName() + ", no cluster config information"); |
| return null; |
| } |
| |
| List<ClusterDasVmConfigInfo> dasVmConfig = configInfo.getDasVmConfig(); |
| for (int dasVmConfigIndex = 0; dasVmConfigIndex < dasVmConfig.size(); dasVmConfigIndex++) { |
| ClusterDasVmConfigInfo dasVmConfigInfo = dasVmConfig.get(dasVmConfigIndex); |
| if (dasVmConfigInfo != null && dasVmConfigInfo.getKey().getValue().equals(vmMor.getValue())) { |
| DasVmPriority dasVmPriority = dasVmConfigInfo.getRestartPriority(); |
| if (dasVmPriority != null) { |
| return dasVmPriority.value(); |
| } else { |
| //VM uses cluster restart priority when DasVmPriority for the VM is null. |
| return ClusterDasVmSettingsRestartPriority.CLUSTER_RESTART_PRIORITY.value(); |
| } |
| } |
| } |
| |
| logger.debug("VM: " + vmMo.getName() + " uses default restart priority in the cluster: " + getName()); |
| return null; |
| } |
| |
| @Override |
| public void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception { |
| if (vmMo == null || StringUtils.isBlank(priority)) { |
| return; |
| } |
| |
| if (!isHAEnabled()) { |
| logger.debug("Couldn't set restart priority for VM: " + vmMo.getName() + ", HA disabled in the cluster"); |
| return; |
| } |
| |
| ManagedObjectReference vmMor = vmMo.getMor(); |
| if (vmMor == null || !vmMor.getType().equals("VirtualMachine")) { |
| logger.debug("Failed to set restart priority for VM: " + vmMo.getName() + ", invalid VM object reference"); |
| return; |
| } |
| |
| String currentVmRestartPriority = getRestartPriorityForVM(vmMo); |
| if (StringUtils.isNotBlank(currentVmRestartPriority) && currentVmRestartPriority.equalsIgnoreCase(priority)) { |
| return; |
| } |
| |
| ClusterDasVmSettings clusterDasVmSettings = new ClusterDasVmSettings(); |
| clusterDasVmSettings.setRestartPriority(priority); |
| |
| ClusterDasVmConfigInfo clusterDasVmConfigInfo = new ClusterDasVmConfigInfo(); |
| clusterDasVmConfigInfo.setKey(vmMor); |
| clusterDasVmConfigInfo.setDasSettings(clusterDasVmSettings); |
| |
| ClusterDasVmConfigSpec clusterDasVmConfigSpec = new ClusterDasVmConfigSpec(); |
| clusterDasVmConfigSpec.setOperation((StringUtils.isNotBlank(currentVmRestartPriority)) ? ArrayUpdateOperation.EDIT : ArrayUpdateOperation.ADD); |
| clusterDasVmConfigSpec.setInfo(clusterDasVmConfigInfo); |
| |
| ClusterConfigSpecEx clusterConfigSpecEx = new ClusterConfigSpecEx(); |
| ClusterDasConfigInfo clusterDasConfigInfo = new ClusterDasConfigInfo(); |
| clusterConfigSpecEx.setDasConfig(clusterDasConfigInfo); |
| clusterConfigSpecEx.getDasVmConfigSpec().add(clusterDasVmConfigSpec); |
| |
| ManagedObjectReference morTask = _context.getService().reconfigureComputeResourceTask(_mor, clusterConfigSpecEx, true); |
| |
| boolean result = _context.getVimClient().waitForTask(morTask); |
| |
| if (result) { |
| _context.waitForTaskProgressDone(morTask); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - setRestartPriority done(successfully)"); |
| } else { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - setRestartPriority done(failed)"); |
| logger.error("Set restart priority failed for VM: " + vmMo.getName() + " due to " + TaskMO.getTaskFailureInfo(_context, morTask)); |
| } |
| } |
| |
| @Override |
| public ManagedObjectReference getHyperHostDatacenter() throws Exception { |
| Pair<DatacenterMO, String> dcPair = DatacenterMO.getOwnerDatacenter(getContext(), getMor()); |
| assert (dcPair != null); |
| return dcPair.first().getMor(); |
| } |
| |
| @Override |
| public ManagedObjectReference getHyperHostOwnerResourcePool() throws Exception { |
| return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(getMor(), "resourcePool"); |
| } |
| |
| @Override |
| public ManagedObjectReference getHyperHostCluster() throws Exception { |
| return _mor; |
| } |
| |
| @Override |
| public synchronized List<VirtualMachineMO> listVmsOnHyperHostWithHypervisorName(String vmName) throws Exception { |
| List<VirtualMachineMO> vms = new ArrayList<>(); |
| List<ManagedObjectReference> hosts = _context.getVimClient().getDynamicProperty(_mor, "host"); |
| if (CollectionUtils.isNotEmpty(hosts)) { |
| for (ManagedObjectReference morHost : hosts) { |
| HostMO hostMo = new HostMO(_context, morHost); |
| vms.addAll(hostMo.listVmsOnHyperHostWithHypervisorName(vmName)); |
| } |
| } |
| return vms; |
| } |
| |
| @Override |
| public VirtualMachineMO findVmOnHyperHost(String name) throws Exception { |
| |
| int key = getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME); |
| if (key == 0) { |
| logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!"); |
| } |
| |
| String instanceNameCustomField = "value[" + key + "]"; |
| ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", instanceNameCustomField}); |
| return HypervisorHostHelper.findVmFromObjectContent(_context, ocs, name, instanceNameCustomField); |
| } |
| |
| @Override |
| public VirtualMachineMO findVmOnPeerHyperHost(String name) throws Exception { |
| int key = getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME); |
| if (key == 0) { |
| logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!"); |
| } |
| |
| String instanceNameCustomField = "value[" + key + "]"; |
| |
| ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", instanceNameCustomField}); |
| return HypervisorHostHelper.findVmFromObjectContent(_context, ocs, name, instanceNameCustomField); |
| } |
| |
| @Override |
| public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - retrieveProperties() for VM properties. target MOR: " + _mor.getValue() + ", properties: " + new Gson().toJson(propertyPaths)); |
| |
| PropertySpec pSpec = new PropertySpec(); |
| pSpec.setType("VirtualMachine"); |
| pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); |
| |
| TraversalSpec host2VmFolderTraversal = new TraversalSpec(); |
| host2VmFolderTraversal.setType("HostSystem"); |
| host2VmFolderTraversal.setPath("vm"); |
| host2VmFolderTraversal.setName("host2VmFolderTraversal"); |
| |
| TraversalSpec cluster2HostFolderTraversal = new TraversalSpec(); |
| cluster2HostFolderTraversal.setType("ClusterComputeResource"); |
| cluster2HostFolderTraversal.setPath("host"); |
| cluster2HostFolderTraversal.setName("cluster2HostFolderTraversal"); |
| cluster2HostFolderTraversal.getSelectSet().add(host2VmFolderTraversal); |
| |
| ObjectSpec oSpec = new ObjectSpec(); |
| oSpec.setObj(getMor()); |
| oSpec.setSkip(Boolean.TRUE); |
| oSpec.getSelectSet().add(cluster2HostFolderTraversal); |
| |
| PropertyFilterSpec pfSpec = new PropertyFilterSpec(); |
| pfSpec.getPropSet().add(pSpec); |
| pfSpec.getObjectSet().add(oSpec); |
| List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>(); |
| pfSpecArr.add(pfSpec); |
| |
| List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - retrieveProperties() done"); |
| return properties.toArray(new ObjectContent[properties.size()]); |
| } |
| |
| @Override |
| public ObjectContent[] getDatastorePropertiesOnHyperHost(String[] propertyPaths) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - retrieveProperties() on Datastore properties. target MOR: " + _mor.getValue() + ", properties: " + new Gson().toJson(propertyPaths)); |
| |
| PropertySpec pSpec = new PropertySpec(); |
| pSpec.setType("Datastore"); |
| pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); |
| |
| TraversalSpec cluster2DatastoreTraversal = new TraversalSpec(); |
| cluster2DatastoreTraversal.setType("ClusterComputeResource"); |
| cluster2DatastoreTraversal.setPath("datastore"); |
| cluster2DatastoreTraversal.setName("cluster2DatastoreTraversal"); |
| |
| ObjectSpec oSpec = new ObjectSpec(); |
| oSpec.setObj(_mor); |
| oSpec.setSkip(Boolean.TRUE); |
| oSpec.getSelectSet().add(cluster2DatastoreTraversal); |
| |
| PropertyFilterSpec pfSpec = new PropertyFilterSpec(); |
| pfSpec.getPropSet().add(pSpec); |
| pfSpec.getObjectSet().add(oSpec); |
| List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>(); |
| pfSpecArr.add(pfSpec); |
| |
| List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - retrieveProperties() done"); |
| return properties.toArray(new ObjectContent[properties.size()]); |
| } |
| |
| public ObjectContent[] getHostPropertiesOnCluster(String[] propertyPaths) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - retrieveProperties() on Host properties. target MOR: " + _mor.getValue() + ", properties: " + new Gson().toJson(propertyPaths)); |
| |
| PropertySpec pSpec = new PropertySpec(); |
| pSpec.setType("HostSystem"); |
| pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); |
| |
| TraversalSpec cluster2HostTraversal = new TraversalSpec(); |
| cluster2HostTraversal.setType("ClusterComputeResource"); |
| cluster2HostTraversal.setPath("host"); |
| cluster2HostTraversal.setName("cluster2HostTraversal"); |
| |
| ObjectSpec oSpec = new ObjectSpec(); |
| oSpec.setObj(_mor); |
| oSpec.setSkip(Boolean.TRUE); |
| oSpec.getSelectSet().add(cluster2HostTraversal); |
| |
| PropertyFilterSpec pfSpec = new PropertyFilterSpec(); |
| pfSpec.getPropSet().add(pSpec); |
| pfSpec.getObjectSet().add(oSpec); |
| |
| List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>(); |
| pfSpecArr.add(pfSpec); |
| |
| List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - retrieveProperties() done"); |
| return properties.toArray(new ObjectContent[properties.size()]); |
| } |
| |
| @Override |
| public boolean createVm(VirtualMachineConfigSpec vmSpec) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - createVM_Task(). target MOR: " + _mor.getValue() + ", VirtualMachineConfigSpec: " + new Gson().toJson(vmSpec)); |
| |
| assert (vmSpec != null); |
| DatacenterMO dcMo = new DatacenterMO(_context, getHyperHostDatacenter()); |
| ManagedObjectReference morPool = getHyperHostOwnerResourcePool(); |
| |
| ManagedObjectReference morTask = _context.getService().createVMTask(dcMo.getVmFolder(), vmSpec, morPool, null); |
| boolean result = _context.getVimClient().waitForTask(morTask); |
| |
| if (result) { |
| _context.waitForTaskProgressDone(morTask); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - createVM_Task() done(successfully)"); |
| return true; |
| } else { |
| logger.error("VMware createVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); |
| } |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - createVM_Task() done(failed)"); |
| return false; |
| } |
| |
| @Override |
| public void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, String configurationId) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - importVmFromOVF(). target MOR: " + _mor.getValue() + ", ovfFilePath: " + ovfFilePath + ", vmName: " + vmName + |
| ", datastore: " + dsMo.getMor().getValue() + ", diskOption: " + diskOption); |
| |
| ManagedObjectReference morRp = getHyperHostOwnerResourcePool(); |
| assert (morRp != null); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - importVmFromOVF(). resource pool: " + morRp.getValue()); |
| |
| HypervisorHostHelper.importVmFromOVF(this, ovfFilePath, vmName, dsMo, diskOption, morRp, null, configurationId); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - importVmFromOVF() done"); |
| } |
| |
| @Override |
| public boolean createBlankVm(String vmName, String vmInternalCSName, int cpuCount, int cpuSpeedMHz, int cpuReservedMHz, boolean limitCpuUse, int memoryMB, |
| int memoryReserveMB, String guestOsIdentifier, ManagedObjectReference morDs, boolean snapshotDirToParent, Pair<String, String> controllerInfo, Boolean systemVm) throws Exception { |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - createBlankVm(). target MOR: " + _mor.getValue() + ", vmName: " + vmName + ", cpuCount: " + cpuCount + ", cpuSpeedMhz: " + |
| cpuSpeedMHz + ", cpuReservedMHz: " + cpuReservedMHz + ", limitCpu: " + limitCpuUse + ", memoryMB: " + memoryMB + ", guestOS: " + guestOsIdentifier + |
| ", datastore: " + morDs.getValue() + ", snapshotDirToParent: " + snapshotDirToParent); |
| |
| boolean result = |
| HypervisorHostHelper.createBlankVm(this, vmName, vmInternalCSName, cpuCount, cpuSpeedMHz, cpuReservedMHz, limitCpuUse, memoryMB, memoryReserveMB, |
| guestOsIdentifier, morDs, snapshotDirToParent, controllerInfo, systemVm); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - createBlankVm() done"); |
| |
| return result; |
| } |
| |
| @Override |
| public ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid, boolean createBaseFolder) throws Exception { |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - mountDatastore(). target MOR: " + _mor.getValue() + ", vmfs: " + vmfsDatastore + ", poolHost: " + poolHostAddress + |
| ", poolHostPort: " + poolHostPort + ", poolPath: " + poolPath + ", poolUuid: " + poolUuid); |
| |
| ManagedObjectReference morDs = null; |
| ManagedObjectReference morDsFirst = null; |
| List<ManagedObjectReference> hosts = _context.getVimClient().getDynamicProperty(_mor, "host"); |
| if (hosts != null && hosts.size() > 0) { |
| for (ManagedObjectReference morHost : hosts) { |
| HostMO hostMo = new HostMO(_context, morHost); |
| morDs = hostMo.mountDatastore(vmfsDatastore, poolHostAddress, poolHostPort, poolPath, poolUuid, true); |
| if (morDsFirst == null) |
| morDsFirst = morDs; |
| |
| // assume datastore is in scope of datacenter |
| assert (morDsFirst.getValue().equals(morDs.getValue())); |
| } |
| } |
| |
| if (morDs == null) { |
| String msg = "Failed to mount datastore in all hosts within the cluster"; |
| logger.error(msg); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - mountDatastore() done(failed)"); |
| throw new Exception(msg); |
| } |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - mountDatastore() done(successfully)"); |
| |
| return morDs; |
| } |
| |
| @Override |
| public void unmountDatastore(String poolUuid) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - unmountDatastore(). target MOR: " + _mor.getValue() + ", poolUuid: " + poolUuid); |
| |
| List<ManagedObjectReference> hosts = _context.getVimClient().getDynamicProperty(_mor, "host"); |
| if (hosts != null && hosts.size() > 0) { |
| for (ManagedObjectReference morHost : hosts) { |
| HostMO hostMo = new HostMO(_context, morHost); |
| hostMo.unmountDatastore(poolUuid); |
| } |
| } |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - unmountDatastore() done"); |
| } |
| |
| @Override |
| public ManagedObjectReference findDatastore(String poolUuid) throws Exception { |
| logger.trace(String.format("Searching datastore in target MOR [%s] with poolUuid [%s].", _mor.getValue(), poolUuid)); |
| |
| CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager()); |
| int key = cfmMo.getCustomFieldKey("Datastore", CustomFieldConstants.CLOUD_UUID); |
| assert (key != 0); |
| |
| ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {"name", String.format("value[%d]", key)}); |
| if (ocs != null) { |
| for (ObjectContent oc : ocs) { |
| if (oc.getPropSet().get(0).getVal().equals(poolUuid)) { |
| logger.trace(String.format("Found datastore [%s] in target MOR [%s].", oc.getObj(), _mor.getValue())); |
| return oc.getObj(); |
| } |
| if (oc.getPropSet().size() > 1) { |
| DynamicProperty prop = oc.getPropSet().get(1); |
| if (prop != null && prop.getVal() != null) { |
| if (prop.getVal() instanceof CustomFieldStringValue) { |
| String val = ((CustomFieldStringValue)prop.getVal()).getValue(); |
| if (val.equalsIgnoreCase(poolUuid)) { |
| logger.trace(String.format("Found datastore [%s] in target MOR [%s].", oc.getObj(), _mor.getValue())); |
| return oc.getObj(); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| logger.trace(String.format("Failed to find a datastore with UUID [%s].", poolUuid)); |
| return null; |
| } |
| |
| @Override |
| public ManagedObjectReference findDatastoreByName(String datastoreName) throws Exception { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public ManagedObjectReference findDatastoreByExportPath(String exportPath) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - findDatastoreByExportPath(). target MOR: " + _mor.getValue() + ", exportPath: " + exportPath); |
| |
| ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {"info"}); |
| if (ocs != null && ocs.length > 0) { |
| for (ObjectContent oc : ocs) { |
| DatastoreInfo dsInfo = (DatastoreInfo)oc.getPropSet().get(0).getVal(); |
| if (dsInfo != null && dsInfo instanceof NasDatastoreInfo) { |
| NasDatastoreInfo info = (NasDatastoreInfo)dsInfo; |
| if (info != null) { |
| String vmwareUrl = info.getUrl(); |
| if (vmwareUrl.charAt(vmwareUrl.length() - 1) == '/') |
| vmwareUrl = vmwareUrl.substring(0, vmwareUrl.length() - 1); |
| |
| URI uri = new URI(vmwareUrl); |
| if (uri.getPath().equals("/" + exportPath)) { |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - findDatastoreByExportPath() done(successfully)"); |
| return oc.getObj(); |
| } |
| } |
| } |
| } |
| } |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - findDatastoreByExportPath() done(failed)"); |
| return null; |
| } |
| |
| @Override |
| public ManagedObjectReference findMigrationTarget(VirtualMachineMO vmMo) throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - findMigrationTarget(). target MOR: " + _mor.getValue() + ", vm: " + vmMo.getName()); |
| |
| List<ClusterHostRecommendation> candidates = recommendHostsForVm(vmMo); |
| if (candidates != null && candidates.size() > 0) { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - findMigrationTarget() done(successfully)"); |
| return candidates.get(0).getHost(); |
| } |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - findMigrationTarget() done(failed)"); |
| return null; |
| } |
| |
| @Override |
| public boolean isHyperHostConnected() throws Exception { |
| ObjectContent[] ocs = getHostPropertiesOnCluster(new String[] {"runtime"}); |
| if (ocs != null && ocs.length > 0) { |
| for (ObjectContent oc : ocs) { |
| HostRuntimeInfo runtimeInfo = (HostRuntimeInfo)oc.getPropSet().get(0).getVal(); |
| // as long as we have one host connected, we assume the cluster is up |
| if (runtimeInfo.getConnectionState() == HostSystemConnectionState.CONNECTED) |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public String getHyperHostDefaultGateway() throws Exception { |
| ObjectContent[] ocs = getHostPropertiesOnCluster(new String[] {"config.network.routeTableInfo.ipRoute"}); |
| if (ocs != null && ocs.length > 0) { |
| for (ObjectContent oc : ocs) { |
| ArrayOfHostIpRouteEntry entries = (ArrayOfHostIpRouteEntry)oc.getPropSet().get(0).getVal(); |
| if (entries != null) { |
| for (HostIpRouteEntry entry : entries.getHostIpRouteEntry()) { |
| if (entry.getNetwork().equalsIgnoreCase("0.0.0.0")) |
| return entry.getGateway(); |
| } |
| } |
| } |
| } |
| |
| throw new Exception("Could not find host default gateway, host is not properly configured?"); |
| } |
| |
| @Override |
| public VmwareHypervisorHostResourceSummary getHyperHostResourceSummary() throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostResourceSummary(). target MOR: " + _mor.getValue()); |
| |
| VmwareHypervisorHostResourceSummary summary = new VmwareHypervisorHostResourceSummary(); |
| |
| ComputeResourceSummary vmwareSummary = (ComputeResourceSummary)_context.getVimClient().getDynamicProperty(_mor, "summary"); |
| |
| // TODO, need to use traversal to optimize retrieve of |
| int cpuNumInCpuThreads = 1; |
| List<ManagedObjectReference> hosts = _context.getVimClient().getDynamicProperty(_mor, "host"); |
| if (hosts != null && hosts.size() > 0) { |
| for (ManagedObjectReference morHost : hosts) { |
| HostMO hostMo = new HostMO(_context, morHost); |
| HostHardwareSummary hardwareSummary = hostMo.getHostHardwareSummary(); |
| |
| if (hardwareSummary.getNumCpuCores() * hardwareSummary.getNumCpuThreads() > cpuNumInCpuThreads) |
| cpuNumInCpuThreads = hardwareSummary.getNumCpuCores() * hardwareSummary.getNumCpuThreads(); |
| } |
| } |
| summary.setCpuCount(cpuNumInCpuThreads); |
| summary.setCpuSpeed(vmwareSummary.getTotalCpu()); |
| summary.setMemoryBytes(vmwareSummary.getTotalMemory()); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostResourceSummary() done"); |
| return summary; |
| } |
| |
| @Override |
| public VmwareHypervisorHostNetworkSummary getHyperHostNetworkSummary(String esxServiceConsolePort) throws Exception { |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostNetworkSummary(). target MOR: " + _mor.getValue() + ", mgmtPortgroup: " + esxServiceConsolePort); |
| |
| List<ManagedObjectReference> hosts = _context.getVimClient().getDynamicProperty(_mor, "host"); |
| if (hosts != null && hosts.size() > 0) { |
| VmwareHypervisorHostNetworkSummary summary = new HostMO(_context, hosts.get(0)).getHyperHostNetworkSummary(esxServiceConsolePort); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostResourceSummary() done(successfully)"); |
| return summary; |
| } |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostResourceSummary() done(failed)"); |
| return null; |
| } |
| |
| @Override |
| public ComputeResourceSummary getHyperHostHardwareSummary() throws Exception { |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostHardwareSummary(). target MOR: " + _mor.getValue()); |
| |
| ClusterComputeResourceSummary hardwareSummary = (ClusterComputeResourceSummary)_context.getVimClient().getDynamicProperty(_mor, "summary"); |
| |
| if (logger.isTraceEnabled()) |
| logger.trace("vCenter API trace - getHyperHostHardwareSummary() done"); |
| return hardwareSummary; |
| } |
| |
| public List<ClusterHostRecommendation> recommendHostsForVm(VirtualMachineMO vmMo) throws Exception { |
| return _context.getService().recommendHostsForVm(_mor, vmMo.getMor(), getHyperHostOwnerResourcePool()); |
| } |
| |
| public List<Pair<ManagedObjectReference, String>> getClusterHosts() throws Exception { |
| List<Pair<ManagedObjectReference, String>> hosts = new ArrayList<Pair<ManagedObjectReference, String>>(); |
| |
| ObjectContent[] ocs = getHostPropertiesOnCluster(new String[] {"name"}); |
| if (ocs != null) { |
| for (ObjectContent oc : ocs) { |
| ManagedObjectReference morHost = oc.getObj(); |
| String name = (String)oc.getPropSet().get(0).getVal(); |
| |
| hosts.add(new Pair<ManagedObjectReference, String>(morHost, name)); |
| } |
| } |
| return hosts; |
| } |
| |
| public HashMap<String, Integer> getVmVncPortsOnCluster() throws Exception { |
| ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", "config.extraConfig[\"RemoteDisplay.vnc.port\"]"}); |
| |
| HashMap<String, Integer> portInfo = new HashMap<String, Integer>(); |
| if (ocs != null && ocs.length > 0) { |
| for (ObjectContent oc : ocs) { |
| List<DynamicProperty> objProps = oc.getPropSet(); |
| if (objProps != null) { |
| String name = null; |
| String value = null; |
| for (DynamicProperty objProp : objProps) { |
| if (objProp.getName().equals("name")) { |
| name = (String)objProp.getVal(); |
| } else { |
| OptionValue optValue = (OptionValue)objProp.getVal(); |
| value = (String)optValue.getValue(); |
| } |
| } |
| |
| if (name != null && value != null) { |
| portInfo.put(name, Integer.parseInt(value)); |
| } |
| } |
| } |
| } |
| |
| return portInfo; |
| } |
| |
| @Override |
| public LicenseAssignmentManagerMO getLicenseAssignmentManager() throws Exception { |
| // LicenseAssignmentManager deals with only host/vcenter licenses only. Has nothing todo with cluster |
| throw new CloudRuntimeException("Unable to get LicenseAssignmentManager at cluster level"); |
| } |
| private ManagedObjectReference getEnvironmentBrowser() throws Exception { |
| if (_environmentBrowser == null) { |
| _environmentBrowser = _context.getVimClient().getMoRefProp(_mor, "environmentBrowser"); |
| } |
| return _environmentBrowser; |
| } |
| @Override |
| public String getRecommendedDiskController(String guestOsId) throws Exception { |
| VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null); |
| GuestOsDescriptor guestOsDescriptor = null; |
| String diskController = null; |
| List<GuestOsDescriptor> guestDescriptors = vmConfigOption.getGuestOSDescriptor(); |
| for (GuestOsDescriptor descriptor : guestDescriptors) { |
| if (guestOsId != null && guestOsId.equalsIgnoreCase(descriptor.getId())) { |
| guestOsDescriptor = descriptor; |
| break; |
| } |
| } |
| if (guestOsDescriptor != null) { |
| diskController = VmwareHelper.getRecommendedDiskControllerFromDescriptor(guestOsDescriptor); |
| logger.debug("Retrieved recommended disk controller for guest OS : " + guestOsId + " in cluster " + getHyperHostName() + " : " + diskController); |
| return diskController; |
| } else { |
| String msg = "Unable to retrieve recommended disk controller for guest OS : " + guestOsId + " in cluster " + getHyperHostName(); |
| logger.error(msg); |
| throw new CloudRuntimeException(msg); |
| } |
| } |
| |
| @Override |
| public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception { |
| VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null); |
| List<GuestOsDescriptor> guestDescriptors = vmConfigOption.getGuestOSDescriptor(); |
| for (GuestOsDescriptor descriptor : guestDescriptors) { |
| if (guestOsId != null && guestOsId.equalsIgnoreCase(descriptor.getId())) { |
| return descriptor; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public List<GuestOsDescriptor> getGuestOsDescriptors() throws Exception { |
| VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null); |
| return vmConfigOption.getGuestOSDescriptor(); |
| } |
| } |