Next.js+React web interface for controlling HAProxy clusters (groups of servers), in conjunction with with https://gitgud.io/fatchan/haproxy-protection.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

88 lines
2.2 KiB

const url = require('url');
const fMap = {
[process.env.HOSTS_MAP_NAME]: {
fname: 'Backends',
description: 'Backend IP mappings for domains',
columnNames: ['Domain', 'Backend'],
},
[process.env.DDOS_MAP_NAME]: {
fname: 'Protection Rules',
description: 'Rules for protection mode on domains and/or paths',
columnNames: ['Domain/Path', 'Mode'],
},
[process.env.BLOCKED_MAP_NAME]: {
fname: 'IP Blacklist',
description: 'IPs/subnets that are outright blocked',
columnNames: ['IP/Subnet', ''],
},
[process.env.WHITELIST_MAP_NAME]: {
fname: 'IP Whitelist',
description: 'IPs/subnets that bypass protection rules',
columnNames: ['IP/Subnet', ''],
},
[process.env.MAINTENANCE_MAP_NAME]: {
fname: 'Maintenance Mode',
description: 'Disable proxying and show maintenance page for selected domains',
columnNames: ['Domain', ''],
},
[process.env.REWRITE_MAP_NAME]: {
fname: 'Redirects',
description: 'Easily redirect domains to an updated domain and/or path',
columnNames: ['Domain', 'Replacement'],
},
// [process.env.BACKENDS_MAP_NAME]: {
// fname: 'Domain Backend Mappings',
// description: 'Which internal server haproxy uses for domains',
// columnNames: ['Domain', 'Server Name'],
// },
};
module.exports = {
fMap,
makeArrayIfSingle: (obj) => !Array.isArray(obj) ? [obj] : obj,
validClustersString: (string) => {
return !string.split(',').some(c => {
const cUrl = url.parse(c);
return (cUrl.protocol !== 'http:' || !cUrl.hostname)
});
},
extractMap: (item) => {
const name = item.file && item.file.match(/\/etc\/haproxy\/map\/(?<name>.+).map/).groups.name;
if (!fMap[name]) { return null; }
const count = item.description && item.description.match(/(?:.+entry_cnt=(?<count>\d+)$)?/).groups.count;
return {
name,
count,
id: item.id,
...fMap[name],
};
},
dynamicResponse: (req, res, code, data) => {
const isRedirect = code === 302;
if (req.headers && req.headers['content-type'] === 'application/json') {
return res
.status(isRedirect ? 200 : code)
.json(data);
}
if (isRedirect) {
return res.redirect(data.redirect);
}
//TODO: pass through app (bind to middleware) and app.render an "error" page for nojs users?
return res.status(code).send(data);
},
};