feat(NetworkMapDashboard): improve ping functionality by utilizing internal tunnel IPs for enhanced connectivity checks
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m3s

This commit is contained in:
2026-02-17 16:35:42 +07:00
parent 683f837b36
commit 7be656c3f2
+42 -33
View File
@@ -56,12 +56,18 @@ export default function NetworkMapDashboard() {
const s1 = getServer(iface.serverId);
const s2 = getServer(iface.serverId2);
if (!s1 || !s2 || s1.ip === s2.ip) return;
const s1Key = s1.id || s1.dns || s1.ip;
const s2Key = s2.id || s2.dns || s2.ip;
if (!s1Key || !s2Key) return;
connList.push({
from: s1.ip,
to: s2.ip,
tunnelType: iface.type || 'GRE',
ipA: iface.localIp,
ipB: iface.remoteIp,
// Внутренние IP туннеля: с сервера 1 до сервера 2 и обратно
fromKey: s1Key,
toKey: s2Key,
internalFromTo: iface.remoteIp || null, // ping: server1 -> remoteIp
internalToFrom: iface.localIp || null, // ping: server2 -> localIp
});
});
@@ -91,42 +97,45 @@ export default function NetworkMapDashboard() {
if (!from || !to || from === to) return;
const srcFrom = servers.find((s) => s.ip === from);
const srcTo = servers.find((s) => s.ip === to);
const canPingFrom = srcFrom && ['jumphost', 'home'].includes(String(srcFrom.type || '').toLowerCase());
const canPingTo = srcTo && ['jumphost', 'home'].includes(String(srcTo.type || '').toLowerCase());
const canPingFrom =
srcFrom && ['jumphost', 'home'].includes(String(srcFrom.type || '').toLowerCase()) && c.internalFromTo;
const canPingTo =
srcTo && ['jumphost', 'home'].includes(String(srcTo.type || '').toLowerCase()) && c.internalToFrom;
// Пингуем только с jumphost/home, иначе бекенд возвращает E_PING (сервер не найден)
// Пингуем по ВНУТРЕННИМ адресам туннеля из /network-config:
// server1 -> remoteIp, server2 -> localIp. serverId — ключ (id/dns/ip) как в servers.json.
if (canPingFrom) {
tasks.push(async () => {
if (pingAbortRef.current) return;
try {
const { data } = await api.post('/mikrotik/ping', {
serverId: from,
target: to,
count: 3,
});
const ms = typeof data?.avgMs === 'number' ? Math.round(data.avgMs) : null;
return { key: key(from, to), ms };
} catch {
return { key: key(from, to), ms: null };
}
});
tasks.push(async () => {
if (pingAbortRef.current) return;
try {
const { data } = await api.post('/mikrotik/ping', {
serverId: c.fromKey,
target: c.internalFromTo,
count: 3,
});
const ms = typeof data?.avgMs === 'number' ? Math.round(data.avgMs) : null;
return { key: key(from, to), ms };
} catch {
return { key: key(from, to), ms: null };
}
});
}
if (canPingTo) {
tasks.push(async () => {
if (pingAbortRef.current) return;
try {
const { data } = await api.post('/mikrotik/ping', {
serverId: to,
target: from,
count: 3,
});
const ms = typeof data?.avgMs === 'number' ? Math.round(data.avgMs) : null;
return { key: key(to, from), ms };
} catch {
return { key: key(to, from), ms: null };
}
});
tasks.push(async () => {
if (pingAbortRef.current) return;
try {
const { data } = await api.post('/mikrotik/ping', {
serverId: c.toKey,
target: c.internalToFrom,
count: 3,
});
const ms = typeof data?.avgMs === 'number' ? Math.round(data.avgMs) : null;
return { key: key(to, from), ms };
} catch {
return { key: key(to, from), ms: null };
}
});
}
});