node-vsphere
node-vsphere copied to clipboard
Running a command with a payload property called 'attributes' fails
Found an interesting one: I was calling vc.runCommand('QueryVmfsDatastoreCreateOptions', queryVmfsDatastoreCreateOptions). The queryVmfsDatastoreCreateOptions.spec.partition.partition object has a property called 'attributes'. This is a required property. If it is included Vsphere returns an error:
Error returned by expat parser: not well-formed (invalid token) while parsing property "totalSectors" of static type long while parsing serialized DataObject of type vim.host.DiskPartitionInfo.Specification at line 1, column 527 while parsing property "partition" of static type HostDiskPartitionSpec while parsing serialized DataObject of type vim.host.VmfsDatastoreCreateSpec at line 1, column 385 while parsing call information for method CreateVmfsDatastore at line 1, column 243
After several hours and several eyes we discovered that 'attributes' is hardcoded in this module. It is expected in validation of certain objects (types.js) and also used for various things in client.js. This conflicts with the use case where we wish to provide our own attributes property for vsphere rather than xml based attributes to help the parser figure out which object to deserialise. Our attributes property is being over written and vsphere is spitting back an error about the object where the 'attributes' property is located. The node-vsphere-soap module also ignores the attributesKey property of the soap client which is used to differentiate between real property attributes and ones to describe the XML type.
As a work around, we have used the $xml property to specify xml for this property rather than json. e.g.
vc.runCommand('QueryVmfsDatastoreCreateOptions', queryVmfsDatastoreCreateOptions).once('result', function (result) { result.returnval[0].spec.vmfs.volumeName = datastoreName var partitionObj = result.returnval[0].spec.partition.partition; var partitionXml = ''; for (key in partitionObj) { var element = partitionObj[key]; var xmlElement = '<' + key + '>' + element + '</' + key + '>' partitionXml += xmlElement; } result.returnval[0].spec.partition.partition = {}; result.returnval[0].spec.partition.partition['$xml'] = partitionXml var createVmfsDatastore = { _this: hostDatastoreSystemMOR, spec: result.returnval[0].spec } vc.runCommand('CreateVmfsDatastore', createVmfsDatastore).once('result', function (result) { resolve(result); }) .once('error', function (err) { console.log(err); reject(err); }); }) .once('error', function (err) { console.log(err); reject(err); });
One to fix for the future...