将 VM 搜索限制为特定集群?
Limiting VM Search to specific cluster(s)?
我正在使用 C# 和 VMware.Vim vsphere API 进行一些搜索,在大多数情况下它工作得很好,除了我不知道如何限制数据中心的特定集群。
例如:
NameValueCollection filter = new NameValueCollection();
filter.Add("Name", vmName2LookFor);
var ret = vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, viewProperties);
var VMs = ret.Cast<VMware.Vim.VirtualMachine>().ToList();
我看到过使用父 属性 递归向上爬树直到达到集群级别的建议,但是随着您获得更多结果,这在扩展方面似乎是一个非常糟糕的主意。
我也看到了使用 TraversalSpec 的参考资料,但我真的找不到任何关于它的好文档。
有人可以帮我吗?
您如何以高效的方式获取集群中的所有 VM and/or 是否有任何文档或者您能给我一些使用 TraversalSpec 的示例吗?
我最终只是为整个数据中心构建了一个主机=>集群映射,然后根据该映射检查 vm.Runtime.Host 属性 以确保虚拟机实际上是 运行特定集群。
这最终是有效的,但下面是我对如何使用 TraversalSpec 的问题的回答。代码在下面,解释在下面。
public SelectionSpec[] buildTraversalFromDatacenterToVM() {
// Recurse through all ResourcePools
TraversalSpec rpToVm = new TraversalSpec() {
Name = "rpToVm",
Type = "ResourcePool",
Path = "vm",
Skip = false
};
// Recurse through all ResourcePools
TraversalSpec rpToRp = new TraversalSpec() {
Name = "rpToRp",
Type = "ResourcePool",
Path = "resourcePool",
Skip = false,
SelectSet = new[] {
new SelectionSpec() { Name = "rpToRp" },
new SelectionSpec() { Name = "rpToVm" }
}
};
// Traversal through ResourcePool branch
TraversalSpec crToRp = new TraversalSpec() {
Name = "crToRp",
Type = "ComputeResource",
Path = "resourcePool",
Skip = false,
SelectSet = new[] {
new SelectionSpec() { Name = "rpToRp" },
new SelectionSpec() { Name = "rpToVm" },
}
};
// Traversal through host branch
TraversalSpec crToH = new TraversalSpec();
crToH.Name = "crToH";
crToH.Type = "ComputeResource";
crToH.Path = "host";
crToH.Skip = false;
// Traversal through hostFolder branch
TraversalSpec dcToHf = new TraversalSpec() {
Name = "dcToHf",
Type = "Datacenter",
Path = "hostFolder",
Skip = false,
SelectSet = new[] { new SelectionSpec() { Name = "visitFolders" } }
};
// Traversal through vmFolder branch
TraversalSpec dcToVmf = new TraversalSpec() {
Name = "dcToVmf",
Type = "Datacenter",
Path = "vmFolder",
Skip = false,
SelectSet = new[] { new SelectionSpec() { Name = "visitFolders" } }
};
// Recurse through all Hosts
TraversalSpec HToVm = new TraversalSpec() {
Name = "HToVm",
Type = "HostSystem",
Path = "vm",
Skip = false,
SelectSet = new[] { new SelectionSpec() { Name = "visitFolders" } }
};
// Recurse through the folders
TraversalSpec visitFolders = new TraversalSpec();
visitFolders.Name = "visitFolders";
visitFolders.Type = "Folder";
visitFolders.Path = "childEntity";
visitFolders.Skip = false;
visitFolders.SelectSet = new[] {
new SelectionSpec() { Name ="visitFolders" },
new SelectionSpec() { Name ="dcToHf" },
new SelectionSpec() { Name ="dcToVmf" },
new SelectionSpec() { Name ="crToH" },
new SelectionSpec() { Name ="crToRp" },
new SelectionSpec() { Name ="HToVm" },
new SelectionSpec() { Name ="rpToVm" },
new SelectionSpec() { Name ="HToVm" },
};
return new SelectionSpec[] { visitFolders, dcToVmf, dcToHf, crToH, crToRp, rpToRp, HToVm, rpToVm };
}
public PropertyFilterSpec[] GetPropertyFilterSpec(ManagedObjectReference root,PropertySpec[] propSpecs) {
if (typeinfo == null || typeinfo.Length == 0) {
return null;
}
var selectionSpecs = buildTraversalFromDatacenterToVM();
PropertyFilterSpec spec = new PropertyFilterSpec();
spec.PropSet = propSpecs;
spec.ObjectSet = new ObjectSpec[] {
new ObjectSpec() {
Obj = root,
Skip = false,
SelectSet = selectionSpecs
}
};
return new PropertyFilterSpec[] { spec }
}
下面是您将如何使用上述功能
// NOTE: setting All to true will return everything for the object, setting it to false
// and filling out the PathSet will instead only return the properties specified
// for performance. For example, below for the HostSystem objects, everything
// on the object will be null except for the name and the parent members
//
var propSpecs = new[] {
new PropertySpec() {
All = true,
Type = "VirtualMachine"
},
new PropertySpec() {
All = false,
Type = "HostSystem",
PathSet = new[]{ "name", "parent" }
}
};
VimClient vimClient = new VMware.Vim.VimClientImpl();
var serviceContent = vimClient.Connect(hostname, VMware.Vim.CommunicationProtocol.Https, null);
var userSession = vimClient.Login(un, pwd);
var propertyCollector = new PropertyCollector(vimClient, serviceContent.PropertyCollector);
var specs = GetPropertyFilterSpec(serviceContent.RootFolder,propSpecs);
ObjectContent[] objContents = propertyCollectionr.RetrieveProperties(specs);
现在开始解释。
因为 vmware 基础架构基本上是一个图,TraversalSpec 描述了如何攀登该图。分配的名称是用户定义的(任何你想要的),但用于引用特定的递归规范。换句话说,它很像一个引用或指针。例如,VisitFolders 规范使用 selectionSpec 引用回自身。这意味着它可以支持嵌套文件夹(多级,而不仅仅是 1 级)。
请注意,您可以比我做的更深入(进入数据存储等),但我不需要走那么远。
一旦您描述了如何遍历图表,您就必须告诉它 return 的属性,这就是 属性Spec 的用途。
PropertySpec 有两个用途。 1. 它充当准过滤器,如果您没有实体的 PropertySpec,那么 vmware API 将 return 没有任何作用。如果您确实有一个 PropertySpec,那么它将 return 只有您要求的属性。
因此在上面的示例中,它将 return 遍历中遇到的 VM 的所有属性,以及遍历中遇到的所有主机的名称和父属性。因为我没有为文件夹指定任何属性,请求将遍历文件夹但不会 return 返回它们的任何内容。
这是关于 vmware 层次结构的文档
和各种规范类型的文档
我正在使用 C# 和 VMware.Vim vsphere API 进行一些搜索,在大多数情况下它工作得很好,除了我不知道如何限制数据中心的特定集群。
例如:
NameValueCollection filter = new NameValueCollection();
filter.Add("Name", vmName2LookFor);
var ret = vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, viewProperties);
var VMs = ret.Cast<VMware.Vim.VirtualMachine>().ToList();
我看到过使用父 属性 递归向上爬树直到达到集群级别的建议,但是随着您获得更多结果,这在扩展方面似乎是一个非常糟糕的主意。
我也看到了使用 TraversalSpec 的参考资料,但我真的找不到任何关于它的好文档。
有人可以帮我吗?
您如何以高效的方式获取集群中的所有 VM and/or 是否有任何文档或者您能给我一些使用 TraversalSpec 的示例吗?
我最终只是为整个数据中心构建了一个主机=>集群映射,然后根据该映射检查 vm.Runtime.Host 属性 以确保虚拟机实际上是 运行特定集群。
这最终是有效的,但下面是我对如何使用 TraversalSpec 的问题的回答。代码在下面,解释在下面。
public SelectionSpec[] buildTraversalFromDatacenterToVM() {
// Recurse through all ResourcePools
TraversalSpec rpToVm = new TraversalSpec() {
Name = "rpToVm",
Type = "ResourcePool",
Path = "vm",
Skip = false
};
// Recurse through all ResourcePools
TraversalSpec rpToRp = new TraversalSpec() {
Name = "rpToRp",
Type = "ResourcePool",
Path = "resourcePool",
Skip = false,
SelectSet = new[] {
new SelectionSpec() { Name = "rpToRp" },
new SelectionSpec() { Name = "rpToVm" }
}
};
// Traversal through ResourcePool branch
TraversalSpec crToRp = new TraversalSpec() {
Name = "crToRp",
Type = "ComputeResource",
Path = "resourcePool",
Skip = false,
SelectSet = new[] {
new SelectionSpec() { Name = "rpToRp" },
new SelectionSpec() { Name = "rpToVm" },
}
};
// Traversal through host branch
TraversalSpec crToH = new TraversalSpec();
crToH.Name = "crToH";
crToH.Type = "ComputeResource";
crToH.Path = "host";
crToH.Skip = false;
// Traversal through hostFolder branch
TraversalSpec dcToHf = new TraversalSpec() {
Name = "dcToHf",
Type = "Datacenter",
Path = "hostFolder",
Skip = false,
SelectSet = new[] { new SelectionSpec() { Name = "visitFolders" } }
};
// Traversal through vmFolder branch
TraversalSpec dcToVmf = new TraversalSpec() {
Name = "dcToVmf",
Type = "Datacenter",
Path = "vmFolder",
Skip = false,
SelectSet = new[] { new SelectionSpec() { Name = "visitFolders" } }
};
// Recurse through all Hosts
TraversalSpec HToVm = new TraversalSpec() {
Name = "HToVm",
Type = "HostSystem",
Path = "vm",
Skip = false,
SelectSet = new[] { new SelectionSpec() { Name = "visitFolders" } }
};
// Recurse through the folders
TraversalSpec visitFolders = new TraversalSpec();
visitFolders.Name = "visitFolders";
visitFolders.Type = "Folder";
visitFolders.Path = "childEntity";
visitFolders.Skip = false;
visitFolders.SelectSet = new[] {
new SelectionSpec() { Name ="visitFolders" },
new SelectionSpec() { Name ="dcToHf" },
new SelectionSpec() { Name ="dcToVmf" },
new SelectionSpec() { Name ="crToH" },
new SelectionSpec() { Name ="crToRp" },
new SelectionSpec() { Name ="HToVm" },
new SelectionSpec() { Name ="rpToVm" },
new SelectionSpec() { Name ="HToVm" },
};
return new SelectionSpec[] { visitFolders, dcToVmf, dcToHf, crToH, crToRp, rpToRp, HToVm, rpToVm };
}
public PropertyFilterSpec[] GetPropertyFilterSpec(ManagedObjectReference root,PropertySpec[] propSpecs) {
if (typeinfo == null || typeinfo.Length == 0) {
return null;
}
var selectionSpecs = buildTraversalFromDatacenterToVM();
PropertyFilterSpec spec = new PropertyFilterSpec();
spec.PropSet = propSpecs;
spec.ObjectSet = new ObjectSpec[] {
new ObjectSpec() {
Obj = root,
Skip = false,
SelectSet = selectionSpecs
}
};
return new PropertyFilterSpec[] { spec }
}
下面是您将如何使用上述功能
// NOTE: setting All to true will return everything for the object, setting it to false
// and filling out the PathSet will instead only return the properties specified
// for performance. For example, below for the HostSystem objects, everything
// on the object will be null except for the name and the parent members
//
var propSpecs = new[] {
new PropertySpec() {
All = true,
Type = "VirtualMachine"
},
new PropertySpec() {
All = false,
Type = "HostSystem",
PathSet = new[]{ "name", "parent" }
}
};
VimClient vimClient = new VMware.Vim.VimClientImpl();
var serviceContent = vimClient.Connect(hostname, VMware.Vim.CommunicationProtocol.Https, null);
var userSession = vimClient.Login(un, pwd);
var propertyCollector = new PropertyCollector(vimClient, serviceContent.PropertyCollector);
var specs = GetPropertyFilterSpec(serviceContent.RootFolder,propSpecs);
ObjectContent[] objContents = propertyCollectionr.RetrieveProperties(specs);
现在开始解释。
因为 vmware 基础架构基本上是一个图,TraversalSpec 描述了如何攀登该图。分配的名称是用户定义的(任何你想要的),但用于引用特定的递归规范。换句话说,它很像一个引用或指针。例如,VisitFolders 规范使用 selectionSpec 引用回自身。这意味着它可以支持嵌套文件夹(多级,而不仅仅是 1 级)。
请注意,您可以比我做的更深入(进入数据存储等),但我不需要走那么远。
一旦您描述了如何遍历图表,您就必须告诉它 return 的属性,这就是 属性Spec 的用途。
PropertySpec 有两个用途。 1. 它充当准过滤器,如果您没有实体的 PropertySpec,那么 vmware API 将 return 没有任何作用。如果您确实有一个 PropertySpec,那么它将 return 只有您要求的属性。
因此在上面的示例中,它将 return 遍历中遇到的 VM 的所有属性,以及遍历中遇到的所有主机的名称和父属性。因为我没有为文件夹指定任何属性,请求将遍历文件夹但不会 return 返回它们的任何内容。
这是关于 vmware 层次结构的文档
和各种规范类型的文档