feat: Implement nested if/else block generation for RouterOS configuration in gateway management to enhance filter logic and maintain compatibility
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 4m27s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 4m27s
This commit is contained in:
+35
-108
@@ -26,6 +26,35 @@ const s3 = new AWS.S3({
|
||||
const BUCKET_NAME = process.env.S3_BUCKET_NAME;
|
||||
const FILE_KEY = 'bgp_data/domains.txt';
|
||||
|
||||
// Helper: build MikroTik nested if/else blocks (RouterOS v7 filter language does not support 'else if')
|
||||
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);
|
||||
}
|
||||
|
||||
// Get domains from S3
|
||||
app.get('/api/domains', async (req, res) => {
|
||||
const params = {
|
||||
@@ -608,42 +637,8 @@ app.get('/api/filters/generate-config', async (req, res) => {
|
||||
config += `// Date: ${new Date().toISOString()}\n\n`;
|
||||
config += '/routing filter bgp-in-tmp {\n';
|
||||
|
||||
// Если есть только один gateway, создаем простую конфигурацию
|
||||
if (Object.keys(gatewayGroups).length === 1) {
|
||||
const [gateway, communities] = Object.entries(gatewayGroups)[0];
|
||||
config += ` if (\n`;
|
||||
communities.forEach((community, index) => {
|
||||
config += ` (bgp-communities includes ${community})`;
|
||||
if (index < communities.length - 1) {
|
||||
config += ` or \n`;
|
||||
}
|
||||
});
|
||||
config += `\n )\n {\n set gw ${gateway}; accept;\n }\n else\n {\n reject;\n }\n`;
|
||||
} else {
|
||||
// Если несколько gateway, создаем каскадную структуру
|
||||
const gatewayEntries = Object.entries(gatewayGroups);
|
||||
gatewayEntries.forEach(([gateway, communities], gatewayIndex) => {
|
||||
if (gatewayIndex === 0) {
|
||||
config += ` if (\n`;
|
||||
} else {
|
||||
config += ` else if (\n`;
|
||||
}
|
||||
|
||||
communities.forEach((community, index) => {
|
||||
config += ` (bgp-communities includes ${community})`;
|
||||
if (index < communities.length - 1) {
|
||||
config += ` or \n`;
|
||||
}
|
||||
});
|
||||
config += `\n )\n {\n set gw ${gateway}; accept;\n }`;
|
||||
|
||||
if (gatewayIndex === gatewayEntries.length - 1) {
|
||||
config += `\n else\n {\n reject;\n }\n`;
|
||||
} else {
|
||||
config += `\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Строим вложенные if/else (RouterOS не поддерживает else if в данном контексте)
|
||||
config += buildNestedGatewayBlocks(gatewayGroups, 4);
|
||||
|
||||
config += '}\n';
|
||||
|
||||
@@ -698,42 +693,8 @@ app.post('/api/filters/export-config', async (req, res) => {
|
||||
config += `// Date: ${new Date().toISOString()}\n\n`;
|
||||
config += '/routing filter bgp-in-tmp {\n';
|
||||
|
||||
// Если есть только один gateway, создаем простую конфигурацию
|
||||
if (Object.keys(gatewayGroups).length === 1) {
|
||||
const [gateway, communities] = Object.entries(gatewayGroups)[0];
|
||||
config += ` if (\n`;
|
||||
communities.forEach((community, index) => {
|
||||
config += ` (bgp-communities includes ${community})`;
|
||||
if (index < communities.length - 1) {
|
||||
config += ` or \n`;
|
||||
}
|
||||
});
|
||||
config += `\n )\n {\n set gw ${gateway}; accept;\n }\n else\n {\n reject;\n }\n`;
|
||||
} else {
|
||||
// Если несколько gateway, создаем каскадную структуру
|
||||
const gatewayEntries = Object.entries(gatewayGroups);
|
||||
gatewayEntries.forEach(([gateway, communities], gatewayIndex) => {
|
||||
if (gatewayIndex === 0) {
|
||||
config += ` if (\n`;
|
||||
} else {
|
||||
config += ` else if (\n`;
|
||||
}
|
||||
|
||||
communities.forEach((community, index) => {
|
||||
config += ` (bgp-communities includes ${community})`;
|
||||
if (index < communities.length - 1) {
|
||||
config += ` or \n`;
|
||||
}
|
||||
});
|
||||
config += `\n )\n {\n set gw ${gateway}; accept;\n }`;
|
||||
|
||||
if (gatewayIndex === gatewayEntries.length - 1) {
|
||||
config += `\n else\n {\n reject;\n }\n`;
|
||||
} else {
|
||||
config += `\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Строим вложенные if/else (RouterOS не поддерживает else if в данном контексте)
|
||||
config += buildNestedGatewayBlocks(gatewayGroups, 4);
|
||||
|
||||
config += '}\n';
|
||||
|
||||
@@ -977,42 +938,8 @@ app.post('/api/server-filters/generate-config', async (req, res) => {
|
||||
config += `// Date: ${new Date().toISOString()}\n\n`;
|
||||
config += '/routing filter bgp-in-tmp {\n';
|
||||
|
||||
// Если есть только один gateway, создаем простую конфигурацию
|
||||
if (Object.keys(gatewayGroups).length === 1) {
|
||||
const [gateway, communities] = Object.entries(gatewayGroups)[0];
|
||||
config += ` if (\n`;
|
||||
communities.forEach((community, index) => {
|
||||
config += ` (bgp-communities includes ${community})`;
|
||||
if (index < communities.length - 1) {
|
||||
config += ` or \n`;
|
||||
}
|
||||
});
|
||||
config += `\n )\n {\n set gw ${gateway}; accept;\n }\n else\n {\n reject;\n }\n`;
|
||||
} else {
|
||||
// Если несколько gateway, создаем каскадную структуру
|
||||
const gatewayEntries = Object.entries(gatewayGroups);
|
||||
gatewayEntries.forEach(([gateway, communities], gatewayIndex) => {
|
||||
if (gatewayIndex === 0) {
|
||||
config += ` if (\n`;
|
||||
} else {
|
||||
config += ` else if (\n`;
|
||||
}
|
||||
|
||||
communities.forEach((community, index) => {
|
||||
config += ` (bgp-communities includes ${community})`;
|
||||
if (index < communities.length - 1) {
|
||||
config += ` or \n`;
|
||||
}
|
||||
});
|
||||
config += `\n )\n {\n set gw ${gateway}; accept;\n }`;
|
||||
|
||||
if (gatewayIndex === gatewayEntries.length - 1) {
|
||||
config += `\n else\n {\n reject;\n }\n`;
|
||||
} else {
|
||||
config += `\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Строим вложенные if/else (RouterOS не поддерживает else if в данном контексте)
|
||||
config += buildNestedGatewayBlocks(gatewayGroups, 4);
|
||||
|
||||
config += '}\n';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user