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
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);
|
|
},
|
|
|
|
};
|
|
|