Name

global.DeviceL3Mapping

Description

Map a device to a router or L3 switch through Layer 3 IPs

Script

// Discovery

/**
* @auther Aleck Lin aleck.lin@servicenow.com
*/

var DeviceL3Mapping = Class.create();

DeviceL3Mapping.prototype = {

  initialize: function(deviceGr) {
  	this.deviceGr = deviceGr;
  	this.deviceIPs = [];
  	this.routers = [];
  },

  map: function() {
  	try {
  		if (JSUtil.nil(this.deviceGr))
  			return;

  		// Find all the IPs that belong to the device
  		this._findAllDeviceIPs();
  		if (!this.deviceIPs || this.deviceIPs.length == 0)
  			return;

  		// Collect all the routers that the IP address is part of...
  		this._collectRouters();
  		if (this.routers.length == 0)
  			return;

  		this._reconcileRelationships();
  	} catch (e) {
  		this._logError(e.toString() + e.stack);
  	}
  },	

  _reconcileRelationships: function() {
  	var relgr, routerId;
  	var df = new DiscoveryFunctions();		

  	var IPRelationTargets = {};
  	relgr = new GlideRecord("cmdb_rel_ci");
  	relgr.addQuery("parent", this.deviceGr.sys_id);		
  	relgr.addQuery("type", df.findCIRelationshipType("cmdb_rel_type", "IP Connection::IP Connection"));
  	relgr.query();
  	while (relgr.next())
  		IPRelationTargets[relgr.child + ''] = true;

  	var existingCIs = new GlideRecord('cmdb_ci');

  	for (var i=0; i<this.routers.length; i++) {
  		routerId = this.routers[i];
  		// There's already a relationship...
  		if (IPRelationTargets[routerId])
  			delete IPRelationTargets[routerId];
  		// If no existing relationship and router exists in cmdb_ci, create relationship
  		else if (existingCIs.get('sys_id', routerId))
  			df.createRelationship(this.deviceGr.sys_id, routerId, "IP Connection::IP Connection");						
  	}		

  	// If there are still entries in the IPRelationTargets, that means they're stale relationships, remove them.
  	for (routerId in IPRelationTargets) {
  		relgr = new GlideRecord("cmdb_rel_ci");
  		relgr.addQuery("parent", this.deviceGr.sys_id);		
  		relgr.addQuery("child", routerId);		
  		relgr.addQuery("type", df.findCIRelationshipType("cmdb_rel_type", "IP Connection::IP Connection"));
  		relgr.query();
  		while (relgr.next()) 	
  			relgr.deleteRecord(); 		
  	}

  },

  _findAllDeviceIPs: function() {
  	var foundBase;
  	var ips = [];
  	var baseIP = this.deviceGr.ip_address + '';

  	var gr = new GlideRecord("cmdb_ci_ip_address");
  	gr.addQuery("nic.cmdb_ci", this.deviceGr.sys_id);
  	gr.addQuery('ip_version', 4);
  	gr.addQuery('install_status', 1); //only installed
  	gr.addQuery('nic.install_status', 1); //only installed nic - PRB1309396
  	gr.query();
  	while (gr.next()) {
  		var ip = gr.ip_address + '';
  		if (JSUtil.notNil(baseIP) && ip == baseIP)
  			foundBase = true;

  		ips.push(ip + "/" + gr.nic.netmask);
  	}

  	if (!foundBase && JSUtil.notNil(baseIP))
  		ips.push(baseIP);	 // At least get the IP_address field

  	this.deviceIPs = ips;
  },	

  _collectRouters: function() {
  	var queried = { };

  	// Collect all the routers that the IP address is part of...
  	for (var i = 0; i < this.deviceIPs.length; i++) {
  		var ip_address = this.deviceIPs[i];
  		var routing_tables = "cmdb_ci_ip_switch, cmdb_ci_ip_router";

  		var gr = new GlideRecord("dscy_route_interface");
  		gr.addQuery("cmdb_ci.sys_class_name", "IN", routing_tables);
  		gr.addQuery("sys_domain", this.deviceGr.sys_domain); // PRB1341362
  		gr.addQuery("install_status", 1); // only match installed routes - PRB1252594
  		if (ip_address.indexOf("/") > 0) {
  			var ip_network = new SncIPNetworkV4(ip_address),
  				hi_ip = new SncAddress32Bit(ip_network.getBroadcastAddress()).getAddressAsLong(),
  				lo_ip = new SncAddress32Bit(ip_network.getAddress()).getAddressAsLong(),
  				key = lo_ip + ":" + hi_ip;

  			if (queried[key])
  				continue;
  			queried[key] = true;

  			gr.addQuery("hi_ip", hi_ip);
  			gr.addQuery("lo_ip", lo_ip);
  		} else {
  			var ip_decimal = new SncAddress32Bit(ip_address).getAddressAsLong();
  			gr.addQuery("hi_ip", ">=", ip_decimal);
  			gr.addQuery("lo_ip", "<=", ip_decimal);
  		}
  		gr.query();

  		while (gr.next()) {
  			//PRB660627: filter out any routers with the default route (0.0.0.0)
  			var dest_ip_network = gr.getValue("dest_ip_network");
  			if (JSUtil.notNil(dest_ip_network) && !dest_ip_network.startsWith("0.0.0.0") && !gr.cmdb_ci.duplicate_of)
  				this.routers.push('' + gr.cmdb_ci);
  		}
  	}
  	var arrayUtil = new DiscoArrayUtil();
  	this.routers = arrayUtil.unique(this.routers);
  },

  _logError: function(msg) {
  	var logger,
  		gr = new GlideRecord('discovery_device_history');

  	if (gr.get('sys_id', current.sys_id)) {
  		logger = new DiscoveryLogger(gr.status, current.sys_id);
  		logger.setSource('DeviceL3Mapping');
  		this._logMsg = function(msg) { logger.error(msg); };
  	} else
  		this._logMsg = function(msg) { gs.error(msg, 'DeviceL3Mapping'); };

  	_this.logMsg(msg);
  }
};

Sys ID

0aa00c84ef52210098d5925495c0fb7a

Offical Documentation

Official Docs: