有没有办法通过vSphere API进行批处理?

时间:2017-05-29 05:27:27

标签: c# vmware

我使用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;
}

2 个答案:

答案 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);
}