1
0
Fork 1
mirror of https://github.com/thatmattlove/hyperglass.git synced 2026-04-17 21:38:27 +00:00

Merge pull request #2 from WilhelmZA/structured

Structured
This commit is contained in:
Carlos Santos 2025-09-26 12:10:37 -03:00 committed by GitHub
commit d1e42f554e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 80 additions and 86 deletions

2
.gitignore vendored
View file

@ -2,6 +2,8 @@
hyperglass/hyperglass/static
TODO*
.env
dev-build.sh
dev-docker/
test.py
.DS_Store

View file

@ -4,11 +4,12 @@
from typing import Union
# Local
from .bgp_route import BGPRouteTable
from .bgp_route import BGPRoute, BGPRouteTable
OutputDataModel = Union[BGPRouteTable]
__all__ = (
"BGPRoute",
"BGPRouteTable",
"OutputDataModel",
)

View file

@ -9,7 +9,7 @@ from pydantic import ConfigDict
# Project
from hyperglass.log import log
from hyperglass.models.data import BGPRouteTable
from hyperglass.models.data import BGPRoute, BGPRouteTable
# Local
from ..main import HyperglassModel
@ -138,8 +138,7 @@ class AristaBGPTable(_AristaBase):
if len(as_path) != 0:
source_as = as_path[0]
routes.append(
{
route_data = {
"prefix": prefix,
"active": route.route_type.active,
"age": self._get_route_age(route.timestamp),
@ -154,7 +153,7 @@ class AristaBGPTable(_AristaBase):
"peer_rid": route.peer_entry.peer_router_id,
"rpki_state": rpki_state,
}
)
routes.append(BGPRoute(**route_data))
serialized = BGPRouteTable(
vrf=self.vrf,

View file

@ -9,7 +9,7 @@ from pydantic import ConfigDict, model_validator
# Project
from hyperglass.log import log
from hyperglass.models.data import BGPRouteTable
from hyperglass.models.data import BGPRoute, BGPRouteTable
# Local
from ..main import HyperglassModel
@ -91,8 +91,7 @@ class FRRBGPTable(_FRRBase):
now = datetime.utcnow().timestamp()
then = datetime.utcfromtimestamp(route.last_update).timestamp()
age = int(now - then)
routes.append(
{
route_data = {
"prefix": self.prefix,
"active": route.bestpath,
"age": age,
@ -109,7 +108,7 @@ class FRRBGPTable(_FRRBase):
# This depends on whether or not the RPKI module is enabled in FRR
"rpki_state": 3,
}
)
routes.append(BGPRoute(**route_data))
serialized = BGPRouteTable(
vrf=vrf,

View file

@ -9,7 +9,7 @@ from pydantic import ConfigDict, field_validator, model_validator
# Project
from hyperglass.log import log
from hyperglass.models.data.bgp_route import BGPRouteTable
from hyperglass.models.data.bgp_route import BGPRoute, BGPRouteTable
# Local
from ..main import HyperglassModel
@ -318,15 +318,9 @@ def _extract_route_entries(lines: t.List[str]) -> t.List[HuaweiRouteEntry]:
class HuaweiBGPRouteTable(BGPRouteTable):
"""Custom BGP Route Table for Huawei that bypasses validation."""
"""Canonical Huawei BGP Route Table."""
def __init__(self, **kwargs):
"""Initialize without calling parent validation."""
# Set attributes directly without validation using object.__setattr__
object.__setattr__(self, "vrf", kwargs.get("vrf", "default"))
object.__setattr__(self, "count", kwargs.get("count", 0))
object.__setattr__(self, "routes", kwargs.get("routes", []))
object.__setattr__(self, "winning_weight", kwargs.get("winning_weight", "low"))
# No custom __init__ needed; inherit from BGPRouteTable (which should be a Pydantic model)
class HuaweiBGPTable(HuaweiBase):
@ -388,7 +382,7 @@ class HuaweiBGPTable(HuaweiBase):
RPKI_STATE_MAP.get("unknown") if route.is_valid else RPKI_STATE_MAP.get("valid")
),
}
routes.append(route_data)
routes.append(BGPRoute(**route_data))
return HuaweiBGPRouteTable(
vrf="default",

View file

@ -9,7 +9,7 @@ from pydantic import ConfigDict, field_validator, model_validator
# Project
from hyperglass.log import log
from hyperglass.util import deep_convert_keys
from hyperglass.models.data.bgp_route import BGPRouteTable
from hyperglass.models.data.bgp_route import BGPRoute, BGPRouteTable
# Local
from ..main import HyperglassModel
@ -176,8 +176,7 @@ class JuniperBGPTable(JuniperBase):
count += table.rt_entry_count
prefix = "/".join(str(i) for i in (table.rt_destination, table.rt_prefix_length))
for route in table.rt_entry:
routes.append(
{
route_data = {
"prefix": prefix,
"active": route.active_tag,
"age": route.age,
@ -192,7 +191,7 @@ class JuniperBGPTable(JuniperBase):
"peer_rid": route.peer_rid,
"rpki_state": route.validation_state,
}
)
routes.append(BGPRoute(**route_data))
serialized = BGPRouteTable(vrf=vrf, count=count, routes=routes, winning_weight="low")
log.bind(platform="juniper", response=repr(serialized)).debug("Serialized response")

View file

@ -282,28 +282,28 @@ class MikrotikBGPTable(MikrotikBase):
return inst
def bgp_table(self) -> BGPRouteTable:
out = []
for r in self.routes:
route_dict = {
"prefix": r.prefix,
"active": r.active,
"age": r.age,
"weight": r.weight,
"med": r.med,
"local_preference": r.local_preference,
"as_path": r.as_path,
"communities": r.all_communities,
"next_hop": r.next_hop,
"source_as": r.source_as,
"source_rid": r.source_rid,
"peer_rid": r.peer_rid,
"rpki_state": r.rpki_state,
routes = []
for route in self.routes:
route_data = {
"prefix": route.prefix,
"active": route.active,
"age": route.age,
"weight": route.weight,
"med": route.med,
"local_preference": route.local_preference,
"as_path": route.as_path,
"communities": route.all_communities,
"next_hop": route.next_hop,
"source_as": route.source_as,
"source_rid": route.source_rid,
"peer_rid": route.peer_rid,
"rpki_state": route.rpki_state,
}
# Instantiate BGPRoute to trigger validation (including external RPKI)
out.append(BGPRoute(**route_dict))
routes.append(BGPRoute(**route_data))
return MikrotikBGPRouteTable(
vrf="default",
count=len(out),
routes=out,
count=len(routes),
routes=routes,
winning_weight="low",
)