Name
global.HAProxy
Description
Process the HAProxy load balancer information collected by the probe.
Script
// Discovery
var HAProxy = Class.create();
HAProxy.prototype = Object.extendsObject (LBModule, {
initialize: function(blocks, lbGr, serverIP, serverName) {
this.frontends = blocks.frontendList;
this.backends = blocks.backendList;
this.listens = blocks.listenList;
this.hosts = blocks.hostList;
this.lbGr = lbGr;
this.serverIP = serverIP;
this.serverName = serverName;
this.type = 'HAProxy';
},
// Populate HAProxy information
populateInfo: function () {
if (this.serverName.indexOf('.') != -1)
this.serverName = this.serverName.split('.')[0];
var poolName = '';
// process frontend block information and populate information
for (var i = 0; i < this.frontends.length; i++) {
var curFrontend = this.frontends[i];
curFrontend.type = 'frontend';
// Process Pool information from used_bckends defined in the frontend blocks
for (var j =0; j < curFrontend.useBackends.length; j++){
poolName = curFrontend.useBackends[j].name;
this.processBlockInfo ( curFrontend, poolName, j);
}
// For every frontend block if the default_backend is defined all requests that are not matching
// to any acl condition will be passed to the default_backend
if (curFrontend.default_backend != undefined) {
poolName = curFrontend.default_backend;
this.processBlockInfo (curFrontend, poolName);
}
}
// process listen blocks information and populate information
for (var key in this.listens) {
var curListen = this.listens[key];
curListen.type = 'listen';
// Process Pool information from used_backends defined in listen blocks
for (i = 0; i < curListen.usedBackends.length; i++) {
poolName = curListen.usedBackends[i].name;
this.processBlockInfo (curListen, poolName, i);
}
// Only process the backends defining backend servers (pool containing atleast one member)
if (curListen.servers.length == 0)
continue;
this.processBlockInfo(curListen,curListen.name);
}
this.reconcile(this.lbGr.getValue('sys_id'));
},
/*
* Populate LB information for a frontend or listen block
* The required information in these blocks are defined with different syntax.
* block: a frontend or listen block
* poolName: a pool (backend block) for that LB information will be populate
* bIndex : This input is only passed if the pool is corresponding to use_backend
* In this case it is the index of the pool in used_backend list in the frontend or listen block
*
*/
processBlockInfo: function (block, poolName, bIndex) {
var msg = '';
if ( this.backends[poolName] == undefined && this.listens[poolName] == undefined)
return;
var lbMethod = 'round-robin';
if ( this.backends[poolName] != undefined)
lbMethod = this.getBalanceMethod (this.backends[poolName]);
if ( this.listens[poolName] != undefined )
lbMethod = this.getBalanceMethod (this.listens[poolName]);
var serviceGrList = this.populateServiceInfo (block,bIndex);
if (serviceGrList.length < 1)
return;
for ( var k = 0; k < serviceGrList.length; k++) {
var serviceGr = serviceGrList[k];
var poolGr = this.updatePoolTable ( poolName, lbMethod, this.lbGr, serviceGr);
if (!gs.nil(poolGr))
this.populatePoolMembers (poolGr, block.type);
else {
msg = 'No load balancer services found for ' + poolName;
DiscoveryLogger.warn (msg,'HAProxy - Get Configuration',this.getEccQueueId(),null);
}
}
},
/*
* populate service information for a block.
* This service can be corresponding to a defaultbackend or realted to acl or listen block.
* based on the value of bIndex we define the service is related to which block
*/
populateServiceInfo: function (block, bIndex) {
var serviceList = [];
for (var i = 0; i< block.bind.length ; i++) {
var service = {};
var port = block.bind[i].startPort;
if (block.bind[i].endPort != undefined) {
port += '-'+ block.bind[i].endPort;
service.last_port = block.bind[i].endPort;
}
service.name = 'HAProxy@' + this.serverName + ':' + port;
service.port = block.bind[i].startPort;
service.ip_address = block.bind[i].ip;
if ( service.ip_address == '*' || service.ip_address == '127.0.0.0')
service.ip_address = this.serverIP;
if (bIndex != undefined) {
var aclName = block.useBackends[bIndex].acl;
if (block.aclList[aclName] != undefined) {
if (block.useBackends[bIndex].condition == 'unless')
service.name = 'HAProxy_unless_'+ aclName + '@' + this.serverName + ':' + port;
else
service.name = 'HAProxy_if_'+ aclName + '@' + this.serverName + ':' + port;
}
} else {
if (block.type == 'frontend')
service.name = 'HAProxy_defaultBackend@' + this.serverName + ':' + port;
else
service.name = 'HAProxy_listen@' + this.serverName + ':' + port;
}
service.load_balancer = this.lbGr.sys_id + '';
serviceList.push (this.updateServiceTable (service));
}
return serviceList;
},
getBalanceMethod: function(block) {
if ( block.balance == undefined )
return 'round-robin';
var method = 'round-robin';
switch (block.balance) {
case 'leastconn': method = 'least-connections';
break;
case 'source':
case 'uri':
case 'static-rr': method = block.balance;
break;
case 'url_param': method = 'url-param';
break;
}
return method;
},
/*
* The pool memebrs information is collected from the
* block in where are defined. Listen blocks or backend blocks
*/
populatePoolMembers: function (poolGr, blockType) {
var poolName = poolGr.getValue ('name');
var pool = '';
if (blockType == 'listen' && this.listens[poolName] != undefined)
pool = this.listens[poolName];
else
pool = this.backends[poolName];
for (var i = 0; i < pool.servers.length; i++){
var server = pool.servers[i];
var member = {};
member.name = server.name;
member.ip_address = '';
if (this.isValidIPv4(server.ip))
member.ip_address = server.ip;
else {
member.fqdn = server.ip;
if (this.hosts [server.ip] != undefined )
member.ip_address = this.hosts[server.ip];
}
member.service_port = server.port;
member.load_balancer = this.lbGr.sys_id + '';
this.updatePoolMemberTable (member, poolGr);
}
},
/*
* Check if a string for ip is an IPv4 ?
*/
isValidIPv4: function(ip) {
try {
var valid = new SncAddress32Bit(ip);
} catch (ex) {
return false;
}
return true;
},
type: 'HAProxy'
});
Sys ID
e5dbb7aed7222100a866ee5b5e61032b