feat(NetworkConfigManager): add IP normalization function to enhance gateway IP generation, ensuring correct handling of full and partial IP inputs
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m44s

This commit is contained in:
2026-01-25 19:25:52 +07:00
parent 80c91d9c54
commit d583757882
+46 -20
View File
@@ -543,6 +543,19 @@ function NetworkConfigManager() {
setGatewayTemplateModalOpen(true);
};
// Нормализация базового IP: если введен полный IP (4 октета), берем только первые 3 октета
const normalizeBaseIp = (baseIp) => {
if (!baseIp || !baseIp.trim()) return '';
const trimmed = baseIp.trim();
const parts = trimmed.split('.');
// Если 4 октета, возвращаем первые 3
if (parts.length === 4) {
return parts.slice(0, 3).join('.');
}
// Если 3 октета или меньше, возвращаем как есть
return trimmed;
};
const handleSelectTemplate = (template) => {
setSelectedTemplate(template);
// Инициализируем gateways из шаблона
@@ -557,8 +570,11 @@ function NetworkConfigManager() {
}
}
// Для рекурсивных gateways генерируем из базового IP
else if (gw.type === 'recursive' && templateBaseIp && templateBaseIp.trim().split('.').length >= 3 && gw.ipTemplate) {
ip = gw.ipTemplate.replace('{baseIp}', templateBaseIp.trim());
else if (gw.type === 'recursive' && templateBaseIp && gw.ipTemplate) {
const normalizedBaseIp = normalizeBaseIp(templateBaseIp);
if (normalizedBaseIp && normalizedBaseIp.split('.').length >= 3) {
ip = gw.ipTemplate.replace('{baseIp}', normalizedBaseIp);
}
}
return {
@@ -587,16 +603,19 @@ function NetworkConfigManager() {
}
}
// Для рекурсивных gateways генерируем из базового IP
else if (gw.type === 'recursive' && templateBaseIp && templateBaseIp.trim().split('.').length >= 3 && originalTemplate && originalTemplate.ipTemplate) {
const templateIp = originalTemplate.ipTemplate.replace('{baseIp}', templateBaseIp.trim());
// Обновляем IP только если он соответствует шаблону (последний октет совпадает) или пустой
const currentIpParts = gw.ip ? gw.ip.split('.') : [];
const templateIpParts = templateIp.split('.');
// Если IP пустой или последний октет совпадает с шаблоном, обновляем
if (!gw.ip || (currentIpParts.length === 4 && templateIpParts.length === 4 &&
currentIpParts[3] === templateIpParts[3])) {
return { ...gw, ip: templateIp };
else if (gw.type === 'recursive' && templateBaseIp && originalTemplate && originalTemplate.ipTemplate) {
const normalizedBaseIp = normalizeBaseIp(templateBaseIp);
if (normalizedBaseIp && normalizedBaseIp.split('.').length >= 3) {
const templateIp = originalTemplate.ipTemplate.replace('{baseIp}', normalizedBaseIp);
// Обновляем IP только если он соответствует шаблону (последний октет совпадает) или пустой
const currentIpParts = gw.ip ? gw.ip.split('.') : [];
const templateIpParts = templateIp.split('.');
// Если IP пустой или последний октет совпадает с шаблоном, обновляем
if (!gw.ip || (currentIpParts.length === 4 && templateIpParts.length === 4 &&
currentIpParts[3] === templateIpParts[3])) {
return { ...gw, ip: templateIp };
}
}
}
return gw;
@@ -626,8 +645,9 @@ function NetworkConfigManager() {
return;
}
// Генерируем IP адреса из шаблонов
const baseIpParts = templateBaseIp.trim().split('.');
// Нормализуем базовый IP (берем первые 3 октета, если введен полный IP)
const normalizedBaseIp = normalizeBaseIp(templateBaseIp);
const baseIpParts = normalizedBaseIp.split('.');
if (baseIpParts.length < 3) {
notify.error('Базовый IP должен содержать минимум 3 октета (например, 10.9.9)');
return;
@@ -651,7 +671,10 @@ function NetworkConfigManager() {
}
// Для рекурсивных gateways генерируем из базового IP
else if (gwTemplate.type === 'recursive' && !ip && selectedTemplate.gateways[index]?.ipTemplate) {
ip = selectedTemplate.gateways[index].ipTemplate.replace('{baseIp}', templateBaseIp.trim());
const normalizedBaseIp = normalizeBaseIp(templateBaseIp);
if (normalizedBaseIp && normalizedBaseIp.split('.').length >= 3) {
ip = selectedTemplate.gateways[index].ipTemplate.replace('{baseIp}', normalizedBaseIp);
}
}
// Если IP все еще пустой, пропускаем
@@ -5109,8 +5132,11 @@ function NetworkConfigManager() {
}
}
// Для рекурсивных gateways генерируем из базового IP
if (gw.type === 'recursive' && templateBaseIp && templateBaseIp.trim().split('.').length >= 3 && gw.ipTemplate) {
return gw.ipTemplate.replace('{baseIp}', templateBaseIp.trim());
if (gw.type === 'recursive' && templateBaseIp && gw.ipTemplate) {
const normalizedBaseIp = normalizeBaseIp(templateBaseIp);
if (normalizedBaseIp && normalizedBaseIp.split('.').length >= 3) {
return gw.ipTemplate.replace('{baseIp}', normalizedBaseIp);
}
}
return '—';
});
@@ -5189,10 +5215,10 @@ function NetworkConfigManager() {
className="form-control"
value={templateBaseIp}
onChange={(e) => setTemplateBaseIp(e.target.value)}
placeholder="10.9.9 или 45.8.248 (минимум 3 октета)"
placeholder="10.9.9 или 10.9.9.1 (минимум 3 октета, полный IP будет нормализован)"
/>
<div className="form-text">
Базовый IP для генерации адресов рекурсивных gateways. Например, для "10.9.9" будут созданы IP: 10.9.9.1, 10.9.9.2, 10.9.9.3 и т.д. Прямые gateways будут использовать IP адрес выбранного сервера.
Базовый IP для генерации адресов рекурсивных gateways. Можно ввести 3 октета (например, "10.9.9") или полный IP (например, "10.9.9.1") - система автоматически возьмет первые 3 октета. Для "10.9.9" будут созданы IP: 10.9.9.1, 10.9.9.2, 10.9.9.3 и т.д. Прямые gateways будут использовать IP адрес выбранного сервера.
</div>
</div>
@@ -5245,7 +5271,7 @@ function NetworkConfigManager() {
placeholder={
gw.type === 'direct' && templateServerId
? (getServerInfo(templateServerId)?.ip || 'IP сервера')
: (gw.ipTemplate ? gw.ipTemplate.replace('{baseIp}', templateBaseIp || 'X.X.X') : 'IP адрес')
: (gw.ipTemplate ? gw.ipTemplate.replace('{baseIp}', normalizeBaseIp(templateBaseIp) || 'X.X.X') : 'IP адрес')
}
/>
<div className="form-text small">