feat: Implement server filters management API and integrate filter handling in FilterManager for enhanced server configuration capabilities
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 6m25s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 6m25s
This commit is contained in:
@@ -648,6 +648,137 @@ app.delete('/api/server-configs/:serverId', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// --- Server Filters Routes ---
|
||||
|
||||
// Get server filters
|
||||
app.get('/api/server-filters/:serverId', async (req, res) => {
|
||||
const { serverId } = req.params;
|
||||
const params = {
|
||||
Bucket: BUCKET_NAME,
|
||||
Key: `server-filters-${serverId}.json`,
|
||||
};
|
||||
|
||||
try {
|
||||
const data = await s3.getObject(params).promise();
|
||||
const fileContent = data.Body.toString('utf-8');
|
||||
let filters = [];
|
||||
|
||||
try {
|
||||
filters = JSON.parse(fileContent);
|
||||
if (!Array.isArray(filters)) {
|
||||
filters = [];
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.error('Error parsing server filters:', parseError);
|
||||
filters = [];
|
||||
}
|
||||
|
||||
res.json(filters);
|
||||
} catch (error) {
|
||||
if (error.code === 'NoSuchKey') {
|
||||
res.json([]); // Return empty array if file does not exist
|
||||
} else {
|
||||
console.error(error);
|
||||
res.status(500).send('Error reading server filters from S3');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update server filters
|
||||
app.post('/api/server-filters/:serverId', async (req, res) => {
|
||||
const { serverId } = req.params;
|
||||
const { filters } = req.body;
|
||||
|
||||
// Validate filters structure
|
||||
if (!Array.isArray(filters)) {
|
||||
return res.status(400).send('Filters must be an array');
|
||||
}
|
||||
|
||||
// Validate each filter has required fields
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
const filter = filters[i];
|
||||
if (!filter.community || !filter.gateway) {
|
||||
return res.status(400).send(`Filter at index ${i} is missing required fields`);
|
||||
}
|
||||
}
|
||||
|
||||
const params = {
|
||||
Bucket: BUCKET_NAME,
|
||||
Key: `server-filters-${serverId}.json`,
|
||||
Body: JSON.stringify(filters, null, 2), // Pretty print JSON
|
||||
ContentType: 'application/json',
|
||||
};
|
||||
|
||||
try {
|
||||
await s3.putObject(params).promise();
|
||||
res.send('Server filters updated successfully');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send('Error writing server filters to S3');
|
||||
}
|
||||
});
|
||||
|
||||
// Generate MikroTik configuration from server filters
|
||||
app.post('/api/server-filters/generate-config', async (req, res) => {
|
||||
const { filters } = req.body;
|
||||
|
||||
if (!Array.isArray(filters) || filters.length === 0) {
|
||||
return res.json({ config: '// No filters to generate configuration' });
|
||||
}
|
||||
|
||||
// Group filters by gateway
|
||||
const gatewayGroups = {};
|
||||
filters.forEach(filter => {
|
||||
if (!gatewayGroups[filter.gateway]) {
|
||||
gatewayGroups[filter.gateway] = [];
|
||||
}
|
||||
gatewayGroups[filter.gateway].push(filter.community);
|
||||
});
|
||||
|
||||
let config = '// Frouting filter configuration for MikroTik 7.14+\n';
|
||||
config += '// Generated automatically\n';
|
||||
config += `// Date: ${new Date().toISOString()}\n\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 += ` \nor `;
|
||||
}
|
||||
});
|
||||
config += `\n)\n{\n set gw ${gateway}; accept;\n}\nelse\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 += ` \nor `;
|
||||
}
|
||||
});
|
||||
config += `\n)\n{\n set gw ${gateway}; accept;\n}`;
|
||||
|
||||
if (gatewayIndex === gatewayEntries.length - 1) {
|
||||
config += `\nelse\n{\n reject;\n}\n`;
|
||||
} else {
|
||||
config += `\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
res.json({ config });
|
||||
});
|
||||
|
||||
// The "catchall" handler: for any request that doesn't
|
||||
// match one above, send back React's index.html file.
|
||||
app.get('*', (req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user