forked from mirrors/thatmattlove-hyperglass
fix Juniper parsing issue when CLI banner is appended to the XML output [skip ci]
This commit is contained in:
parent
0c4d94a3e7
commit
35270c9825
1 changed files with 31 additions and 2 deletions
|
|
@ -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:
|
||||
|
||||
```
|
||||
<rpc-reply>
|
||||
...
|
||||
<cli>
|
||||
<banner>{master}</banner>
|
||||
</cli>
|
||||
</rpc-reply>
|
||||
|
||||
{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))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue