Name
global.DiscoveryIpAddressHandler
Description
Provides functionality to prevent IP flip flop on hardware CIs
Script
var DiscoveryIpAddressHandler;
(function() {
/**********************************************
Local Variables
***********************************************/
var mainCiIpList = [];
var inputPayload = null;
/**********************************************
Public API
***********************************************/
DiscoveryIpAddressHandler = {
getPayloadWithoutIpAddressForHardwareCis: getPayloadWithoutIpAddressForHardwareCis,
findOrUpdateIpAddress: findOrUpdateIpAddress,
// exposed for testing
getCiPayloadsWithIpAddress: getCiPayloadsWithIpAddress
};
function getPayloadWithoutIpAddressForHardwareCis(payload) {
payload = JSON.parse(payload);
inputPayload = payload;
var ciTypesExtendingHardware = GlideDBObjectManager.get().getAllExtensions('cmdb_ci_hardware');
// iterate over hardware CIs and remove ip_address attribute on the CI before payload is processed by IRE
for (var index = 0; index < payload.items.length; index++) {
var item = payload.items[index];
if (ciTypesExtendingHardware.contains(item.values.sys_class_name)) {
// extract ip_address attribute and remove ip_address from the CI input for all hardware CIs and put the value in memory
// keeping track of index for usage during ip_address reconciliation
mainCiIpList[index] = item.values.ip_address;
// deleting an attribute on an object could be less efficient than setting the attribute to undefined
// when using JSON.stringify(), Rhino will ignore all properties set to undefined in the result string.
item.values.ip_address = undefined;
}
}
return JSON.stringify(payload);
}
function findOrUpdateIpAddress(ireOutput) {
var ciPayloadsWithIpAddress = getCiPayloadsWithIpAddress(ireOutput);
if (ciPayloadsWithIpAddress.items.length < 1)
return;
var discoverySource = gs.getProperty("glide.discovery.source_name", "ServiceNow");
SNC.IdentificationEngineScriptableApi.createOrUpdateCI(discoverySource, JSON.stringify(ciPayloadsWithIpAddress));
}
function getCiPayloadsWithIpAddress(ireOutput) {
var parsedOutputPayload = JSON.parse(ireOutput);
var ipList = [];
for (index = 0; index < inputPayload.items.length; index++) {
item = inputPayload.items[index];
if ('cmdb_ci_ip_address' == item.values.sys_class_name) {
ipList.push(item.values.ip_address);
}
}
// extract main CIs from the IRE output payload for ip_address reconciliation
var ciPayloadsWithIpAddress = {
items: []
};
mainCiIpList.forEach(function(discoveredIpAddress, ciIndex) {
if (JSUtil.nil(discoveredIpAddress))
return;
var operationType = parsedOutputPayload.items[ciIndex].operation;
if (operationType == 'UPDATE' || operationType == 'NO_CHANGE') {
// try to fetch the CI record with ip_address value not one of IPs discovered.
// if a record exists, it means the ip_address found on ciGr was not discovered and needs to be updated.
// using glide aggregate here as it offers better DB performance compared to glide record
var ciSysId = parsedOutputPayload.items[ciIndex].sysId;
var ciGr = new GlideAggregate(parsedOutputPayload.items[ciIndex].className);
ciGr.addQuery('sys_id', ciSysId);
ciGr.addQuery('ip_address', 'NOT IN', ipList);
ciGr.addAggregate('COUNT', 'ip_address');
ciGr.query();
if (!ciGr.hasNext())
return;
// if we are here, the ip address on the CI couldn't be discovered.
// run CI through IRE with ip_address attribute set to discoveredIpAddress
var ciPayload = inputPayload.items[ciIndex];
ciPayload.values.ip_address = discoveredIpAddress;
ciPayloadsWithIpAddress.items.push(ciPayload);
}
});
return ciPayloadsWithIpAddress;
}
})();
Sys ID
472639fc770e6110996857792c5a9986