在实际应用中,需要显示出数据中心(Datacenter)、集群(ClusterComputeResource)、主机(HostSystem)、虚拟机(VirtualMachine)之间的目录关系。这里忽略VAPP以及APP。
正所谓无图无真相,先展示一张vSphere Client上的截图,以便形象的描述本文所要呈现的内容。
左边的目录树形象的展示了数据中心(Datacenter)、集群(ClusterComputeResource)、主机(HostSystem)、虚拟机(VirtualMachine)之间的目录关系。但是如何通过vSphere Webservice SDK进行获取相应的信息呢?
首先罗列本文所要展示的几个方法:
1. 根据主机名获取虚拟机的名称列表 |
public static List<String> getVmNameListByHostName(String hostName) throws Exception |
2. 根据集群名获取主机的名称列表 |
public static List<String> getHostNameListByClusterName(String clusterName) throws Exception |
3. 根据集群名获取虚拟机的名称列表 |
public static List<String> getVmNameListByClusterName(String clusterName) throws Exception |
4. 根据数据中心名获取主机名称列表 |
public static List<String> getHostNameListByDCName(String dcName) throws Exception |
5. 根据数据中心名获取虚拟机名称列表 |
public static List<String> getVmNameListByDCName(String dcName) throws Exception |
6. 根据数据中心名称获取集群(ClusterComputeResource)列表 |
public static List<String> getClusterNameListByDCName(String dcName) throws Exception |
首先根据主机名获取虚拟机的名称列表,这个比较简单,因为HostSystem有一个属性就是vm,关系一目了然。
根据主机名称遍历,获取匹配主机名称的记录,根据vm的属性名获取虚拟机的ArrayOfManagedObjectReference对象,然后通过:
List<ManagedObjectReference> vmTempList = ((ArrayOfManagedObjectReference)dp.getVal()).getManagedObjectReference();
获取每一个虚拟机的对象,最后根据虚拟机对象获得相应的名称。
同样,根据集群名获取主机名也是相同的。
下面展示出关键代码(所涉及的调用的方法如果未展示出来,可参考前面6篇同系列的博文,在其中会找到,如果真是本人疏忽遗漏,可在下方评论,我会尽快补上):
private static List<String> getNameListByName(String paraName, String paraObject, String paraProperty) throws Exception { List<String> list = new ArrayList<String>(); RetrieveResult props = getRetrieveResultObjectWithProperty(paraObject, paraProperty); List<ManagedObjectReference> vmList = null; if (props != null) { Boolean flag = false; if (paraProperty.compareToIgnoreCase("name") < 0) { for (ObjectContent oc : props.getObjects()) { if (flag == true) { break; } List<ManagedObjectReference> vmTempList = null; String path = null; List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { path = dp.getName(); if (path.equalsIgnoreCase(paraProperty)) { vmTempList = ((ArrayOfManagedObjectReference)dp.getVal()).getManagedObjectReference(); } if (path.equalsIgnoreCase("name")) { String value = (String) dp.getVal(); if (value.equals(paraName)) { flag = true; vmList = vmTempList; break; } } } } } } else { for (ObjectContent oc : props.getObjects()) { if (flag == true) { break; } String path = null; List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { path = dp.getName(); if (path.equalsIgnoreCase("name")) { String value = (String) dp.getVal(); if (value.equals(paraName)) { flag = true; } } if (path.equalsIgnoreCase(paraProperty)) { List<ManagedObjectReference> vmTempList = ((ArrayOfManagedObjectReference)dp.getVal()).getManagedObjectReference(); if (flag == true) { vmList = vmTempList; break; } } } } } } } if(vmList != null) { for(ManagedObjectReference mor:vmList) { String objectName = getObjectName(mor); if(objectName != null) { list.add(objectName); } } } return list; } public static List<String> getVmNameListByHostName(String hostName) throws Exception { return getNameListByName(hostName,"HostSystem","vm"); } public static List<String> getHostNameListByClusterName(String clusterName) throws Exception { return getNameListByName(clusterName,"ComputeResource","host"); }
在集群(ComputeResource)中没有像在HostSystem中有类似vm的虚拟机属性,但是我们可以根据集群获得主机,主机获得虚拟机的方式,获得一个虚拟机的列表,代码如下:
public static List<String> getVmNameListByClusterName(String clusterName) throws Exception { List<String> ansList = new ArrayList<String>(); List<String> hostList = getNameListByName(clusterName,"ComputeResource","host"); if(hostList != null) { for(String hostName : hostList) { List<String> vmList = null; if(hostName != null) { vmList = getVmNameListByHostName(hostName); } if(vmList != null) { for(String vmName : vmList) { if(vmName != null) { ansList.add(vmName); } } } } } return ansList; }
接下去,通过数据中心(Datacenter)获取集群、主机、虚拟机的列表就比较绕了。首先看一下Datacenter的api:
我们可以发现其中有hostFolder,vmFolder的属性,hostFolder对应的是集群和主机,而vmFolder对应的是虚拟机,所以这里我们可以先通过数据中心的名称获取其对应的hostFolder以及vmFolder的对象,然后通过遍历这些对象多去相应的关键属性。对于如何遍历对象,相信看过我前面几篇博文的朋友应该了解了,关键理解这幅图:
好了,直接上代码,希望各位朋友能够很快理解。
private static TraversalSpec getHostFolderTraversalSpec() { SelectionSpec ss = new SelectionSpec(); ss.setName("VisitFolders"); TraversalSpec computeResourceToHostSystem = new TraversalSpec(); computeResourceToHostSystem.setName("computeResourceToHostSystem"); computeResourceToHostSystem.setType("ComputeResource"); computeResourceToHostSystem.setPath("host"); computeResourceToHostSystem.setSkip(false); computeResourceToHostSystem.getSelectSet().add(ss); TraversalSpec hostFolderToComputeResource = new TraversalSpec(); hostFolderToComputeResource.setName("hostFolderToComputeResource"); hostFolderToComputeResource.setType("Folder"); hostFolderToComputeResource.setPath("childEntity"); hostFolderToComputeResource.setSkip(false); hostFolderToComputeResource.getSelectSet().add(ss); TraversalSpec traversalSpec = new TraversalSpec(); traversalSpec.setName("VisitFolders"); traversalSpec.setType("Folder"); traversalSpec.setPath("childEntity"); traversalSpec.setSkip(false); List<SelectionSpec> sSpecArr = new ArrayList<SelectionSpec>(); sSpecArr.add(ss); sSpecArr.add(hostFolderToComputeResource); sSpecArr.add(computeResourceToHostSystem); traversalSpec.getSelectSet().addAll(sSpecArr); return traversalSpec; } private static TraversalSpec getHostFolderOfComputeResourceTraversalSpec() { SelectionSpec ss = new SelectionSpec(); ss.setName("VisitFolders"); TraversalSpec hostFolderToComputeResource = new TraversalSpec(); hostFolderToComputeResource.setName("hostFolderToComputeResource"); hostFolderToComputeResource.setType("Folder"); hostFolderToComputeResource.setPath("childEntity"); hostFolderToComputeResource.setSkip(false); hostFolderToComputeResource.getSelectSet().add(ss); TraversalSpec traversalSpec = new TraversalSpec(); traversalSpec.setName("VisitFolders"); traversalSpec.setType("Folder"); traversalSpec.setPath("childEntity"); traversalSpec.setSkip(false); List<SelectionSpec> sSpecArr = new ArrayList<SelectionSpec>(); sSpecArr.add(ss); sSpecArr.add(hostFolderToComputeResource); traversalSpec.getSelectSet().addAll(sSpecArr); return traversalSpec; } private static TraversalSpec getVmFolderTraversalSpec() { TraversalSpec vAppToVM = new TraversalSpec(); vAppToVM.setName("vAppToVM"); vAppToVM.setType("VirtualApp"); vAppToVM.setPath("vm"); TraversalSpec vAppToVApp = new TraversalSpec(); vAppToVApp.setName("vAppToVApp"); vAppToVApp.setType("VirtualApp"); vAppToVApp.setPath("resourcePool"); SelectionSpec vAppRecursion = new SelectionSpec(); vAppRecursion.setName("vAppToVApp"); SelectionSpec vmInVApp = new SelectionSpec(); vmInVApp.setName("vAppToVM"); List<SelectionSpec> vAppToVMSS = new ArrayList<SelectionSpec>(); vAppToVMSS.add(vAppRecursion); vAppToVMSS.add(vmInVApp); vAppToVApp.getSelectSet().addAll(vAppToVMSS); SelectionSpec sSpec = new SelectionSpec(); sSpec.setName("VisitFolders"); TraversalSpec traversalSpec = new TraversalSpec(); traversalSpec.setName("VisitFolders"); traversalSpec.setType("Folder"); traversalSpec.setPath("childEntity"); traversalSpec.setSkip(false); List<SelectionSpec> sSpecArr = new ArrayList<SelectionSpec>(); sSpecArr.add(sSpec); sSpecArr.add(vAppToVM); sSpecArr.add(vAppToVApp); traversalSpec.getSelectSet().addAll(sSpecArr); return traversalSpec; } private static ManagedObjectReference getHostFolderObjectByDcName(String dcName) throws Exception { ManagedObjectReference hostFolder = null; RetrieveResult props = getRetrieveResultObjectWithProperty("Datacenter", "hostFolder"); if(props != null) { Boolean flag = false; for (ObjectContent oc : props.getObjects()) { if (flag == true) { break; } String path = null; List<DynamicProperty> dps = oc.getPropSet(); ManagedObjectReference mor = null; if (dps != null) { for (DynamicProperty dp : dps) { path = dp.getName(); if (path.equalsIgnoreCase("hostFolder")) { mor = (ManagedObjectReference)dp.getVal(); } if (path.equalsIgnoreCase("name")) { String value = (String) dp.getVal(); if (value.equals(dcName)) { flag = true; hostFolder = mor; break; } } } } } } return hostFolder; } private static ManagedObjectReference getVmFolderObjectByDcName(String dcName) throws Exception { ManagedObjectReference vmFolder = null; RetrieveResult props = getRetrieveResultObjectWithProperty("Datacenter", "vmFolder"); if(props != null) { Boolean flag = false; for (ObjectContent oc : props.getObjects()) { if (flag == true) { break; } String path = null; List<DynamicProperty> dps = oc.getPropSet(); ManagedObjectReference mor = null; if (dps != null) { for (DynamicProperty dp : dps) { path = dp.getName(); if (path.equalsIgnoreCase("name")) { String value = (String) dp.getVal(); if (value.equals(dcName)) { flag = true; } } if (path.equalsIgnoreCase("vmFolder")) { mor = (ManagedObjectReference)dp.getVal(); if(flag == true) { vmFolder = mor; break; } } } } } } return vmFolder; } private static List<String> getHostNamesByHostFolder(ManagedObjectReference hostFolder) throws Exception { List<String> list = new ArrayList<String>(); TraversalSpec tSpec = getHostFolderTraversalSpec(); PropertySpec propertySpec = new PropertySpec(); propertySpec.setAll(Boolean.FALSE); propertySpec.getPathSet().add("name"); propertySpec.setType("HostSystem"); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(hostFolder); objectSpec.setSkip(Boolean.TRUE); objectSpec.getSelectSet().add(tSpec); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.getPropSet().add(propertySpec); propertyFilterSpec.getObjectSet().add(objectSpec); List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1); listpfs.add(propertyFilterSpec); List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs); if (listobjcont != null) { for (ObjectContent oc : listobjcont) { String hostnm = null; List<DynamicProperty> listDynamicProps = oc.getPropSet(); DynamicProperty[] dps = listDynamicProps.toArray(new DynamicProperty[listDynamicProps.size()]); if (dps != null) { for (DynamicProperty dp : dps) { hostnm = (String) dp.getVal(); if (hostnm != null) { list.add(hostnm); } } } } } return list; } private static List<String> getClusterNamesByHostFolder(ManagedObjectReference hostFolder) throws Exception { List<String> list = new ArrayList<String>(); TraversalSpec tSpec = getHostFolderOfComputeResourceTraversalSpec(); PropertySpec propertySpec = new PropertySpec(); propertySpec.setAll(Boolean.FALSE); propertySpec.getPathSet().add("name"); propertySpec.setType("ClusterComputeResource"); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(hostFolder); objectSpec.setSkip(Boolean.TRUE); objectSpec.getSelectSet().add(tSpec); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.getPropSet().add(propertySpec); propertyFilterSpec.getObjectSet().add(objectSpec); List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1); listpfs.add(propertyFilterSpec); List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs); if (listobjcont != null) { for (ObjectContent oc : listobjcont) { String hostnm = null; List<DynamicProperty> listDynamicProps = oc.getPropSet(); DynamicProperty[] dps = listDynamicProps.toArray(new DynamicProperty[listDynamicProps.size()]); if (dps != null) { for (DynamicProperty dp : dps) { hostnm = (String) dp.getVal(); if (hostnm != null) { list.add(hostnm); } } } } } return list; } private static List<String> getVmNamesByVmFolder(ManagedObjectReference vmFolder) throws Exception { List<String> list = new ArrayList<String>(); TraversalSpec tSpec = getVmFolderTraversalSpec(); PropertySpec propertySpec = new PropertySpec(); propertySpec.setAll(Boolean.FALSE); propertySpec.getPathSet().add("name"); propertySpec.setType("VirtualMachine"); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(vmFolder); objectSpec.setSkip(Boolean.TRUE); objectSpec.getSelectSet().add(tSpec); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.getPropSet().add(propertySpec); propertyFilterSpec.getObjectSet().add(objectSpec); List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1); listpfs.add(propertyFilterSpec); List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs); if (listobjcont != null) { for (ObjectContent oc : listobjcont) { String vmName = null; List<DynamicProperty> listDynamicProps = oc.getPropSet(); DynamicProperty[] dps = listDynamicProps.toArray(new DynamicProperty[listDynamicProps.size()]); if (dps != null) { for (DynamicProperty dp : dps) { vmName = (String) dp.getVal(); if (vmName != null) { list.add(vmName); } } } } } return list; } public static List<String> getHostNameListByDCName(String dcName) throws Exception { ManagedObjectReference hostFolder = getHostFolderObjectByDcName(dcName); List<String> list = null; if(hostFolder != null) { list = getHostNamesByHostFolder(hostFolder); } return list; } public static List<String> getVmNameListByDCName(String dcName) throws Exception { List<String> list = null; ManagedObjectReference vmFolder = getVmFolderObjectByDcName(dcName); if(vmFolder != null) { list = getVmNamesByVmFolder(vmFolder); } return list; } public static List<String> getClusterNameListByDCName(String dcName) throws Exception { ManagedObjectReference hostFolder = getHostFolderObjectByDcName(dcName); List<String> list = null; if(hostFolder != null) { list = getClusterNamesByHostFolder(hostFolder); } return list; }
最后三个以public static修饰的方法就是通过数据中心的名称获取集群、主机、虚拟机的名称列表的方法。
如有疑问,欢迎提出。本文展示的代码都经过真实环境运行并投入使用中。