我使用的是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多个VM。
我真的希望查询返回我所有的虚拟机
更新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库不会检索所有结果。我需要想办法一步到位。
我需要跟进这个请求
ContinueRetrievePropertiesEx
{
"_this": {
"attributes": {
"type": "PropertyCollector"
},
"$value": "propertyCollector"
},
"token": "0"
}
HEre是我如何用图书馆做到这一点的:
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('ContinuueRetrievePropertiesEx',args)并附加其结果。再次检查最后的令牌,然后返回结果或进行另一个递归调用。。。也许这应该移回库
您只需使用RetrieveProperties
,就不需要进行任何类型的遍历。