nettopo-go

Минимальный старт проекта сетового инвентаризатора и топологии на Go без Docker.

Что уже есть

  • GET /health - проверка состояния API.
  • POST /api/scans - создание задания скана.
  • GET /api/scans - список сканов.
  • GET /api/scans/{id} - просмотр созданного задания.
  • GET /api/scans/diff?from=&to= - сравнение двух сканов (hosts/links).
  • GET /api/scans/{id}/hosts - результаты проверки хостов по скану.
  • GET /api/scans/{id}/ports - результаты проверки TCP-портов по скану.
  • GET /api/scans/{id}/snmp - результаты SNMP v2c (sysName, sysDescr, sysObjectID).
  • GET /api/scans/{id}/lldp - LLDP соседи (если устройство отдает LLDP-MIB по SNMP).
  • GET /api/scans/{id}/links - базовые связи из LLDP с попыткой сопоставления по remote_sys_name.
  • GET /api/scans/{id}/topology - граф nodes/edges для визуализации.
  • GET / - простая UI-страница для просмотра топологии.
  • Валидация CIDR и exclude IP.
  • Два backend-хранилища: in-memory и PostgreSQL.
  • После создания scan запускается фоновый discovery с обновлением статуса и прогресса.
  • Отдельный чек-лист ручной приемки: MANUAL_TEST_CHECKLIST.md.
  • План продолжения на завтра: NEXT_STEPS.md.

Требования

  • Go 1.22+

Проверка версии:

go version

Зависимости Go (go.mod, go.sum)

В репозитории закоммичен go.sum: в нём зафиксированы контрольные суммы модулей из go.mod. Это нужно, чтобы на новом клоне (например на сервере после git pull) команда go build не завершалась ошибкой вида missing go.sum entry for module .... Исходники зависимостей в git не копируются — при сборке модули по-прежнему загружаются через прокси модулей (proxy.golang.org или ваш GOPROXY), если не используете vendor.

После изменения зависимостей выполните go mod tidy и закоммитьте обновлённые go.mod и go.sum. Проверка целостности: go mod verify.

Если на машине нет доступа в интернет во время сборки, можно закоммитить каталог vendor/ (команда go mod vendor) и собирать так: go build -mod=vendor -o nettopo-server ./cmd/server.

Запуск локально

  1. Перейдите в проект:
cd nettopo-go
  1. Скопируйте переменные окружения:
cp .env.example .env
  1. Запустите API:
HTTP_ADDR=:8080 go run ./cmd/server

UI открывается по адресу:

http://localhost:8080/

Что умеет UI сейчас:

  • загрузить topology по scan_id;
  • автоматически подставить последний scan (Последний scan);
  • сравнить два scan прямо на странице (from/to) через /api/scans/diff.
  • выбрать scan из выпадающего списка последних 20;
  • подсветить на графе новые ([+], зеленый) и пропавшие ([-], красный) хосты по diff.
  • использовать легенду цветов и фильтр узлов: все / только новые / только пропавшие.
  • экспортировать topology и diff в JSON-файлы кнопками из UI.
  • создать scan по CIDR из UI и дождаться завершения кнопкой "Ждать завершения".

По умолчанию используется STORE_BACKEND=memory. SNMP-проверка по умолчанию включена (SNMP_ENABLED=true, community public).

PostgreSQL без Docker

Вариант A: macOS (Homebrew)

brew install postgresql@16
brew services start postgresql@16
createdb nettopo
createuser nettopo
psql -d postgres -c "alter user nettopo with password 'nettopo';"
psql -d postgres -c "grant all privileges on database nettopo to nettopo;"

Вариант B: Ubuntu/Debian

sudo apt update
sudo apt install -y postgresql postgresql-contrib
sudo -u postgres psql -c "create user nettopo with password 'nettopo';"
sudo -u postgres psql -c "create database nettopo owner nettopo;"

Вариант C: Windows

  • Установить PostgreSQL через официальный installer.
  • Создать БД nettopo и пользователя nettopo (через pgAdmin или psql).

Запуск API с PostgreSQL

export STORE_BACKEND=postgres
export DB_DSN='postgres://nettopo:nettopo@localhost:5432/nettopo?sslmode=disable'
export RUN_MIGRATIONS=true
go run ./cmd/server

При первом запуске автоматически применится миграция scan_jobs.

Быстрая проверка API

Проверка health:

curl -s http://localhost:8080/health

Создать scan:

curl -s -X POST http://localhost:8080/api/scans \
  -H "Content-Type: application/json" \
  -d '{
    "name":"Office scan",
    "cidrs":["192.168.1.0/24"],
    "exclude_ips":["192.168.1.1"],
    "options":{
      "ping_timeout_ms":700,
      "ping_retries":1,
      "max_parallel_hosts":128,
      "port_scan_enabled":true,
      "ports":[22,80,443,161]
    }
  }'

Получить scan по id:

curl -s http://localhost:8080/api/scans/<scan_id>

Получить список scan jobs:

curl -s http://localhost:8080/api/scans?limit=20

Сравнить два scan:

curl -s "http://localhost:8080/api/scans/diff?from=<scan_id_1>&to=<scan_id_2>"

В ответе у scan есть:

  • status: queued, running, done, failed
  • progress: 0..100
  • stats.hosts_total, stats.hosts_up

Получить результаты по хостам:

curl -s http://localhost:8080/api/scans/<scan_id>/hosts?limit=200

Получить результаты по портам:

curl -s http://localhost:8080/api/scans/<scan_id>/ports?limit=500

Получить SNMP результаты:

curl -s http://localhost:8080/api/scans/<scan_id>/snmp?limit=500

Получить LLDP результаты:

curl -s http://localhost:8080/api/scans/<scan_id>/lldp?limit=1000

Получить связи:

curl -s http://localhost:8080/api/scans/<scan_id>/links?limit=1000

Получить topology (nodes/edges):

curl -s http://localhost:8080/api/scans/<scan_id>/topology?limit=2000

Запуск как сервис на Linux (systemd)

  1. Собрать бинарник:
go build -o nettopo-server ./cmd/server
  1. Скопировать unit-файл:
sudo cp deploy/nettopo-go.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now nettopo-go
  1. Проверить статус:
systemctl status nettopo-go

Размещение за IIS на Windows

  • Запускать nettopo-server.exe как Windows Service.
  • На IIS настроить Reverse Proxy к http://localhost:8080.
  • Требуются URL Rewrite + ARR.

Шаблон web.config лежит в deploy/web.config.example.

S
Description
No description provided
Readme 194 KiB
Languages
Go 59.9%
HTML 40.1%