93 lines
2.5 KiB
JavaScript
93 lines
2.5 KiB
JavaScript
/**
|
|
* Вспомогательные утилиты
|
|
*/
|
|
|
|
const crypto = require('crypto');
|
|
|
|
/**
|
|
* Конвертировать дату в ISO строку
|
|
*/
|
|
function toIso(x) {
|
|
try { return new Date(x).toISOString(); } catch { return null; }
|
|
}
|
|
|
|
/**
|
|
* Разбить строку по пробелам
|
|
*/
|
|
function splitWhitespace(line) {
|
|
return String(line || '').trim().split(/\s+/);
|
|
}
|
|
|
|
/**
|
|
* Вычислить SHA256 хэш строки
|
|
*/
|
|
function sha256OfString(s) {
|
|
return crypto.createHash('sha256').update(Buffer.from(String(s), 'utf-8')).digest('hex');
|
|
}
|
|
|
|
/**
|
|
* Преобразовать ошибки AJV в читаемый формат
|
|
*/
|
|
function mapAjvErrors(errors) {
|
|
if (!Array.isArray(errors)) return [];
|
|
return errors.map((e) => ({
|
|
message: e.message,
|
|
instancePath: e.instancePath,
|
|
keyword: e.keyword,
|
|
params: e.params,
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Маппинг UI ресурсов на S3 ключи (для истории версий)
|
|
*/
|
|
function resourceToKey(resource) {
|
|
switch (resource) {
|
|
case 'domains-new': return 'bgp_data/domains_community.txt';
|
|
case 'ip-ranges': return 'bgp_data/ips.txt';
|
|
case 'asns': return 'bgp_data/asns.txt';
|
|
default: return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Построить вложенные if/else блоки для MikroTik конфигурации
|
|
*/
|
|
function buildNestedGatewayBlocks(gatewayGroups, baseIndentSpaces = 4) {
|
|
const indent = (n) => ' '.repeat(n);
|
|
const entries = Object.entries(gatewayGroups);
|
|
if (entries.length === 0) return '';
|
|
|
|
function buildAt(index, pad) {
|
|
const [gateway, communities] = entries[index];
|
|
let s = '';
|
|
s += `${indent(pad)}if (\n`;
|
|
communities.forEach((community, i) => {
|
|
s += `${indent(pad + 4)}(bgp-communities includes ${community})`;
|
|
if (i < communities.length - 1) s += ' or \n';
|
|
});
|
|
s += `\n${indent(pad)})\n`;
|
|
s += `${indent(pad)}{\n${indent(pad + 8 - 4)}set gw ${gateway}; accept;\n${indent(pad)}}\n`;
|
|
if (index < entries.length - 1) {
|
|
s += `${indent(pad)}else\n${indent(pad)}{\n`;
|
|
s += buildAt(index + 1, pad + 4);
|
|
s += `\n${indent(pad)}}`;
|
|
} else {
|
|
s += `${indent(pad)}else\n${indent(pad)}{\n${indent(pad + 4)}reject;\n${indent(pad)}}`;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
return buildAt(0, baseIndentSpaces);
|
|
}
|
|
|
|
module.exports = {
|
|
toIso,
|
|
splitWhitespace,
|
|
sha256OfString,
|
|
mapAjvErrors,
|
|
resourceToKey,
|
|
buildNestedGatewayBlocks,
|
|
};
|
|
|