Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CiscoIOSXRConfigParser fails with ValueError: empty separator when the banner is at the end of a config. #614

Open
jtdub opened this issue Jan 17, 2025 · 0 comments

Comments

@jtdub
Copy link
Contributor

jtdub commented Jan 17, 2025

Environment

  • Python version: 3.9.19 and 3.11.3
  • netutils version: 1.10.0, 1.11.0, and 1.12.0

Expected Behavior

When loading an intended config into the netutils config parser, I expect the config to be loaded without error.

Observed Behavior

In the intended config, when a banner is loaded at the very end of the config and the banner delimiter is the last character, the config will fail to load in the parser with a value error.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 1305, in __init__
    super(IOSXRConfigParser, self).__init__(config)
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 534, in __init__
    super(CiscoConfigParser, self).__init__(config)
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 65, in __init__
    super(BaseSpaceConfigParser, self).__init__(config)
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 32, in __init__
    self.build_config_relationship()
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 1386, in build_config_relationship
    line = self._build_banner(line)  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 1329, in _build_banner
    banner, end, _ = line.rpartition(self.delimiter)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: empty separator

Steps to Reproduce

  1. Create two sample configs. The first with a banner at the end of the config. The second with the banner not at the end of the config.

banner1.txt

ntp
 server 192.0.2.1
 server 192.0.2.2

banner motd ^This is the first line test banner.
This is the second line of a test banner.
This is the third line of a test banner.^

banner2.txt

banner motd ^This is the first line of a test banner.
This is the second line of a test banner.
This is the third line of a test banner.^

ntp
 server 192.0.2.1
 server 192.0.2.2
  1. In the python IDE import the pathlib.Path and netutils.config.parser.IOSXRConfigParser libraries.
from pathlib import Path
from netutils.config.parser import IOSXRConfigParser
  1. In the python IDE, load the two banners as strings from their respective files.
banner1 = Path().joinpath("iosxr_banner1.txt").read_text()
banner2 = Path().joinpath("iosxr_banner2.txt").read_text()
>>> banner1
'ntp\n server 192.0.2.1\n server 192.0.2.2\n\nbanner motd ^This is the first line test banner.\nThis is the second line of a test banner.\nThis is the third line of a test banner.^\n'
>>> banner2
'banner motd ^\nThis is the first line of a test banner.\nThis is the second line of a test banner.\nThis is the third line of a test banner.^\n\nntp\n server 192.0.2.1\n server 192.0.2.2\n'
  1. In the python IDE, load the banner1 string into the IOSXRConfigParser. This will result in a traceback.
parsed_banner1 = IOSXRConfigParser(banner1)
>>> parsed_banner1 = IOSXRConfigParser(banner1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 1305, in __init__
    super(IOSXRConfigParser, self).__init__(config)
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 534, in __init__
    super(CiscoConfigParser, self).__init__(config)
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 65, in __init__
    super(BaseSpaceConfigParser, self).__init__(config)
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 32, in __init__
    self.build_config_relationship()
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 1386, in build_config_relationship
    line = self._build_banner(line)  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jtdub/Documents/code/netutils/netutils/config/parser.py", line 1329, in _build_banner
    banner, end, _ = line.rpartition(self.delimiter)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: empty separator
  1. In the python IDE, load the banner2 string into the IOSXRConfigParser. This will load as expected.
parsed_banner2 = IOSXRConfigParser(banner2)
>>> parsed_banner2 = IOSXRConfigParser(banner2)
>>> parsed_banner2.build_config_relationship()
[ConfigLine(config_line='banner motd ^', parents=()), ConfigLine(config_line='This is the first line of a test banner.\nThis is the second line of a test banner.\nThis is the third line of a test banner.^', parents=('banner motd ^',)), ConfigLine(config_line='ntp', parents=()), ConfigLine(config_line=' server 192.0.2.1', parents=('ntp',)), ConfigLine(config_line=' server 192.0.2.2', parents=('ntp',))]

The condition that is being met is a result of the last character of the config being a banner delimiter. Either the delimiter isn't properly being set or the delimiter is set, but the parser is failing to recognize the character at the end of the file and the use of rpartition is raising a ValueError.

https://github.com/networktocode/netutils/blob/develop/netutils/config/parser.py#L1329

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant