diff --git a/hyperglass/parsing/juniper.py b/hyperglass/parsing/juniper.py index bcb3c46..820694a 100644 --- a/hyperglass/parsing/juniper.py +++ b/hyperglass/parsing/juniper.py @@ -1,6 +1,7 @@ """Parse Juniper XML Response to Structured Data.""" # Standard Library +import re from typing import Dict, Iterable # Third Party @@ -14,14 +15,42 @@ from hyperglass.configuration import params from hyperglass.models.parsing.juniper import JuniperRoute +def clean_xml_output(output: str) -> str: + """Remove Juniper-specific patterns from output.""" + patterns = ( + """ + The XML response can a CLI banner appended to the end of the XML + string. For example: + + ``` + + ... + + {master} + + + + {master} + ``` + + This pattern will remove anything inside braces, including the braces. + """ + r"\{.+\}", + ) + lines = (line.strip() for line in output.split()) + scrubbed_lines = (re.sub(pat, "", line) for pat in patterns for line in lines) + return "\n".join(scrubbed_lines) + + def parse_juniper(output: Iterable) -> Dict: # noqa: C901 """Parse a Juniper BGP XML response.""" data = {} for i, response in enumerate(output): + cleaned = clean_xml_output(response) try: parsed = xmltodict.parse( - response, force_list=("rt", "rt-entry", "community") + cleaned, force_list=("rt", "rt-entry", "community") ) log.debug("Initially Parsed Response: \n{}", parsed) @@ -49,7 +78,7 @@ def parse_juniper(output: Iterable) -> Dict: # noqa: C901 except xmltodict.expat.ExpatError as err: log.critical(str(err)) - raise ParsingError("Error parsing response data") + raise ParsingError("Error parsing response data") from err except KeyError as err: log.critical("{} was not found in the response", str(err))