我使用vSphere API检索vCenter中的所有虚拟机。但是,我没有找到任何官方文档或代码示例提及批处理/分页请求。我的代码如下:
VimClient client = new VimClient();
client.Connect(host, CommunicationProtocol.Https, 443);
client.Login(userName, password);
IList<EntityViewBase> vms = client.FindEntityViews(typeof(VirtualMachine), null, null, null);
我检查了ReSharper反编译的源代码。有趣的是,有一个可以为空的参数&#34; beginEntity&#34 ;;但是没有办法指定要检索的实体数量。完全没有希望他们可以支持批次吗?
public List<EntityViewBase> FindEntityViews(Type viewType, ManagedObjectReference beginEntity, NameValueCollection filter, string[] properties)
{
IList<ViewBase> viewBaseList = (IList<ViewBase>) null;
ManagedObjectReference beginEntity1 = beginEntity ?? this._serviceContent.RootFolder;
string[] strArray = (string[]) null;
if (filter != null && filter.Count > 0)
{
string[] propertyList = new string[filter.Count];
filter.AllKeys.CopyTo((Array) propertyList, 0);
strArray = VimClient.ValidatePropertyPathList(viewType, propertyList);
}
ObjectContent[] objectContentArray = new PropertyCollector(this, this._serviceContent.PropertyCollector).RetrieveProperties(new PropertyFilterSpec[1]
{
EntityViewBase.GetSearchFilterSpec(this, beginEntity1, new PropertySpec()
{
All = new bool?(false),
Type = viewType.Name,
PathSet = strArray
})
});
List<ManagedObjectReference> managedObjectReferenceList = new List<ManagedObjectReference>();
if (objectContentArray != null)
{
foreach (ObjectContent objectContent in objectContentArray)
{
if (beginEntity == null || !objectContent.Obj.Value.Equals(beginEntity.Value) || !objectContent.Obj.Type.Equals(beginEntity.Type))
{
if (filter != null && filter.Count > 0)
{
DynamicProperty[] propSet = objectContent.PropSet;
if (propSet != null)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
foreach (DynamicProperty dynamicProperty in propSet)
dictionary.Add(dynamicProperty.Name, dynamicProperty.Val);
if (dictionary.Count > 0 && VimClient.MatchProperyList(filter, viewType, (IDictionary<string, object>) dictionary))
managedObjectReferenceList.Add(objectContent.Obj);
}
}
else
managedObjectReferenceList.Add(objectContent.Obj);
}
}
}
if (managedObjectReferenceList.Count > 0)
viewBaseList = (IList<ViewBase>) this.GetViewsByMorefs((IEnumerable<ManagedObjectReference>) managedObjectReferenceList, properties);
List<EntityViewBase> entityViewBaseList = (List<EntityViewBase>) null;
if (viewBaseList != null)
{
entityViewBaseList = new List<EntityViewBase>();
foreach (ViewBase viewBase in (IEnumerable<ViewBase>) viewBaseList)
{
EntityViewBase entityViewBase = viewBase as EntityViewBase;
entityViewBaseList.Add(entityViewBase);
}
}
return entityViewBaseList;
}
public List<ViewBase> GetViewsByMorefs(IEnumerable<ManagedObjectReference> moRefs, params string[] properties)
{
Dictionary<string, PropertyFilterSpec> propertyFilterSpecList = new Dictionary<string, PropertyFilterSpec>();
foreach (ManagedObjectReference moRef in moRefs)
{
if (propertyFilterSpecList.ContainsKey(moRef.Type.ToLower()))
{
PropertyFilterSpec propertyFilterSpec = propertyFilterSpecList[moRef.Type.ToLower()];
propertyFilterSpec.ObjectSet = new List<ObjectSpec>((IEnumerable<ObjectSpec>) propertyFilterSpec.ObjectSet)
{
new ObjectSpec() { Obj = moRef }
}.ToArray();
}
else
{
PropertyFilterSpec resultPropertyFilterSpec;
Dictionary<string, List<string>> currentAllowedPropertyPath;
DynamicPropertyFilterSpecGenerator.Generate(moRef, properties, out resultPropertyFilterSpec, out currentAllowedPropertyPath);
propertyFilterSpecList.Add(moRef.Type.ToLower(), resultPropertyFilterSpec);
}
}
PropertyFilterSpec[] propertyFilterSpecArray = new PropertyFilterSpec[propertyFilterSpecList.Values.Count];
propertyFilterSpecList.Values.CopyTo(propertyFilterSpecArray, 0);
ObjectContent[] objectContent = new PropertyCollector(this, this._serviceContent.PropertyCollector).RetrieveProperties(propertyFilterSpecArray);
List<ViewBase> viewsByMorefs = this.GetViewsByMorefs(moRefs, objectContent, propertyFilterSpecList);
return viewsByMorefs;
}
private List<ViewBase> GetViewsByMorefs(IEnumerable<ManagedObjectReference> moRefs, ObjectContent[] objectContent, Dictionary<string, PropertyFilterSpec> propertyFilterSpecList)
{
List<ViewBase> viewBaseList = new List<ViewBase>();
List<string> stringList = new List<string>();
foreach (ManagedObjectReference moRef in moRefs)
stringList.Add(moRef.Value);
Dictionary<string, ObjectContent> objectContentList = new Dictionary<string, ObjectContent>();
foreach (ObjectContent objectContent1 in objectContent)
objectContentList.Add(objectContent1.Obj.Value, objectContent1);
Dictionary<string, ViewBase> generatedManagedObjectList = new Dictionary<string, ViewBase>();
foreach (ObjectContent objectContent1 in objectContent)
{
if (stringList.Contains(objectContent1.Obj.Value))
{
ConstructorInfo constructor = ViewBase.GetViewType(objectContent1.Obj.Type).GetConstructor(new Type[2]
{
typeof (VimClient),
typeof (ManagedObjectReference)
});
if (constructor != null)
{
ViewBase currentObject = (ViewBase) constructor.Invoke(new object[2]
{
(object) this,
(object) objectContent1.Obj
});
ViewBase.SetViewData(currentObject, (string) null, (Dictionary<string, List<string>>) null, objectContentList, generatedManagedObjectList);
viewBaseList.Add(currentObject);
}
}
}
return viewBaseList;
}
答案 0 :(得分:1)
我不知道如何实现这一目标。
但是,您发布的第二个代码段(经过反编译的Logstash
)显示了使用VMware Property Collector
的方法FindEntityViews
。如果您使用retrievePropertiesEx
,则可以为其提供最大数量,然后拨打continueRetrievePropertiesEx
。
请注意,根据我的经验,vSphere API非常强大,因此除非您拥有数千台虚拟机,否则您可能会发现您不需要分页(当然,除非您有其他注意事项)。
答案 1 :(得分:0)
这是一段代码,说明了我最终如何实现批处理。
VimClient vimClient = new VimClient();
vimClient.Connect(host, CommunicationProtocol.Https, 443);
vimClient.Login(userName, password);
string token = string.Empty;
while (true)
{
// Construct the property collector
PropertyCollector propertyCollector = new PropertyCollector(vimClient, vimClient.ServiceContent.PropertyCollector);
// Retrieve a batch of objects
RetrieveResult result;
if (!string.IsNullOrWhiteSpace(token))
result = propertyCollector.ContinueRetrievePropertiesEx(token);
else
{
result = propertyCollector.RetrievePropertiesEx(new[]
{
EntityViewBase.GetSearchFilterSpec(vimClient, vimClient.ServiceContent.RootFolder, new PropertySpec
{
All = false,
Type = typeof(VirtualMachine),
PathSet = null
})
}, new RetrieveOptions { MaxObjects = 100 });
}
// Exit early if no entities retrieved
if (null == result || 0 == result.Objects.Length)
break;
// Get the MoRefs of retrieval result
List<ManagedObjectReference> objectMoRefList = result.Objects.Select(o => o.Obj).ToList();
// Retrieve the properties of objects
List <EntityViewBase> entityList = vimClient.GetViewsByMorefs(objectMoRefList)?.Select(viewBase => viewBase as EntityViewBase).ToList();
// Return the objects and batch retrieval token
token = new BatchRetrievalToken(result.Token)
entityList.ForEach(e => yield return e);
}