feat(scan): несколько CIDR в одном поле, перечисление через запятую
Made-with: Cursor
This commit is contained in:
@@ -14,7 +14,7 @@ const maxCIDRSExpanded = 16384
|
|||||||
|
|
||||||
var cidrRangeRE = regexp.MustCompile(`^\s*(?P<left>.+?/\d+)\s*-\s*(?P<right>.+?/\d+)\s*$`)
|
var cidrRangeRE = regexp.MustCompile(`^\s*(?P<left>.+?/\d+)\s*-\s*(?P<right>.+?/\d+)\s*$`)
|
||||||
|
|
||||||
// expandCIDRSFromRequest раскрывает каждую строку: один CIDR или диапазон "start/end mask - end/end mask".
|
// expandCIDRSFromRequest раскрывает каждую строку: перечисление через запятую, один CIDR или диапазон a/b - c/d.
|
||||||
func expandCIDRSFromRequest(inputs []string) ([]string, error) {
|
func expandCIDRSFromRequest(inputs []string) ([]string, error) {
|
||||||
var all []string
|
var all []string
|
||||||
for _, raw := range inputs {
|
for _, raw := range inputs {
|
||||||
@@ -22,11 +22,17 @@ func expandCIDRSFromRequest(inputs []string) ([]string, error) {
|
|||||||
if raw == "" {
|
if raw == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
part, err := expandCIDREntry(raw)
|
for _, piece := range strings.Split(raw, ",") {
|
||||||
if err != nil {
|
piece = strings.TrimSpace(piece)
|
||||||
return nil, err
|
if piece == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
part, err := expandCIDREntry(piece)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
all = append(all, part...)
|
||||||
}
|
}
|
||||||
all = append(all, part...)
|
|
||||||
}
|
}
|
||||||
if len(all) == 0 {
|
if len(all) == 0 {
|
||||||
return nil, errors.New("cidrs must not be empty")
|
return nil, errors.New("cidrs must not be empty")
|
||||||
|
|||||||
@@ -53,3 +53,23 @@ func TestExpandCIDRSFromRequestDedup(t *testing.T) {
|
|||||||
t.Fatalf("дедуп: %v", out)
|
t.Fatalf("дедуп: %v", out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExpandCIDRSFromRequestCommaList(t *testing.T) {
|
||||||
|
out, err := expandCIDRSFromRequest([]string{"172.16.0.0/24, 192.168.160.0/24 ,192.168.170.0/24"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(out) != 3 {
|
||||||
|
t.Fatalf("ожидали 3 подсети, получили %d: %v", len(out), out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExpandCIDRSFromRequestCommaAndRange(t *testing.T) {
|
||||||
|
out, err := expandCIDRSFromRequest([]string{"10.0.0.0/30,192.168.1.0/24-192.168.2.0/24"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(out) != 1+2 {
|
||||||
|
t.Fatalf("ожидали /30 + 2×/24, получили %d: %v", len(out), out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<strong>Один scan = один полный проход по сети.</strong> Для каждого IP из CIDR (с исключениями): <strong>ping</strong> → для ответивших — проверка <strong>TCP-портов</strong> → если включён SNMP — опрос <strong>системы (sysName и др.)</strong> и сразу обход <strong>LLDP-MIB</strong> (соседи по портам). Отдельной кнопки «только LLDP» нет: соседи попадают в этот же цикл. Кнопка «Создать scan» ставит задачу и сама ждёт завершения, показывая прогресс в строке статуса ниже.
|
<strong>Один scan = один полный проход по сети.</strong> Для каждого IP из CIDR (с исключениями): <strong>ping</strong> → для ответивших — проверка <strong>TCP-портов</strong> → если включён SNMP — опрос <strong>системы (sysName и др.)</strong> и сразу обход <strong>LLDP-MIB</strong> (соседи по портам). Отдельной кнопки «только LLDP» нет: соседи попадают в этот же цикл. Кнопка «Создать scan» ставит задачу и сама ждёт завершения, показывая прогресс в строке статуса ниже.
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<input id="cidrInput" placeholder="CIDR или диапазон: 192.168.160.0/24 - 192.168.190.0/24" style="min-width: 420px;" />
|
<input id="cidrInput" placeholder="CIDR, список через запятую или диапазон: 172.16.0.0/24,192.168.160.0/24" style="min-width: 480px;" />
|
||||||
<button id="createScanBtn">Создать scan и ждать</button>
|
<button id="createScanBtn">Создать scan и ждать</button>
|
||||||
<button id="watchScanBtn">Ждать завершения (текущий scan_id)</button>
|
<button id="watchScanBtn">Ждать завершения (текущий scan_id)</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -793,7 +793,7 @@
|
|||||||
async function createScan() {
|
async function createScan() {
|
||||||
const cidr = cidrInput.value.trim();
|
const cidr = cidrInput.value.trim();
|
||||||
if (!cidr) {
|
if (!cidr) {
|
||||||
setStatus("Введите CIDR или диапазон подсетей (IPv4), например 192.168.1.0/24 или 192.168.160.0/24 - 192.168.190.0/24.");
|
setStatus("Введите CIDR(ы): один адрес, несколько через запятую или диапазон IPv4 (192.168.160.0/24 - 192.168.190.0/24).");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setStatus("Отправка запроса на сервер: создание задачи scan…");
|
setStatus("Отправка запроса на сервер: создание задачи scan…");
|
||||||
|
|||||||
Reference in New Issue
Block a user