Devices carry a reachable_prefixes set (migration 0004) reported by their agent
from the kernel FIB, via a new agent-authed POST /devices/{name}/routes endpoint.
This is scoping/observability data, so it does not bump the config generation and
is exposed on the device resource.
It deliberately does NOT limit which rules a device enforces: the compiler still
emits every applicable rule on every enforcing device. The interface-agnostic,
address-matched rule form is correct under ECMP precisely because it does not
depend on which device is on the path, and most routers hold a default route
anyway — so reachability could not meaningfully narrow the rule set. The reported
FIB is kept for fleet visibility and future zone-origin validation.
- Add snat/masquerade, netmap, and 1:1 nat as stored, terraformable resources:
migration 0003, model types, store CRUD (id-keyed, generation-bumping), and
REST handlers. These are the global-intent/device-resolved NAT tier; compiler
rendering of NAT into per-device configs is a tracked follow-up.
- Add a testcontainers-backed store integration suite exercising the CRUD
lifecycle, generation bumping, source/dest grammar validation, and FK cascade
against a real Postgres. It self-skips under 'go test -short' (the CI path) so
a container runtime is only needed for the full run.
Expand asn address groups to concrete prefixes centrally (one iplocate key,
consistent fleet-wide) and refresh them on a per-group TTL (default 24h). A
background Refresher scans for due groups, unions each group's ASNs to a deduped
prefix set, and writes them to a new resolved/resolved_at column (migration
0002). Fail-safe: a lookup error or empty expansion keeps the last-good set,
never emptying it. The compiler folds resolved prefixes into the rendered set
members; membership churn bumps the generation but never rewrites rules. The
iplocate client is endpoint-configurable and response-tolerant, documented as
needing endpoint/key confirmation. Unit tests cover TTL parsing, due-checks, and
union/dedup/error propagation with a fake expander.