vSphere CreateContainerView / RetrievePropertiesEx仅返回100个对象

时间:2016-01-08 20:58:32

标签: node.js soap vsphere node-vsphere

我正在使用nodejs并且节点代码相当简单(在这里使用一些民间故事,但任务类似于承诺):

const connect = (vcenter) => {
    return new Task( (reject, resolve) => {
        const Vsphere = require('vsphere');
        const vc = new Vsphere.Client(vcenter, 'me', 'myPass', false);

        vc.once('ready', () => resolve(vc));
        vc.once('error', reject);
    })
}
const getVirtualMachines = (vc) => {
    return new Task( (reject, resolve) => {
        const rootFolder = vc.serviceContent.rootFolder;
        const vms =  vc.getMORefsInContainerByType( rootFolder, 'VirtualMachine');
        vms.once('result', resolve)
        vms.once('error', reject)
    })
}

connect(vcenterIp).
    chain(getVirtualMachines).
    // SNIP (this isn't significant)
    fork(e2,f2)

并导致发送这些请求

CreateContainerView
{
   "_this": {
      "attributes": {
         "type": "ViewManager"
      },
      "$value": "ViewManager"
   },
   "container": {
      "attributes": {
         "type": "Folder"
      },
      "$value": "group-d1"
   },
   "type": "VirtualMachine",
   "recursive": true
}



RetrievePropertiesEx
{
   "_this": {
      "attributes": {
         "type": "PropertyCollector"
      },
      "$value": "propertyCollector"
   },
   "specSet": [
      {
         "attributes": {
            "xsi:type": "PropertyFilterSpec"
         },
         "propSet": [
            {
               "attributes": {
                  "xsi:type": "PropertySpec"
               },
               "type": "VirtualMachine",
               "all": true
            }
         ],
         "objectSet": [
            {
               "attributes": {
                  "xsi:type": "ObjectSpec"
               },
               "obj": {
                  "attributes": {
                     "type": "ContainerView"
                  },
                  "$value": "session[520e031b-3c15-9c1d-408a-45ab98bde1dc]52dfe626-a128-c94f-8c4c-df52a68d97c0"
               },
               "skip": true,
               "selectSet": [
                  {
                     "attributes": {
                        "xsi:type": "TraversalSpec"
                     },
                     "type": "ContainerView",
                     "path": "view",
                     "skip": false
                  }
               ]
            }
         ]
      }
   ],
   "options": {}
}

返回

{ returnval: 
   { token: '0',
     objects: 
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] } }

我看到的问题是API只返回100个项目,而我的环境中有超过100个。

我真的希望查询返回我的所有虚拟机

更新1:

  

要调用单个属性集合操作,请调用   RetrievePropertiesEx方法。示例应用程序通过了   填充的PropertyFilterSpec和一个空的选项结构   方法。 RetrieveOptions.maxObjects的默认值指定了   没有设置可返回的对象数的最大值。该   PropertyCollector可以施加最大值。如果收集的数量   对象大于最大值,PropertyCollector返回一个   RetrieveResult数据对象中的标记值,并使用此标记   使用。检索剩余的属性   ContinueRetrievePropertiesEx API方法

https://pubs.vmware.com/vsphere-50/index.jsp?topic=%2Fcom.vmware.wssdk.pg.doc_50%2FPG_Ch5_PropertyCollector.7.5.html

更新2

确定查看返回的结果vSPehere返回一个令牌代码。并且node-vsphere库不会检索所有结果。我需要找到一种方法来一步完成所有结果。

2 个答案:

答案 0 :(得分:2)

我需要跟进此请求

ContinueRetrievePropertiesEx
{
   "_this": {
      "attributes": {
         "type": "PropertyCollector"
      },
      "$value": "propertyCollector"
   },
   "token": "0"
}

我是如何用图书馆完成这项工作的:

const connect = (vcenter) => {
    return new Task( (reject, resolve) => {
        const Vsphere = require('vsphere');
        const vc = new Vsphere.Client(vcenter, 'xyz\\tbrown', 'ijhi', false);

        vc.once('ready', () => resolve(vc));
        vc.once('error', reject);
    })
}

const getVirtualMachines = (vc) => {
    return new Task( (reject, resolve) => {
        const rootFolder = vc.serviceContent.rootFolder;
        const vms =  vc.getMORefsInContainerByType( rootFolder, 'VirtualMachine');
        vms.once('result', (initial) =>{
            if(initial.returnval.token == undefined) {
                resolve(initial)
                return
            }else {
                const thisReceiveAll = receiveAll(reject, resolve)
                thisReceiveAll(vc, initial)
            }
        })
        vms.once('error', reject)
    })
}

const receiveAll = (reject, resolve) => (vc, initial) => {
    const executeContinueReceive = function executeContinueReceive(previous) {
        const args = {
            _this: {"attributes":{"type":"PropertyCollector"},"$value":"propertyCollector"},
            token: previous.returnval.token
        }
        vc.vc.runCommand('ContinueRetrievePropertiesEx', args).once('result', function(current){
            const previousObjects = previous.returnval.objects
            const currentObjects = current.returnval.objects
            const allObjects = previousObjects.concat(currentObjects)

            current.returnval.objects = allObjects
            if(current.returnval.token == undefined) {
                resolve(current);
                return
            }
            return executeContinueReceive(current)

        }).once('error', reject);
    }
    executeContinueReceive(initial)
}

基本上当我检索初始结果集并检查令牌时。如果令牌在那里,我输入一个递归" receiveAll"调用runCommand(' ContinueRetrievePropertiesEx',args)并附加其结果的函数。再次检查最后的令牌,并返回结果或进行另一次递归调用...也许这应该移回到库中

答案 1 :(得分:0)

您只需使用RetrieveProperties即可,无需进行任何类型的遍历。