We moved from vRO 7.1 to 7.4
The action that isn't working is one that will select a template by version and then pass that on for cloning to VM. The new version of vRO throws an error that the split is undefined. I'm not sure why I was hoping someone can help me track this down.
var filter = '^' + os + '\\-template\\-\\d+\\.\\d+\\.\\d+$'; // string
var targetTypes = ['VirtualMachine'];// string[]
var properties = ['name'];// string[]
var rootObject = null;// Any
var foundObjects = [];
var containerRoot = null
if (typeof rootObject === 'undefined' || rootObject == null || rootObject == '<<null>>') {
containerRoot = vc.rootFolder
} else {
containerRoot = rootObject
}
var recursive = true
var containerView = vc.viewManager.createContainerView(containerRoot, targetTypes, recursive)
// create an object spec for the beginning of the traversal;
// container view is the root object for this traversal
var oSpec = new VcObjectSpec()
oSpec.obj = containerView.reference
oSpec.skip = true
// create a traversal spec to select all objects in the view
var tSpec = new VcTraversalSpec()
tSpec.name = 'traverseEntities'
tSpec.path = 'view'
tSpec.skip = false
tSpec.type = 'ContainerView'
// add it to the object spec
oSpec.selectSet = [tSpec]
var propertySpecs = new Array()
for (var t in targetTypes) {
// specify the properties for retrieval
var pSpec = new VcPropertySpec()
pSpec.type = targetTypes[t]
pSpec.pathSet = properties
propertySpecs.push(pSpec)
}
var fs = new VcPropertyFilterSpec()
fs.objectSet = [ oSpec ]
fs.propSet = propertySpecs
var retrieveOptions = new VcRetrieveOptions()
var propertyCollector = vc.propertyCollector.createPropertyCollector()
try {
retrieveResult = propertyCollector.retrievePropertiesEx([fs], retrieveOptions)
do {
if (typeof retrieveResult !== 'undefined' && retrieveResult !== null) {
processObjects(retrieveResult)
if (retrieveResult.token !== 'undefined' && retrieveResult.token !== null) {
retrieveResult = propertyCollector.continueRetrievePropertiesEx(retrieveResult.token)
} else {
break
}
} else {
break;
}
} while(true)
} finally {
propertyCollector.destroyPropertyCollector()
}
for (i=0;i<foundObjects.length;i++) {
System.log(foundObjects[i]);
}
System.log(foundObjects.length);
vms = new Array()
for (var i in foundObjects) {
vms.push(Server.fromUri(foundObjects[i]))
}
if(vms.length === 0) {
System.warn("No template could be found for OS '" + os + "'");
return null;
} else {
vms.sort(versionCompare);
var indexToReturn = vms.length - 1;
System.log("The most current " + os + " template is " + vms[indexToReturn].name);
return vms[indexToReturn];
}
function processObjects(retrieveResult) {
var resultObjects = retrieveResult.objects
if (typeof foundObjects === 'undefined' || foundObjects === null) {
foundObjects = new Array()
}
var pattern = new RegExp(filter,'i')
for (r in resultObjects) {
var objContent = resultObjects[r]
var id = objContent.obj.value
var type = objContent.obj.type
var props = objContent.propSet
for (p in props) {
if (pattern.test(props[p].val)) {
var dunesId = "dunes://service.dunes.ch/CustomSDKObject?id='"
+ vc.id + "/" + id +"'&dunesName='VC:" + type + "'"
foundObjects.push(dunesId)
break
}
}
}
}
/**
* Compares two software version numbers (e.g. "1.7.1" or "1.2b").
*
* This function was born in http://stackoverflow.com/a/6832721.
*
* @param {string} v1 The first version to be compared.
* @param {string} v2 The second version to be compared.
* @param {object} [options] Optional flags that affect comparison behavior:
* <ul>
* <li>
* <tt>lexicographical: true</tt> compares each part of the version strings lexicographically instead of
* naturally; this allows suffixes such as "b" or "dev" but will cause "1.10" to be considered smaller than
* "1.2".
* </li>
* <li>
* <tt>zeroExtend: true</tt> changes the result if one version string has less parts than the other. In
* this case the shorter string will be padded with "zero" parts instead of being considered smaller.
* </li>
* </ul>
* @returns {number|NaN}
* <ul>
* <li>0 if the versions are equal</li>
* <li>a negative integer iff v1 < v2</li>
* <li>a positive integer iff v1 > v2</li>
* <li>NaN if either version string is in the wrong format</li>
* </ul>
*
* @copyright by Jon Papaioannou (["john", "papaioannou"].join(".") + "@gmail.com")
* @license This function is in the public domain. Do what you want with it, no strings attached.
*/
function versionCompare(v1, v2, options) {
var lexicographical = options && options.lexicographical,
zeroExtend = options && options.zeroExtend,
v1parts = v1.name.split('-')[2].split('.');
v2parts = v2.name.split('-')[2].split('.');
function isValidPart(x) {
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
}
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
return NaN;
}
if (zeroExtend) {
while (v1parts.length < v2parts.length) v1parts.push("0");
while (v2parts.length < v1parts.length) v2parts.push("0");
}
if (!lexicographical) {
v1parts = v1parts.map(Number);
v2parts = v2parts.map(Number);
}
for (var i = 0; i < v1parts.length; ++i) {
if (v2parts.length == i) {
return 1;
}
if (v1parts[i] == v2parts[i]) {
continue;
}
else if (v1parts[i] > v2parts[i]) {
return 1;
}
else {
return -1;
}
}
if (v1parts.length != v2parts.length) {
return -1;
}
return 0;
}
var filter = '^' + os + '\\-template\\-\\d+\\.\\d+\\.\\d+$'; // string
var targetTypes = ['VirtualMachine'];// string[]
var properties = ['name'];// string[]
var rootObject = null;// Any
var foundObjects = [];
var containerRoot = null
if (typeof rootObject === 'undefined' || rootObject == null || rootObject == '<<null>>') {
containerRoot = vc.rootFolder
} else {
containerRoot = rootObject
}
var recursive = true
var containerView = vc.viewManager.createContainerView(containerRoot, targetTypes, recursive)
// create an object spec for the beginning of the traversal;
// container view is the root object for this traversal
var oSpec = new VcObjectSpec()
oSpec.obj = containerView.reference
oSpec.skip = true
// create a traversal spec to select all objects in the view
var tSpec = new VcTraversalSpec()
tSpec.name = 'traverseEntities'
tSpec.path = 'view'
tSpec.skip = false
tSpec.type = 'ContainerView'
// add it to the object spec
oSpec.selectSet = [tSpec]
var propertySpecs = new Array()
for (var t in targetTypes) {
// specify the properties for retrieval
var pSpec = new VcPropertySpec()
pSpec.type = targetTypes[t]
pSpec.pathSet = properties
propertySpecs.push(pSpec)
}
var fs = new VcPropertyFilterSpec()
fs.objectSet = [ oSpec ]
fs.propSet = propertySpecs
var retrieveOptions = new VcRetrieveOptions()
var propertyCollector = vc.propertyCollector.createPropertyCollector()
try {
retrieveResult = propertyCollector.retrievePropertiesEx([fs], retrieveOptions)
do {
if (typeof retrieveResult !== 'undefined' && retrieveResult !== null) {
processObjects(retrieveResult)
if (retrieveResult.token !== 'undefined' && retrieveResult.token !== null) {
retrieveResult = propertyCollector.continueRetrievePropertiesEx(retrieveResult.token)
} else {
break
}
} else {
break;
}
} while(true)
} finally {
propertyCollector.destroyPropertyCollector()
}
for (i=0;i<foundObjects.length;i++) {
System.log(foundObjects[i]);
}
System.log(foundObjects.length);
vms = new Array()
for (var i in foundObjects) {
vms.push(Server.fromUri(foundObjects[i]))
}
if(vms.length === 0) {
System.warn("No template could be found for OS '" + os + "'");
return null;
} else {
vms.sort(versionCompare);
var indexToReturn = vms.length - 1;
System.log("The most current " + os + " template is " + vms[indexToReturn].name);
return vms[indexToReturn];
}
function processObjects(retrieveResult) {
var resultObjects = retrieveResult.objects
if (typeof foundObjects === 'undefined' || foundObjects === null) {
foundObjects = new Array()
}
var pattern = new RegExp(filter,'i')
for (r in resultObjects) {
var objContent = resultObjects[r]
var id = objContent.obj.value
var type = objContent.obj.type
var props = objContent.propSet
for (p in props) {
if (pattern.test(props[p].val)) {
var dunesId = "dunes://service.dunes.ch/CustomSDKObject?id='"
+ vc.id + "/" + id +"'&dunesName='VC:" + type + "'"
foundObjects.push(dunesId)
break
}
}
}
}
/**
* Compares two software version numbers (e.g. "1.7.1" or "1.2b").
*
*
* @param {string} v1 The first version to be compared.
* @param {string} v2 The second version to be compared.
* @param {object} [options] Optional flags that affect comparison behavior:
* <ul>
* <li>
* <tt>lexicographical: true</tt> compares each part of the version strings lexicographically instead of
* naturally; this allows suffixes such as "b" or "dev" but will cause "1.10" to be considered smaller than
* "1.2".
* </li>
* <li>
* <tt>zeroExtend: true</tt> changes the result if one version string has less parts than the other. In
* this case the shorter string will be padded with "zero" parts instead of being considered smaller.
* </li>
* </ul>
* @returns {number|NaN}
* <ul>
* <li>0 if the versions are equal</li>
* <li>a negative integer iff v1 < v2</li>
* <li>a positive integer iff v1 > v2</li>
* <li>NaN if either version string is in the wrong format</li>
* </ul>
*
* @copyright by Jon Papaioannou (["john", "papaioannou"].join(".") + "@gmail.com")
* @license This function is in the public domain. Do what you want with it, no strings attached.
*/
function versionCompare(v1, v2, options) {
var lexicographical = options && options.lexicographical,
zeroExtend = options && options.zeroExtend,
v1parts = v1.name.split('-')[2].split('.');
v2parts = v2.name.split('-')[2].split('.');
function isValidPart(x) {
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
}
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
return NaN;
}
if (zeroExtend) {
while (v1parts.length < v2parts.length) v1parts.push("0");
while (v2parts.length < v1parts.length) v2parts.push("0");
}
if (!lexicographical) {
v1parts = v1parts.map(Number);
v2parts = v2parts.map(Number);
}
for (var i = 0; i < v1parts.length; ++i) {
if (v2parts.length == i) {
return 1;
}
if (v1parts[i] == v2parts[i]) {
continue;
}
else if (v1parts[i] > v2parts[i]) {
return 1;
}
else {
return -1;
}
}
if (v1parts.length != v2parts.length) {
return -1;
}
return 0;
}