使用VMware VSphere WebService SDK进行开发 (七)——获取数据中心、集群、主机、虚拟机的目录结构

使用VMware VSphere WebService SDK进行开发 (七)——获取数据中心、集群、主机、虚拟机的目录结构

在实际应用中,需要显示出数据中心(Datacenter)、集群(ClusterComputeResource)、主机(HostSystem)、虚拟机(VirtualMachine)之间的目录关系。这里忽略VAPP以及APP。

正所谓无图无真相,先展示一张vSphere Client上的截图,以便形象的描述本文所要呈现的内容。

左边的目录树形象的展示了数据中心(Datacenter)、集群(ClusterComputeResource)、主机(HostSystem)、虚拟机(VirtualMachine)之间的目录关系。但是如何通过vSphere Webservice SDK进行获取相应的信息呢?

首先罗列本文所要展示的几个方法:

  1. 根据主机名获取虚拟机的名称列表
    public static List getVmNameListByHostName(String hostName) throws Exception
  2. 根据集群名获取主机的名称列表
    public static List getHostNameListByClusterName(String clusterName) throws Exception
  3. 根据集群名获取虚拟机的名称列表
    public static List getVmNameListByClusterName(String clusterName) throws Exception
  4. 根据数据中心名获取主机名称列表
    public static List getHostNameListByDCName(String dcName) throws Exception
  5. 根据数据中心名获取虚拟机名称列表
    public static List getVmNameListByDCName(String dcName) throws Exception
  6. 根据数据中心名称获取集群(ClusterComputeResource)列表
    public static List 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修饰的方法就是通过数据中心的名称获取集群、主机、虚拟机的名称列表的方法。

如有疑问,欢迎提出。本文展示的代码都经过真实环境运行并投入使用中。


欢迎支持笔者的作品《深入理解Kafka: 核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客(ID: hiddenkafka)。
本文作者: 朱小厮

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×