Made-with: Cursor
7.8 KiB
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.
Запуск локально
- Перейдите в проект:
cd nettopo-go
- Скопируйте переменные окружения:
cp .env.example .env
- Запустите 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,failedprogress: 0..100stats.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)
- Собрать бинарник:
go build -o nettopo-server ./cmd/server
- Скопировать unit-файл:
sudo cp deploy/nettopo-go.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now nettopo-go
- Проверить статус:
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.