mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
fix an issue with juniper as_path queries that only returned ipv4 or ipv6 routes (not both), causing queries to fail
This commit is contained in:
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
- [#135](https://github.com/checktheroads/hyperglass/issues/135): Fix an issue where Juniper indirect next-hops were empty.
|
||||
- Fix an issue where Juniper structured AS_PATH or Community queries would appear to fail if one address family (IPv4 or IPv6) had an empty response. For example, if an AS_PATH query for `.* 29414 .*` was made (which only returns IPv4 routes), the query would fail.
|
||||
|
||||
### Changed
|
||||
- Updated major Python dependencies (FastAPI, Scrapli, Netmiko, Pydantic, Uvicorn, Gunicorn, etc.)
|
||||
|
@@ -75,8 +75,20 @@ async def execute(query: Query) -> Union[str, Sequence[Dict]]:
|
||||
|
||||
output = await driver.parsed_response(response)
|
||||
|
||||
if isinstance(output, str):
|
||||
# If the output is a string (not structured) and is empty,
|
||||
# produce an error.
|
||||
if output == "" or output == "\n":
|
||||
raise ResponseEmpty(params.messages.no_output, device_name=query.device.name)
|
||||
raise ResponseEmpty(
|
||||
params.messages.no_output, device_name=query.device.name
|
||||
)
|
||||
elif isinstance(output, Dict):
|
||||
# If the output an empty dict, responses have data, produce an
|
||||
# error.
|
||||
if not output:
|
||||
raise ResponseEmpty(
|
||||
params.messages.no_output, device_name=query.device.name
|
||||
)
|
||||
|
||||
log.debug("Output for query: {}:\n{}", query.json(), repr(output))
|
||||
signal.alarm(0)
|
||||
|
31265
hyperglass/models/parsing/juniper_route_aspath.xml
Normal file
31265
hyperglass/models/parsing/juniper_route_aspath.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
|
||||
# Standard Library
|
||||
import re
|
||||
from typing import Dict, List, Iterable, Generator
|
||||
from typing import Dict, List, Sequence, Generator
|
||||
|
||||
# Third Party
|
||||
import xmltodict
|
||||
@@ -10,8 +10,7 @@ from pydantic import ValidationError
|
||||
|
||||
# Project
|
||||
from hyperglass.log import log
|
||||
from hyperglass.exceptions import ParsingError, ResponseEmpty
|
||||
from hyperglass.configuration import params
|
||||
from hyperglass.exceptions import ParsingError
|
||||
from hyperglass.models.parsing.juniper import JuniperRoute
|
||||
|
||||
REMOVE_PATTERNS = (
|
||||
@@ -51,7 +50,7 @@ def clean_xml_output(output: str) -> str:
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def parse_juniper(output: Iterable) -> Dict: # noqa: C901
|
||||
def parse_juniper(output: Sequence) -> Dict: # noqa: C901
|
||||
"""Parse a Juniper BGP XML response."""
|
||||
data = {}
|
||||
|
||||
@@ -71,10 +70,10 @@ def parse_juniper(output: Iterable) -> Dict: # noqa: C901
|
||||
parsed_base = parsed["route-information"]
|
||||
|
||||
if "route-table" not in parsed_base:
|
||||
raise ResponseEmpty(params.messages.no_output)
|
||||
return data
|
||||
|
||||
if "rt" not in parsed_base["route-table"]:
|
||||
raise ResponseEmpty(params.messages.no_output)
|
||||
return data
|
||||
|
||||
parsed = parsed_base["route-table"]
|
||||
|
||||
|
@@ -14,9 +14,13 @@ from .juniper import parse_juniper
|
||||
SAMPLE_FILES = (
|
||||
Path(__file__).parent.parent / "models" / "parsing" / "juniper_route_direct.xml",
|
||||
Path(__file__).parent.parent / "models" / "parsing" / "juniper_route_indirect.xml",
|
||||
Path(__file__).parent.parent / "models" / "parsing" / "juniper_route_aspath.xml",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@log.catch
|
||||
def run():
|
||||
"""Run tests."""
|
||||
samples = ()
|
||||
if len(sys.argv) == 2:
|
||||
samples += (sys.argv[1],)
|
||||
@@ -29,3 +33,7 @@ if __name__ == "__main__":
|
||||
parsed = parse_juniper([sample])
|
||||
log.info(json.dumps(parsed, indent=2))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
Reference in New Issue
Block a user