Store device FIB for observability (no rule limiting)
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.
This commit is contained in:
+26
-3
@@ -290,10 +290,11 @@ func (s *Store) RecordDeviceStatus(ctx context.Context, name string, generation
|
||||
|
||||
func (s *Store) GetDevice(ctx context.Context, name string) (model.Device, error) {
|
||||
var d model.Device
|
||||
var resolver, settings []byte
|
||||
var resolver, settings, reachable []byte
|
||||
err := s.pool.QueryRow(ctx,
|
||||
`SELECT name, class, COALESCE(fabric, ''), resolver, settings FROM devices WHERE name = $1`, name,
|
||||
).Scan(&d.Name, &d.Class, &d.Fabric, &resolver, &settings)
|
||||
`SELECT name, class, COALESCE(fabric, ''), resolver, settings, reachable_prefixes
|
||||
FROM devices WHERE name = $1`, name,
|
||||
).Scan(&d.Name, &d.Class, &d.Fabric, &resolver, &settings, &reachable)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return d, ErrNotFound
|
||||
}
|
||||
@@ -303,9 +304,31 @@ func (s *Store) GetDevice(ctx context.Context, name string) (model.Device, error
|
||||
if err := json.Unmarshal(resolver, &d.Resolver); err != nil {
|
||||
return d, err
|
||||
}
|
||||
if err := json.Unmarshal(reachable, &d.ReachablePrefixes); err != nil {
|
||||
return d, err
|
||||
}
|
||||
return d, json.Unmarshal(settings, &d.Settings)
|
||||
}
|
||||
|
||||
// UpdateDeviceRoutes stores the reachable prefixes an agent reports from its FIB.
|
||||
// This is scoping data, not config — it does not bump the config generation.
|
||||
func (s *Store) UpdateDeviceRoutes(ctx context.Context, name string, prefixes []string) error {
|
||||
reachable, err := jsonb(prefixes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tag, err := s.pool.Exec(ctx,
|
||||
`UPDATE devices SET reachable_prefixes = $2, routes_reported_at = now() WHERE name = $1`,
|
||||
name, reachable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ---- Settings, portgroups, policies ----------------------------------------
|
||||
|
||||
func (s *Store) GetSettings(ctx context.Context) (model.Settings, error) {
|
||||
|
||||
Reference in New Issue
Block a user