Name
global.LBModule
Description
Provide functions to populate load-balancing information in the corresponding tables.
Script
// Discovery
var LBModule = Class.create();
LBModule.prototype = {
discoveredServices : [],
discoveredPools : [],
discoveredPoolMembers : [],
data : [],
initialize: function() {
this.type = '';
},
// populate the load_balancer in cmdb_ci_lb_appl
updateLbTable: function(serverName, ip, lbTable) {
var appTable = 'cmdb_ci_lb_appl';
var lbName = this.type+'@'+serverName;
var curTime = new GlideDateTime();
if (lbTable != undefined)
appTable = lbTable;
var lbGr = new GlideRecord(appTable);
lbGr.addQuery('name',lbName);
lbGr.addQuery('ip_address',ip);
lbGr.query();
if (!lbGr.next()) {
lbGr.initialize ();
lbGr.setValue('name', lbName);
lbGr.setValue('ip_address', ip);
lbGr.setValue('last_discovered', curTime);
lbGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
lbGr.insert();
} else {
lbGr.setValue('last_discovered', curTime);
lbGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
lbGr.update();
}
return lbGr;
},
updateNginxLbTable: function(serverName, ip, lbTable, hostCISysId, hostTable, webserverSysId) {
var appTable = 'cmdb_ci_lb_appl';
var lbName = this.type + '@' + serverName;
var RunsOn_Runs = '60bc4e22c0a8010e01f074cbe6bd73c3';
if (lbTable != undefined)
appTable = lbTable;
var lbNginxGr = new GlideRecord(appTable);
lbNginxGr.addQuery('name', lbName);
lbNginxGr.query();
while (lbNginxGr.next()) {
// Multiple Nginx load balancers can share same names, hence fetching
// the relevant load balancer using the web server it is associated to
var webserverGr = new GlideRecord('cmdb_rel_ci');
webserverGr.addQuery('parent', webserverSysId);
webserverGr.addQuery('child', lbNginxGr.getValue('sys_id'));
webserverGr.query();
if (webserverGr.next()) {
/*
If Run On::Runs relationship doesn't exist between Nginx load balancer and Host CI,
then create one and then call IRE. Previously, IRE was not used to identify the CI
and the code was not populating relationship, it was only performing insert/update
on CI using GlideRecord. Now when the flow is switched to IRE, it tries to find the
dependent relationship, if it doesn't exist it creates a new Nginx Load balancer CI
though it exists leading to duplicates. To avoid this duplication, the relationship
record is first created in the below code before invoking the IRE
*/
new DiscoveryFunctions().createRelationshipIfNotExists(lbNginxGr.getValue('sys_id'), hostCISysId, 'Runs on::Runs');
break;
}
}
/* Sample payload
{
"items": [
{
"className": "cmdb_ci_lb_nginx",
"values": {
"name": "Nginx@nginxproxyl7mig-jt65"
}
},
{
"className": "cmdb_ci_linux_server",
"values": {
"sys_id": "e3a0f6828783495038370e19dabb358a"
}
}
],
"relations": [
{
"type": "Runs on::Runs",
"parent": 0,
"child": 1
}
]
}
*/
var payload = {
"items": [{
"className": appTable,
"values": {
"name": lbName
}
},
{
"className": hostTable + '',
"values": {
"sys_id": hostCISysId
}
}
],
"relations": [{
"parent": 0,
"child": 1,
"type": "Runs on::Runs"
}]
};
var json = new JSON();
var output = json.decode(SNC.IdentificationEngineScriptableApi.createOrUpdateCI(gs.getProperty('glide.discovery.source_name', "ServiceNow"), json.encode(payload)));
var lbSysId = output.items[0].sysId;
var lbGr = new GlideRecord(appTable);
lbGr.get('sys_id', lbSysId);
return lbGr;
},
// populate the service in cmdb_ci_lb_service table
updateServiceTable: function(service) {
var curTime = new GlideDateTime();
var serviceGr = new GlideRecord('cmdb_ci_lb_service');
serviceGr.addQuery('name', service.name);
serviceGr.addQuery('ip_address', service.ip_address);
serviceGr.addQuery('port', service.port);
serviceGr.addQuery('load_balancer', service.load_balancer);
if (service.input_url != undefined)
serviceGr.addQuery('input_url', service.input_url);
serviceGr.query();
if (!serviceGr.next()) {
serviceGr.initialize();
for (var key in service)
serviceGr.setValue(key, service[key]);
serviceGr.setValue('last_discovered', curTime);
serviceGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
serviceGr.insert();
} else {
serviceGr.setValue('last_discovered', curTime);
serviceGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
if (serviceGr.install_status == 100) // if previously 'Absent' update to 'Installed'
serviceGr.install_status = 1;
serviceGr.update();
}
this.discoveredServices.push(serviceGr.sys_id);
return serviceGr;
},
// populate pool information in cmdb_ci_lb_pool table
updatePoolTable: function(poolName, lbMethod, lbGr, serviceGr) {
var sysId = lbGr.sys_id+ '';
var poolSysId = null;
var curTime = new GlideDateTime ();
var poolGr = new GlideRecord('cmdb_ci_lb_pool');
poolGr.addQuery('name', poolName);
poolGr.addQuery('load_balancer', sysId);
poolGr.query ();
if (!poolGr.next ()) {
poolGr.initialize ();
poolGr.setValue('name', poolName);
poolGr.setValue('load_balancer', sysId);
poolGr.setValue('load_balancing_method', lbMethod);
poolGr.setValue('last_discovered', curTime);
poolGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
poolSysId = poolGr.insert();
} else {
poolGr.setValue('last_discovered', curTime);
poolGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
if (poolGr.install_status == 100) // if previously 'Absent' update to 'Installed'
poolGr.install_status = 1;
poolSysId = poolGr.update();
}
serviceGr.setValue('pool', poolSysId);
serviceGr.update();
// create relation between service service and pool pool
if (poolSysId)
g_disco_functions.createRelationshipIfNotExists(serviceGr.sys_id+'', poolGr.sys_id+'', 'Uses::Used by');
this.discoveredPools.push(poolSysId);
return poolGr;
},
// populate pool members information in cmdb_ci_lb_pool_member table
updatePoolMemberTable: function (lbMember, poolGr) {
var curTime = new GlideDateTime ();
var memberSysId = null;
var pmGr = new GlideRecord('cmdb_ci_lb_pool_member');
pmGr.addQuery('name', lbMember.name);
pmGr.addQuery('service_port', lbMember.service_port);
pmGr.addQuery('load_balancer', poolGr.getValue('load_balancer'));
if (lbMember.fqdn != undefined)
pmGr.addQuery('fqdn', lbMember.fqdn);
else
pmGr.addQuery('ip_address', lbMember.ip_address);
//pmGr.addQuery('pool',poolGr.getValue('sys_id')+'');
pmGr.query();
if (!pmGr.next()) {
pmGr.initialize();
for (var key in lbMember)
pmGr.setValue(key,lbMember[key]);
pmGr.setValue('last_discovered', curTime);
pmGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
pmGr.setValue('pool', poolGr.getValue('sys_id'));
memberSysId = pmGr.insert ();
} else {
pmGr.setValue ('last_discovered', curTime);
pmGr.setValue('discovery_source', gs.getProperty('glide.discovery.source_name', "ServiceNow"));
if (pmGr.install_status == 100) // if previously 'Absent' update to 'Installed'
pmGr.install_status = 1;
pmGr.setValue('pool', poolGr.getValue('sys_id'));
memberSysId = pmGr.update ();
}
// create relation between service tp pool (has to be completed)
if (memberSysId)
g_disco_functions.createRelationshipIfNotExists(poolGr.sys_id+'', pmGr.sys_id+'', 'Members::Member of');
this.discoveredPoolMembers.push(memberSysId);
},
// reconcile services, pools and pool members of a load balancer.
reconcile: function(lbSysId){
this._reconcile('cmdb_ci_lb_pool_member', this.discoveredPoolMembers, lbSysId);
this._reconcile('cmdb_ci_lb_pool', this.discoveredPools,lbSysId);
this._reconcile('cmdb_ci_lb_service', this.discoveredServices, lbSysId);
},
// reconcile data in a table for a load balancer based on discovered data
// mark record 'Absent' if not found
_reconcile: function (table, populatedData, lbSysId) {
var gr = new GlideRecord(table);
gr.addQuery('load_balancer', lbSysId);
gr.query();
while (gr.next()) {
var found = false;
for (var i = 0; i < populatedData.length && !found; i++) {
if (populatedData[i] == gr.getValue('sys_id'))
found = true;
}
if (!found) {
gr.install_status = 100; // 'Absent'
gr.update();
}
}
},
/*
* not currently called, it was used when we were deleting on reconcile
* but now we are marking absent and the relationships are allowed to remain
*/
_reconcileRelations: function(delSysId) {
var relGr = new GlideRecord('cmdb_rel_ci');
var gr1 = relGr.addQuery('parent', delSysId);
gr1.addOrCondition('child', delSysId);
relGr.query();
relGr.deleteMultiple();
},
type: 'LBModule'
};
Sys ID
cd56914cd74221002f04ee5b5e6103ac