Closed yurividal closed 10 months ago
Hey @yurividal, sorry for the late reply and that I missed this comment.
No, currently HA deployment is not supported. FiberGlass currently only supports running on a single server, using the flat files from ISC-DHCP as the "database".
Eventually we may try to work on supporting Kea DHCP's PostgreSQL option, which could allow for something akin to an HA deployment. But for now, it's just flat files on a single server.
I know this is closed but here is a suggestion on the HA environment, at least as a short-term fix you could make the lease-parser.js skip the leases that are not true leases. Obviously, you still have to run an instance on each server so you can't get away from that but at least it cleans up the lease table page of all the "Undefined" entries. Not really a solution but as far as I can tell it works for me in a fail-over setup.
Here is updated lease-parser.js file:
/**
* Created by cmiles on 8/9/2017.
*/
module.exports = {
parse: function (input) {
var lease_data = input.split('lease')
for (i = 0; i < lease_data.length; i++) {
ip_address = ''
lines = lease_data[i].split('\n')
for (l = 0; l < lines.length; l++) {
/**
* Trim whitespaces at each end of the line
*/
lines[l] = lines[l].trim()
/**
* Break each newline into an array split into spaces
* Ex: [ 'starts', '3', '2017/08/09', '04:50:53;' ]
*
* @type {string[]}
*/
line_data_arg = lines[l].split(' ')
if (
/{/i.test(lines[l]) &&
/\./i.test(lines[l]) &&
!/uid/i.test(lines[l])
) {
ip_address = line_data_arg[0].trim()
if (typeof dhcp_lease_data[ip_address] === 'undefined') {
dhcp_lease_data[ip_address] = {}
}
option_data = {}
}
if (ip_address !== '') {
if (/start/i.test(lines[l])) {
/*
Make sure we force format as UTC because that is what the leases are formatted in
*/
date =
(line_data_arg[2] + ' ' + line_data_arg[3])
.trim()
.replace(/\//gi, '-')
.replace(/;/i, '') + ' UTC'
start_unix_time = Date.parse(date) / 1000
dhcp_lease_data[ip_address].start = start_unix_time
}
if (/ends/i.test(lines[l])) {
/*
Make sure we force format as UTC because that is what the leases are formatted in
*/
lease_end =
(line_data_arg[2] + ' ' + line_data_arg[3])
.trim()
.replace(/\//gi, '-')
.replace(/;/i, '') + ' UTC'
now_unix_time = parseInt((new Date().getTime() / 1000).toFixed(0))
end_unix_time = parseInt(
(new Date(lease_end).getTime() / 1000).toFixed(0).toLocaleString()
)
/*
console.log('now ' + now_unix_time);
console.log('end ' + end_unix_time);
console.log('now ' + new Date());
console.log('end_raw ' + lease_end);
console.log('end ' + new Date(lease_end));
*/
if (end_unix_time <= now_unix_time) {
delete dhcp_lease_data[ip_address]
break
}
dhcp_lease_data[ip_address].end = end_unix_time
}
if (/ethernet/i.test(lines[l])) {
if (typeof line_data_arg[2] !== 'undefined') {
dhcp_lease_data[ip_address].mac = line_data_arg[2]
.replace(/;/gi, '')
.trim()
if (
dhcp_lease_data[ip_address].mac.split(':').join('').trim() ===
''
)
continue
if (
dhcp_lease_data[ip_address].mac
.split(':')
.join('')
.toUpperCase()
.trim() === ''
)
continue
/* Mac OUI Lookup */
var mac_oui = dhcp_lease_data[ip_address].mac
.split(':')
.join('')
.toUpperCase()
.slice(0, 6)
dhcp_lease_data[ip_address].mac_oui_vendor = ''
if (typeof oui_data[mac_oui] !== 'undefined') {
dhcp_lease_data[ip_address].mac_oui_vendor = oui_data[mac_oui]
}
}
}
if (/hostname/i.test(lines[l])) {
if (typeof line_data_arg[1] !== 'undefined')
dhcp_lease_data[ip_address].host = line_data_arg[1]
.replace(/;/gi, '')
.replace(/"/gi, '')
.trim()
}
if (/set/i.test(lines[l])) {
set_data = lines[l]
.replace(/;/gi, '')
.replace(/"/gi, '')
.replace(/ = /gi, ' ')
.replace(/set/gi, '')
.trim()
set_data_split = set_data.split(' ')
option_key = set_data_split[0].trim()
option_value = set_data.replace(RegExp(option_key, 'g'), '').trim()
option_data[option_key] = option_value
if (typeof dhcp_lease_data[ip_address]['options'] === 'undefined')
dhcp_lease_data[ip_address]['options'] = []
}
if (/binding state (backup|free);/i.test(lines[l])) {
// Skip the lease if it contains "binding state backup;" or "binding state free;"
delete dhcp_lease_data[ip_address];
break;
}
if (/option/i.test(lines[l])) {
set_data = lines[l]
.replace(/;/gi, '')
.replace(/"/gi, '')
.replace(/ = /gi, ' ')
.replace(/option/gi, '')
.trim()
set_data_split = set_data.split(' ')
option_key = set_data_split[0].trim()
option_value = set_data.replace(RegExp(option_key, 'g'), '').trim()
option_data[option_key] = option_value
if (typeof dhcp_lease_data[ip_address]['options'] === 'undefined')
dhcp_lease_data[ip_address]['options'] = []
}
if (
lines[l].charAt(0) === '}' &&
typeof dhcp_lease_data[ip_address]['options'] !== 'undefined'
) {
if (typeof option_data !== 'undefined') {
dhcp_lease_data[ip_address]['options'] = option_data
}
option_data = []
}
/* End of Lease */
if (lines[l].charAt(0) === '}') {
if (debug_watch_lease_parse_stream) {
console.log('[Glass Server] Lease Parse')
console.log(JSON.stringify(dhcp_lease_data[ip_address], null, 2))
}
}
}
}
}
return
},
parseV6: function (input) {
let leaseFileEntries = input.split('\n\n')
leaseFileEntries.forEach((entry) => {
// not every entry is guaranteed to be a lease block
// some entries are a line that starts with "server-duid"
const leaseBlock = entry.match(/iaaddr (?<v6_address>[^ ]+) {([\s\S]*?)}/)
if (leaseBlock) {
const v6_address = leaseBlock.groups.v6_address
// the addr is the key in each lease data object
// {
// "2600::0::0(you get the point)": {
// "start": "<date>",
// "end": "<date>"
// }
// }
v6_dhcp_lease_data[v6_address] = {}
const leaseInfo = leaseBlock[0]
const endMatch = leaseInfo.match(
/ends (?<end_time>\d+ \d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2});/
)
if (endMatch) {
const endDate = endMatch.groups.end_time
.split(' ')[1]
.trim()
.split('/')
.join('-')
const endTime = endMatch.groups.end_time.split(' ')[2].trim()
const endDateTime = `${endDate} ${endTime} UTC`
const endUnixTime = Date.parse(endDateTime) / 1000
v6_dhcp_lease_data[v6_address] = {
end: endUnixTime,
}
}
}
})
return
},
clean: function () {
for (var key in dhcp_lease_data) {
now_unix_time = parseInt((new Date().getTime() / 1000).toFixed(0))
end_unix_time = dhcp_lease_data[key].end
if (now_unix_time >= end_unix_time) {
console.log(
'[DHCP Lease Data] Lease ' + key + ' has expired - clearing'
)
delete dhcp_lease_data[key]
}
}
},
}
or just add the following to line 139
if (/binding state (backup|free);/i.test(lines[l])) { // Skip the lease if it contains "binding state backup;" or "binding state free;" delete dhcp_lease_data[ip_address]; break; }
This probably isn't the end all but it will make having an HA setup a little cleaner at least in the meantime.
Does this front-end support multiple ISC DHCP backends?