Files
EvoBGP/.cursor/rules/networking-bird.mdc
T
DenozordecandCursor 0ea5b3b738
CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Has been skipped
CI / go (push) Failing after 41s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
fix(bird2): switch download host from bird.network.cz to bird.nic.cz
Docker-сборка birdc падала с HTTP 403 при скачивании исходников BIRD
2.14 с bird.network.cz. Старый домен bird.network.cz больше не отдаёт
файлы (403 для всех путей и User-Agent), официальный сайт BIRD переехал
на bird.nic.cz.

URL bird.nic.cz/download/bird-2.14.tar.gz проверен: 200 OK, ~1.4 МБ,
совпадает с размером на старом домене. Страница old-releases на новом
домене подтверждает тот же путь /download/bird-2.14.tar.gz.

Изменены все 5 вхождений старого домена в репозитории:
- deploy/docker/bird/bird-from-source.sh — критичный curl в сборке;
- .cursor/rules/networking-bird.mdc — BIRD2 docs и DOC-SYNC-05;
- .cursor/rules/context7-stack.mdc — приоритет источников;
- .cursor/rules/engineering.mdc — таблица Documentation Sync.

Co-authored-by: Cursor <[email protected]>
2026-07-02 23:30:56 +07:00

220 lines
9.0 KiB
Plaintext

---
description: EvoBGP — BIRD2, BGP policy, IP/CIDR, маршрутизация, валидация конфигов
globs:
- internal/birdfmt/**
- internal/birddeploy/**
- internal/pipeline/**
- deploy/bird/**
- "**/testdata/scenarios/**"
alwaysApply: false
---
# Networking & Routing Rules
Общие правила: `.cursor/rules/engineering.mdc`. Пакет BIRD: `internal/birdfmt/doc.go`.
## Single source of truth
| Домен | SSOT |
|-------|------|
| Префиксы для анонса | Модули tenant → materialized snapshot → ревизия (`store`, `pipeline`, `CreateRenderRevision`) |
| Текст BIRD-фрагментов | `internal/birdfmt` — только генератор `evobgp_*.conf` |
| Каркас `bird.conf` | Operator skeleton + `include` (`StandardIncludeFragments`) |
| Параметры BIRD tenant | Global settings: `bird_router_id`, `bird_local_asn`, … (`docs/manual.md`) |
| BGP peers | `BGPPeer` + `ParsePeerNeighbor` |
**BIRD2 docs:** https://bird.nic.cz/?get_doc
---
## A. BIRD2 Configuration Rules
**BIRD-01** | MUST | Имена фрагментов — константы `Fragment*` (`evobgp_prefixes_v4.conf`, …); include `bird.d/<name>`.
*Rationale:* совместимость deploy.
*Проверка:* `layout.go`; `go test ./internal/birdfmt/...`
**BIRD-02** | MUST | Порядок include: filters v4/v6 → BGP template → prefixes v4/v6 → peers (`StandardIncludeFragments`).
*Rationale:* фильтры до ссылок.
*Проверка:* scenario `standard_layout`; `bird -p`
**BIRD-03** | MUST | `bird.conf` (router id, device, direct, includes) отдельно от `bird.d/evobgp_*` (политика, префиксы).
*Rationale:* атомарная подмена фрагментов.
*Проверка:* review layout.
**BIRD-04** | MUST | Новая логика фильтрации — функция в `birdfmt` + unit-тест; NEVER дублировать filter-блок в два `.conf` вручную.
*Rationale:* DRY v4/v6.
*Проверка:* `filter_test.go`; review.
**BIRD-05** | MUST | Filter: префикс `evobgp_`, суффикс `_v4`/`_v6`; templates `bgp_template` / `bgp_template_v6`.
*Проверка:* `bgp.go`, `layout.go`.
**BIRD-06** | MUST | `router id` — валидный IPv4 dotted-quad (`RenderMainBirdConf`).
*Проверка:* `birdfmt` error; `bird -p`
**BIRD-07** | MUST | Communities — `RouteCommunityAttrs`; синтаксис `((a,b))` в `add()`, не `add(65000,1)`.
*Проверка:* `community_bird_test.go`
**BIRD-08** | SHOULD | Комментарии `#` в preamble; в фрагментах — revision/module id где уместно.
*Проверка:* review.
**BIRD-09** | NEVER | Ручное редактирование `evobgp_*.conf` на ноде без ревизии/бандла в control plane.
*Rationale:* drift.
*Проверка:* `evobgp-deploy` logs.
**BIRD-10** | MUST | Новый scenario: `testdata/scenarios/<name>/bird.conf` (+ `bird.d/`) проходит `bird -p`.
*Проверка:* CI `bird2`
**BIRD-11** | MUST | Только BIRD **2.x**, не 1.6.
*Проверка:* `bird --version`
**BIRD-12** | MUST | Apply: staging → `bird -p` → atomic swap → `birdc configure`; NEVER configure без parse check.
*Проверка:* `birdctl.go`; `birddeploy` review.
---
## B. Routing Policy Rules
**RTE-01** | MUST | BGP template: `import none` на каждый AFI, если задача явно не добавляет import policy.
*Rationale:* deny-by-default.
*Проверка:* `bgp.go`
**RTE-02** | MUST | Export filter завершается `reject;`.
*Проверка:* `filter.go`; `filter_export` scenario.
**RTE-03** | MUST | Анонс только префиксов materialized revision; NEVER static `route` вне pipeline/birdfmt без operator approval.
*Проверка:* store snapshot; review.
**RTE-04** | NEVER | Анонс `0.0.0.0/0`, `::/0`, RFC1918/ULA, loopback, link-local, multicast, reserved без documented exception.
*Проверка:* ingest validation; review.
**RTE-05** | NEVER | Префиксы чужих ASN без авторизации (IRR/RPKI — ops review).
*Проверка:* ops review.
**RTE-06** | MUST | Отдельные export filters IPv4 и IPv6.
*Проверка:* `RenderExportFilterIPv4/IPv6`
**RTE-07** | SHOULD | AS_PATH match — ASN из tenant modules; дедуп `filterUniqueASNs`.
*Проверка:* unit tests.
**RTE-08** | MUST | Peer import/export overrides — расширение `birdfmt`, не ad-hoc в operator `bird.conf`.
*Проверка:* review.
**RTE-09** | SHOULD | hold 90s / keepalive 30s — менять только с обоснованием в settings/docs.
*Проверка:* review.
**RTE-10** | MUST | После apply — post-check `birdc`/метрики (`mergeBirdPostApplyMeta`, `EVOBGP_BIRDC_SOCKET`).
*Проверка:* jobs meta; observability poller.
---
## C. IP Addressing Rules
**IP-01** | MUST | CIDR в Go — `netip.Prefix`; строка — `Masked().String()`.
*Проверка:* `pipeline/parse.go`
**IP-02** | MUST | IPv4/IPv6 — отдельные fragments/filters.
*Проверка:* `layout.go`
**IP-03** | MUST | BGP neighbor — `ParsePeerNeighbor`; `/32`/`/128` нормализуются в host addr.
*Проверка:* `peer_neighbor_test.go`
**IP-04** | NEVER | Hardcoded production CIDR вне testdata/fixtures.
*Проверка:* grep; review.
**IP-05** | MUST | Fixtures/docs — TEST-NET (RFC 5737, 3849): `203.0.113.0/24`, `198.51.100.0/24`, `2001:db8::/32`.
*Проверка:* scenarios.
**IP-06** | MUST | Domain→IP: host routes `/32`, `/128` via `ipToHostPrefix`; invalid отбрасывается.
*Проверка:* `collect_parallel.go`
**IP-07** | MUST | IP range entries — валидный CIDR на границе API/store.
*Проверка:* httpapi; review.
**IP-08** | SHOULD | Множество префиксов — без дубликатов; агрегация — policy decision.
*Проверка:* snapshot dedup.
**IP-09** | MUST | `router id`, `local as` — из tenant settings, не hardcode в callers `birdfmt`.
*Проверка:* `docs/manual.md`
**IP-10** | NEVER | Reserved blocks (`0.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `224.0.0.0/4`, IPv6 analogs) в materialized prefixes.
*Проверка:* review; future validator.
---
## D. Internet Compliance
**COMP-01** | SHOULD | Policy changes — сверка RFC 4271, 4760, 7454 (обзор).
*Проверка:* review.
**COMP-02** | MUST | No excessive deaggregation без need.
*Проверка:* review prefix list.
**COMP-03** | MUST | Standard community 0..65535; large — schema store.
*Проверка:* `community_bird_test.go`
**COMP-04** | NEVER | AS_PATH/MED manipulation без product spec.
*Проверка:* review output.
**COMP-05** | SHOULD | Revision/job meta: source, counts, samples (`revisionLogEntry`).
*Проверка:* jobs.
**COMP-06** | MUST | Node: `evobgp-node verify-bundle` перед apply.
*Проверка:* `docs/access.md`
**COMP-07** | SHOULD | `bird_local_asn` = `local as` в templates/peers.
*Проверка:* settings + birdfmt.
**COMP-08** | NEVER | Default route leak без named `default-originate` policy.
*Проверка:* export filter review.
---
## Validation & Observability
**VAL-01** | MUST | Перед деплоем: `bird -c <bird.conf> -p` (main + includes).
*Проверка:* CI `bird2`; `ParseCheck`
**VAL-02** | MUST | Preview ревизии read-only; apply — jobs/apply/bundle only.
*Проверка:* OpenAPI + httpapi.
**VAL-03** | MUST | Изменения birdfmt — `go test ./internal/birdfmt/...`.
*Проверка:* CI `go`
**VAL-04** | SHOULD | Dry-run apply где API поддерживает `dry_run`.
*Проверка:* routes.go.
**VAL-05** | MUST | `/metrics` Prometheus; `EVOBGP_BIRDC_SOCKET` — BGP session poller.
*Проверка:* `observability`
**VAL-06** | MUST | Логировать job_id, revision_id, speaker_id на apply/refresh/rollback.
*Проверка:* jobs API.
**VAL-07** | SHOULD | После apply — `birdc show protocols` / parsers в `birdfmt`.
*Проверка:* `protocols.go`
**VAL-08** | MUST | Мониторить drift: `last_applied_revision_id` vs published (`evobgp-deploy`).
*Проверка:* deploy worker.
---
## Documentation Sync
**DOC-SYNC-05** | MUST | BIRD — https://bird.nic.cz/?get_doc
**DOC-SYNC-08** | MUST | BGP policy — RFC 4271, 4760, 7454 + BIRD docs + `birdfmt`
**DOC-SYNC-09** | MUST | CIDR — https://pkg.go.dev/net/netip ; примеры — RFC 5737, 3849
---
## Enforcement
```powershell
go test ./internal/birdfmt/... ./internal/pipeline/... -count=1
bird -c internal/birdfmt/testdata/scenarios/<name>/bird.conf -p
```
**PR checklist `birdfmt/**`, `pipeline/**`, `deploy/bird/**`:**
- [ ] filter + unit-test + `bird -p`
- [ ] нет дубли filter logic v4/v6 без общей Go-функции
- [ ] префиксы только store/revision path
- [ ] `import none` на templates сохранён