feat(MikrotikConnection): add MikroTik connection testing functionality in ServerModal; update API routes and README for new encryption key and connection endpoint
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m13s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m13s
This commit is contained in:
@@ -13,6 +13,7 @@ const {
|
||||
buildMikrotikConfig,
|
||||
} = require('../utils/mikrotikInterfaceGenerator');
|
||||
const { readS3TextObject } = require('../services/s3Service');
|
||||
const { RouterOSAPI } = require('node-routeros');
|
||||
|
||||
async function fetchJsonFromS3(key, defaultValue = null) {
|
||||
try {
|
||||
@@ -162,8 +163,73 @@ async function generateRecursiveRoutes(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/mikrotik/test-connection
|
||||
* Body: { serverId?: string, host?, port?, user?, password? }
|
||||
* Если host/port/user/password переданы — тестирует с ними (без сохранения).
|
||||
* Иначе берёт credentials из сервера по serverId.
|
||||
*/
|
||||
async function testMikrotikConnection(req, res) {
|
||||
try {
|
||||
const { serverId, host: bodyHost, port: bodyPort, user: bodyUser, password: bodyPassword } = req.body || {};
|
||||
|
||||
let host, port, user, password;
|
||||
|
||||
if (bodyHost && bodyPassword) {
|
||||
host = bodyHost;
|
||||
port = parseInt(bodyPort || '8728', 10) || 8728;
|
||||
user = bodyUser || 'admin';
|
||||
password = bodyPassword;
|
||||
} else if (serverId) {
|
||||
const servers = await fetchJsonFromS3('servers.json', []);
|
||||
const server = servers.find(s => s.id === serverId || s.dns === serverId || s.ip === serverId);
|
||||
if (!server) {
|
||||
return sendError(res, 404, 'Server not found', 'E_NOT_FOUND');
|
||||
}
|
||||
if (server.type !== 'jumphost') {
|
||||
return sendError(res, 400, 'Only jumphost servers have MikroTik credentials', 'E_BAD_REQUEST');
|
||||
}
|
||||
if (!server.encryptedMikrotikPassword) {
|
||||
return sendError(res, 400, 'MikroTik password not configured for this server', 'E_BAD_REQUEST');
|
||||
}
|
||||
try {
|
||||
password = decrypt(server.encryptedMikrotikPassword);
|
||||
} catch (decErr) {
|
||||
return sendError(res, 500, 'Failed to decrypt MikroTik password', 'E_DECRYPT');
|
||||
}
|
||||
host = server.mikrotikHost || server.ip || server.dns;
|
||||
port = parseInt(server.mikrotikPort || '8728', 10) || 8728;
|
||||
user = server.mikrotikUser || 'admin';
|
||||
} else {
|
||||
return sendError(res, 400, 'Provide serverId or (host + password)', 'E_BAD_REQUEST');
|
||||
}
|
||||
|
||||
const conn = new RouterOSAPI({
|
||||
host: String(host),
|
||||
user: String(user),
|
||||
password: String(password),
|
||||
port: Number(port) || 8728,
|
||||
});
|
||||
|
||||
await conn.connect();
|
||||
await conn.write('/system/resource/print', []);
|
||||
conn.close();
|
||||
|
||||
res.json({ ok: true, message: 'Соединение успешно' });
|
||||
} catch (error) {
|
||||
const msg = error.message || String(error);
|
||||
res.status(400).json({
|
||||
ok: false,
|
||||
message: msg.includes('ECONNREFUSED') ? 'Соединение отклонено. Проверьте хост и порт.' :
|
||||
msg.includes('Authentication') || msg.includes('login') ? 'Неверный логин или пароль' :
|
||||
msg,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generateMikrotikConfig,
|
||||
generateInterfaces,
|
||||
generateRecursiveRoutes,
|
||||
testMikrotikConnection,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user