From d3bf307d6c28f64714a7ccfe75835a8732185d57 Mon Sep 17 00:00:00 2001 From: shats Date: Thu, 22 Jan 2026 12:05:07 +0700 Subject: [PATCH] feat(NetworkConfigManager, FilterManager): update gateway configuration to use IP as name; enhance filtering logic and UI to accommodate changes in gateway structure --- example/s3/network-config.json | 9 +- frontend/src/FilterManager.jsx | 5 +- frontend/src/NetworkConfigManager.jsx | 139 ++++++++++++++++---------- 3 files changed, 92 insertions(+), 61 deletions(-) diff --git a/example/s3/network-config.json b/example/s3/network-config.json index a33c6e5..b41155c 100644 --- a/example/s3/network-config.json +++ b/example/s3/network-config.json @@ -2,7 +2,6 @@ "gateways": [ { "id": "gw-cloudflare-swe", - "name": "SWE-IHOR", "ip": "94.142.140.1", "description": "Cloudflare Sweden - основной выход", "serverId": "SWE-HIPHOST", @@ -11,7 +10,6 @@ }, { "id": "gw-bunny-swe", - "name": "SWE-BUNNY", "ip": "94.142.140.2", "description": "Bunny CDN Sweden", "serverId": "SWE-HIPHOST", @@ -20,7 +18,6 @@ }, { "id": "gw-telegram-nl", - "name": "TG-PROXY-1", "ip": "149.154.167.50", "description": "Telegram DC2", "serverId": "NL-AMSTERDAM", @@ -29,7 +26,6 @@ }, { "id": "gw-hetzner-de", - "name": "DE-HETZNER", "ip": "195.100.30.21", "description": "Hetzner Frankfurt", "serverId": "DE-FRANKFURT", @@ -38,7 +34,6 @@ }, { "id": "gw-fastly-us", - "name": "US-FASTLY", "ip": "151.101.1.1", "description": "Fastly US East", "serverId": "US-NEWYORK", @@ -47,9 +42,8 @@ }, { "id": "gw-recursive-swe", - "name": "SWE-RECURSIVE", "ip": "10.0.0.1", - "description": "Рекурсивный gateway через SWE-IHOR", + "description": "Рекурсивный gateway через 94.142.140.1", "serverId": "SWE-HIPHOST", "country": "SWE", "type": "recursive", @@ -72,7 +66,6 @@ "type": "WireGuard", "localIp": "10.20.0.1", "remoteIp": "10.20.0.2", - "port": "51820", "serverId": "SWE-HIPHOST" }, { diff --git a/frontend/src/FilterManager.jsx b/frontend/src/FilterManager.jsx index 0abe5fc..80c56cd 100644 --- a/frontend/src/FilterManager.jsx +++ b/frontend/src/FilterManager.jsx @@ -789,9 +789,10 @@ function FilterManager() { }); networkGateways.forEach(gw => { + if (!gw.ip) return; // Пропускаем gateway без IP gws.push({ - name: gw.name, - ip: gw.ip || '', + name: gw.ip, // Используем IP как имя для совместимости со старой логикой + ip: gw.ip, comment: gw.description || '', serverDns: serverDns, country: country, diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index 5c147d0..24cba21 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -61,7 +61,6 @@ const GATEWAY_TYPES = [ // Пустые объекты const getEmptyGateway = () => ({ id: `gw-${Date.now()}-${Math.random().toString(16).slice(2, 6)}`, - name: '', ip: '', description: '', serverId: '', @@ -76,7 +75,6 @@ const getEmptyInterface = () => ({ type: 'GRE', localIp: '', remoteIp: '', - port: '', serverId: '', }); @@ -232,7 +230,6 @@ function NetworkConfigManager() { result = result.filter(g => { const server = getServerInfo(g.serverId); return ( - g.name?.toLowerCase().includes(term) || g.ip?.toLowerCase().includes(term) || g.country?.toLowerCase().includes(term) || server?.country?.toLowerCase().includes(term) || @@ -501,37 +498,48 @@ function NetworkConfigManager() { code += `\n# === Рекурсивные маршруты для сервера: ${serverName} ===\n`; gateways.forEach(gw => { - const parentGateway = getParentGateway(gw.parentGatewayId); + const parent = getParentGateway(gw.parentGatewayId); - if (!parentGateway) { - code += `\n# Gateway "${gw.name}" - родительский gateway не найден, пропущен\n`; + if (!parent) { + code += `\n# Gateway "${gw.ip || 'без IP'}" - родительский gateway/интерфейс не найден, пропущен\n`; return; } if (!gw.ip) { - code += `\n# Gateway "${gw.name}" - IP адрес не указан, пропущен\n`; + code += `\n# Gateway без IP адреса - пропущен\n`; return; } - if (!parentGateway.ip) { - code += `\n# Gateway "${gw.name}" - родительский gateway "${parentGateway.name}" не имеет IP, пропущен\n`; + // Определяем IP родителя в зависимости от типа + const parentIp = parent.type === 'interface' ? parent.remoteIp : parent.ip; + + if (!parentIp) { + const parentType = parent.type === 'interface' ? 'интерфейс' : 'gateway'; + code += `\n# Gateway "${gw.ip}" - родительский ${parentType} не имеет IP, пропущен\n`; return; } validRoutesCount++; // Создаём маршрут для рекурсивного gateway - // Маршрут к IP рекурсивного gateway направляется через родительский gateway - code += `\n# Рекурсивный gateway: ${gw.name} (IP: ${gw.ip})\n`; - code += `# Родительский gateway: ${parentGateway.name} (IP: ${parentGateway.ip})\n`; + const parentLabel = parent.type === 'interface' + ? `интерфейс ${parent.name || parent.type} (${parent.remoteIp})` + : `gateway ${parent.ip}`; + + code += `\n# Рекурсивный gateway: ${gw.ip}\n`; + code += `# Родительский: ${parentLabel}\n`; // Создаём маршрут к IP рекурсивного gateway через родительский - code += `/ip route add dst-address=${gw.ip}/32 gateway=${parentGateway.ip} comment="Recursive: ${gw.name} -> ${parentGateway.name}"\n`; + const comment = gw.description + ? `${gw.description} -> ${parentIp}` + : `Recursive: ${gw.ip} -> ${parentIp}`; + code += `/ip route add dst-address=${gw.ip}/32 gateway=${parentIp} comment="${comment}"\n`; // Если у рекурсивного gateway есть описание с указанием на default route if (gw.description && (gw.description.toLowerCase().includes('default') || gw.description.toLowerCase().includes('0.0.0.0'))) { code += `# Дополнительный default route через рекурсивный gateway\n`; - code += `/ip route add dst-address=0.0.0.0/0 gateway=${parentGateway.ip} comment="Recursive default: ${gw.name} -> ${parentGateway.name}"\n`; + const defaultComment = gw.description ? `${gw.description} (default)` : `Recursive default: ${gw.ip}`; + code += `/ip route add dst-address=0.0.0.0/0 gateway=${parentIp} comment="${defaultComment}"\n`; } }); }); @@ -650,10 +658,19 @@ function NetworkConfigManager() { ); }; - // === Получение родительского gateway === - const getParentGateway = (gatewayId) => { - if (!gatewayId) return null; - return config.gateways?.find(g => g.id === gatewayId); + // === Получение родительского gateway или интерфейса === + const getParentGateway = (parentId) => { + if (!parentId) return null; + + // Сначала ищем в gateway + const gateway = config.gateways?.find(g => g.id === parentId); + if (gateway) return { type: 'gateway', ...gateway }; + + // Если не найден, ищем в интерфейсах + const iface = config.tunnelInterfaces?.find(i => i.id === parentId); + if (iface) return { type: 'interface', ...iface }; + + return null; }; // === Рендер карточки Gateway === @@ -678,7 +695,7 @@ function NetworkConfigManager() {
- {gateway.name || '—'} + {gateway.ip || '—'} {gatewayType.label} @@ -730,7 +747,12 @@ function NetworkConfigManager() { {parentGateway && (
- Родитель: {parentGateway.name} + + Родитель: {parentGateway.type === 'interface' + ? `Интерфейс ${parentGateway.name || parentGateway.type} (${parentGateway.remoteIp})` + : `Gateway ${parentGateway.ip}` + } +
)} @@ -756,12 +778,11 @@ function NetworkConfigManager() {
{iface.name || '—'}
-
- - {iface.type} - - {iface.port && :{iface.port}} -
+
+ + {iface.type} + +
@@ -1112,7 +1133,10 @@ function NetworkConfigManager() { {parentGateway && (
- → {parentGateway.name} + → {parentGateway.type === 'interface' + ? `Интерфейс ${parentGateway.name || parentGateway.type} (${parentGateway.remoteIp})` + : `Gateway ${parentGateway.ip}` + }
)} @@ -1234,7 +1258,6 @@ function NetworkConfigManager() { Тип Local IP Remote IP - Порт Сервер Действия @@ -1265,7 +1288,6 @@ function NetworkConfigManager() { {iface.remoteIp || '—'} - {iface.port || '—'} {server ? (
@@ -1420,7 +1442,13 @@ function NetworkConfigManager() { onChange={(val) => setEditingGateway({ ...editingGateway, ip: val })} placeholder="94.142.140.1" required + disabled={gatewayModalMode === 'edit'} /> + {gatewayModalMode === 'edit' && ( +
+ IP адрес нельзя изменить после создания +
+ )}
{editingGateway.type === 'recursive' && (
- +
- Рекурсивный gateway ссылается на другой gateway (обычно прямой) + Рекурсивный gateway может ссылаться на прямой gateway или на интерфейс (по его remote IP)
)} @@ -1546,7 +1592,7 @@ function NetworkConfigManager() { placeholder="10.10.0.1" />
-
+
-
- setEditingInterface({ ...editingInterface, port: val })} - placeholder="51820" - /> -
)} @@ -1621,7 +1658,7 @@ function NetworkConfigManager() { message={ itemToDelete ? ( <> -

Вы уверены, что хотите удалить {itemToDelete.name || itemToDelete.cidr || 'этот элемент'}?

+

Вы уверены, что хотите удалить {itemToDelete.ip || itemToDelete.name || itemToDelete.cidr || 'этот элемент'}?

Это действие нельзя отменить.

) : null