feat(NetworkConfigManager): add optional interface names for servers; enhance interface name generation logic with DNS parsing and user-defined names
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m41s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m41s
This commit is contained in:
@@ -138,6 +138,8 @@ function NetworkConfigManager() {
|
||||
const [templateServer2, setTemplateServer2] = useState('');
|
||||
const [templateType, setTemplateType] = useState('GRE');
|
||||
const [templateNamePrefix, setTemplateNamePrefix] = useState('');
|
||||
const [templateName1, setTemplateName1] = useState(''); // Опциональное имя для сервера 1
|
||||
const [templateName2, setTemplateName2] = useState(''); // Опциональное имя для сервера 2
|
||||
|
||||
// === MikroTik Code Generation ===
|
||||
const [mikrotikCodeModalOpen, setMikrotikCodeModalOpen] = useState(false);
|
||||
@@ -441,12 +443,44 @@ function NetworkConfigManager() {
|
||||
};
|
||||
|
||||
// === Генерация имени интерфейса на основе серверов ===
|
||||
const generateInterfaceName = (server1, server2, type, prefix = '') => {
|
||||
const server1Name = server1?.dns?.split('.')[0] || server1?.ip?.split('.').join('-') || 'server1';
|
||||
const server2Name = server2?.dns?.split('.')[0] || server2?.ip?.split('.').join('-') || 'server2';
|
||||
const typeLower = type.toLowerCase();
|
||||
// Для сервера 1: берем часть из DNS сервера 2 (например, msk) и имя хоста сервера 2 (ihor)
|
||||
// Для сервера 2: берем часть из DNS сервера 1 (например, swe) и имя хоста сервера 1 (hiphost)
|
||||
const generateInterfaceName = (currentServer, otherServer, type, prefix = '') => {
|
||||
// Парсим DNS имена
|
||||
const parseDnsParts = (dns) => {
|
||||
if (!dns) return null;
|
||||
const parts = dns.split('.');
|
||||
if (parts.length >= 2) {
|
||||
return {
|
||||
hostname: parts[0], // первая часть (имя хоста)
|
||||
location: parts[1] // вторая часть (локация, например msk, swe)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const currentParts = parseDnsParts(currentServer?.dns);
|
||||
const otherParts = parseDnsParts(otherServer?.dns);
|
||||
|
||||
let name;
|
||||
|
||||
if (currentParts && otherParts) {
|
||||
// Используем локацию из другого сервера и имя хоста из другого сервера
|
||||
// Например: для сервера 1 (hiphost.swe.shx.su) с сервером 2 (ihor.msk.rt.shx.su)
|
||||
// Имя на сервере 1: msk-ihor
|
||||
name = `${otherParts.location}-${otherParts.hostname}`;
|
||||
} else if (currentServer?.dns) {
|
||||
// Fallback: используем первую часть DNS
|
||||
name = currentServer.dns.split('.')[0];
|
||||
} else if (currentServer?.ip) {
|
||||
// Fallback: используем IP
|
||||
name = currentServer.ip.split('.').join('-');
|
||||
} else {
|
||||
name = 'server';
|
||||
}
|
||||
|
||||
const prefixPart = prefix ? `${prefix}-` : '';
|
||||
return `${prefixPart}${typeLower}-${server1Name}-${server2Name}`;
|
||||
return `${prefixPart}${name}`;
|
||||
};
|
||||
|
||||
// === Создание интерфейса из шаблона ===
|
||||
@@ -469,9 +503,9 @@ function NetworkConfigManager() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Генерируем имена интерфейсов
|
||||
const name1 = generateInterfaceName(server1, server2, templateType, templateNamePrefix);
|
||||
const name2 = generateInterfaceName(server2, server1, templateType, templateNamePrefix);
|
||||
// Генерируем имена интерфейсов (используем опциональные имена если указаны)
|
||||
const name1 = templateName1.trim() || generateInterfaceName(server1, server2, templateType, templateNamePrefix);
|
||||
const name2 = templateName2.trim() || generateInterfaceName(server2, server1, templateType, templateNamePrefix);
|
||||
|
||||
// Генерируем IP адреса
|
||||
const localIp = generateFreePrivateIp(null, false, null);
|
||||
@@ -518,6 +552,8 @@ function NetworkConfigManager() {
|
||||
setTemplateServer2('');
|
||||
setTemplateType('GRE');
|
||||
setTemplateNamePrefix('');
|
||||
setTemplateName1('');
|
||||
setTemplateName2('');
|
||||
};
|
||||
|
||||
// === CRUD для Interfaces ===
|
||||
@@ -2749,6 +2785,8 @@ function NetworkConfigManager() {
|
||||
setTemplateServer2('');
|
||||
setTemplateType('GRE');
|
||||
setTemplateNamePrefix('');
|
||||
setTemplateName1('');
|
||||
setTemplateName2('');
|
||||
}}
|
||||
onSubmit={handleCreateInterfaceFromTemplate}
|
||||
title="Создать интерфейс из шаблона"
|
||||
@@ -2819,38 +2857,70 @@ function NetworkConfigManager() {
|
||||
const server2 = getServerInfo(templateServer2);
|
||||
if (!server1 || !server2) return null;
|
||||
|
||||
const previewName1 = generateInterfaceName(server1, server2, templateType, templateNamePrefix);
|
||||
const previewName2 = generateInterfaceName(server2, server1, templateType, templateNamePrefix);
|
||||
const autoName1 = generateInterfaceName(server1, server2, templateType, templateNamePrefix);
|
||||
const autoName2 = generateInterfaceName(server2, server1, templateType, templateNamePrefix);
|
||||
const previewName1 = templateName1.trim() || autoName1;
|
||||
const previewName2 = templateName2.trim() || autoName2;
|
||||
const previewLocalIp = generateFreePrivateIp(null, false, null);
|
||||
const previewRemoteIp = previewLocalIp ? generateFreePrivateIp(null, true, previewLocalIp) : null;
|
||||
|
||||
return (
|
||||
<div className="col-12">
|
||||
<div className="card card-sm border">
|
||||
<div className="card-body">
|
||||
<h6 className="card-title mb-3">Предпросмотр интерфейса:</h6>
|
||||
<div className="row g-2">
|
||||
<div className="col-md-6">
|
||||
<div className="small text-muted mb-1">Сервер 1 ({server1.dns || server1.ip}):</div>
|
||||
<div><strong>Имя:</strong> <code>{previewName1}</code></div>
|
||||
<div><strong>Local IP:</strong> <code>{previewLocalIp || '—'}</code></div>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<div className="small text-muted mb-1">Сервер 2 ({server2.dns || server2.ip}):</div>
|
||||
<div><strong>Имя:</strong> <code>{previewName2}</code></div>
|
||||
<div><strong>Local IP:</strong> <code>{previewRemoteIp || '—'}</code></div>
|
||||
</div>
|
||||
{previewLocalIp && previewRemoteIp && (
|
||||
<div className="col-12 mt-2">
|
||||
<div className="badge bg-success-lt text-success">
|
||||
{previewLocalIp} ↔ {previewRemoteIp}
|
||||
</div>
|
||||
<>
|
||||
<div className="col-md-6">
|
||||
<label className="form-label">
|
||||
Имя интерфейса (сервер 1)
|
||||
{!templateName1 && <span className="text-muted small ms-1">(авто: {autoName1})</span>}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
value={templateName1}
|
||||
onChange={(e) => setTemplateName1(e.target.value)}
|
||||
placeholder={autoName1}
|
||||
/>
|
||||
<div className="form-text">Оставьте пустым для автогенерации</div>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<label className="form-label">
|
||||
Имя интерфейса (сервер 2)
|
||||
{!templateName2 && <span className="text-muted small ms-1">(авто: {autoName2})</span>}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
value={templateName2}
|
||||
onChange={(e) => setTemplateName2(e.target.value)}
|
||||
placeholder={autoName2}
|
||||
/>
|
||||
<div className="form-text">Оставьте пустым для автогенерации</div>
|
||||
</div>
|
||||
<div className="col-12">
|
||||
<div className="card card-sm border">
|
||||
<div className="card-body">
|
||||
<h6 className="card-title mb-3">Предпросмотр интерфейса:</h6>
|
||||
<div className="row g-2">
|
||||
<div className="col-md-6">
|
||||
<div className="small text-muted mb-1">Сервер 1 ({server1.dns || server1.ip}):</div>
|
||||
<div><strong>Имя:</strong> <code>{previewName1}</code></div>
|
||||
<div><strong>Local IP:</strong> <code>{previewLocalIp || '—'}</code></div>
|
||||
</div>
|
||||
)}
|
||||
<div className="col-md-6">
|
||||
<div className="small text-muted mb-1">Сервер 2 ({server2.dns || server2.ip}):</div>
|
||||
<div><strong>Имя:</strong> <code>{previewName2}</code></div>
|
||||
<div><strong>Local IP:</strong> <code>{previewRemoteIp || '—'}</code></div>
|
||||
</div>
|
||||
{previewLocalIp && previewRemoteIp && (
|
||||
<div className="col-12 mt-2">
|
||||
<div className="badge bg-success-lt text-success">
|
||||
{previewLocalIp} ↔ {previewRemoteIp}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user