-
Notifications
You must be signed in to change notification settings - Fork 66
ADVA OS ConfigParser Support #747
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
base: develop
Are you sure you want to change the base?
Conversation
architekture
commented
Dec 16, 2025
- Added base ADVA ConfigParser class and two subclasses (FSP150F2, FSP150F3)
- Added compliance and parser testing suites, tests are successful
|
Can you link to the vendor this is referencing? also, not normal for us to have separation of subclasses such as FSP150F2, FSP150F3, may make sense but should have context as to the why. |
This was my request because f2 and f3 have many differences and we don't know them all "yet". Also Netmiko has two different drivers for f2 and f3 so we wanted to follow suite on that front. Netmiko drivers: https://github.com/ktbyers/netmiko/blob/develop/PLATFORMS.md#:~:text=adva_fsp150f2,adva_fsp150f3 |
|
Corrected issues with documentation and formatting. All checks green. |
jeffkala
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with suggested change to change fragment.
|
Please hold off on this one until I can get a look |
|
To start, it's not clear to me what vendor this is?? Is this adtran? |
ADTRAN Holdings acquired ADVA Optical Networking, these are still using Adva OS so are a different OS vs Adtran which has its own netmiko driver etc. |
Co-authored-by: Jeff Kala <48843785+jeffkala@users.noreply.github.com>
| class ADVAConfigParser(BaseSpaceConfigParser): | ||
| """Base ADVA OS ConfigParser class.""" | ||
|
|
||
| banner_start: t.List[str] = ["security-banner"] | ||
|
|
||
| @property | ||
| def banner_end(self) -> str: | ||
| """Demarcate End of Banner char.""" | ||
| return '"' | ||
|
|
||
| def _build_banner(self, config_line: str) -> t.Optional[str]: | ||
| """Build banner specific to ADVA AOS devices. | ||
| Args: | ||
| config_line: The start of the banner config. | ||
| Returns: | ||
| The next configuration line in the configuration text or None. | ||
| Raises: | ||
| ValueError when parser is unable to identify the banner end. | ||
| """ | ||
| if config_line.endswith(self.banner_end): | ||
| self._update_config_lines(config_line) | ||
| self._current_parents = self._current_parents[:-1] | ||
| try: | ||
| return next(self.generator_config) | ||
| except StopIteration: | ||
| return None | ||
|
|
||
| raise ValueError("Unable to parse banner end.") | ||
|
|
||
|
|
||
| class ADVAFSP150F2ConfigParser(ADVAConfigParser): | ||
| """ADVA OS FSP-150 F2 ConfigParser.""" | ||
|
|
||
| comment_chars: t.List[str] = ["remark", "exit"] | ||
|
|
||
|
|
||
| class ADVAFSP150F3ConfigParser(ADVAConfigParser): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| class ADVAConfigParser(BaseSpaceConfigParser): | |
| """Base ADVA OS ConfigParser class.""" | |
| banner_start: t.List[str] = ["security-banner"] | |
| @property | |
| def banner_end(self) -> str: | |
| """Demarcate End of Banner char.""" | |
| return '"' | |
| def _build_banner(self, config_line: str) -> t.Optional[str]: | |
| """Build banner specific to ADVA AOS devices. | |
| Args: | |
| config_line: The start of the banner config. | |
| Returns: | |
| The next configuration line in the configuration text or None. | |
| Raises: | |
| ValueError when parser is unable to identify the banner end. | |
| """ | |
| if config_line.endswith(self.banner_end): | |
| self._update_config_lines(config_line) | |
| self._current_parents = self._current_parents[:-1] | |
| try: | |
| return next(self.generator_config) | |
| except StopIteration: | |
| return None | |
| raise ValueError("Unable to parse banner end.") | |
| class ADVAFSP150F2ConfigParser(ADVAConfigParser): | |
| """ADVA OS FSP-150 F2 ConfigParser.""" | |
| comment_chars: t.List[str] = ["remark", "exit"] | |
| class ADVAFSP150F3ConfigParser(ADVAConfigParser): | |
| class _ADVAConfigParser(BaseSpaceConfigParser): | |
| """Base ADVA OS ConfigParser class.""" | |
| banner_start: t.List[str] = ["security-banner"] | |
| @property | |
| def banner_end(self) -> str: | |
| """Demarcate End of Banner char.""" | |
| return '"' | |
| def _build_banner(self, config_line: str) -> t.Optional[str]: | |
| """Build banner specific to ADVA AOS devices. | |
| Args: | |
| config_line: The start of the banner config. | |
| Returns: | |
| The next configuration line in the configuration text or None. | |
| Raises: | |
| ValueError when parser is unable to identify the banner end. | |
| """ | |
| if config_line.endswith(self.banner_end): | |
| self._update_config_lines(config_line) | |
| self._current_parents = self._current_parents[:-1] | |
| try: | |
| return next(self.generator_config) | |
| except StopIteration: | |
| return None | |
| raise ValueError("Unable to parse banner end.") | |
| class ADVAFSP150F2ConfigParser(_ADVAConfigParser): | |
| """ADVA OS FSP-150 F2 ConfigParser.""" | |
| comment_chars: t.List[str] = ["remark", "exit"] | |
| class ADVAFSP150F3ConfigParser(_ADVAConfigParser): |
| @@ -0,0 +1,5 @@ | |||
| features = [ | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you test the banner feature explicitly here?
| parents=("configure system",), | ||
| ), | ||
| ConfigLine(config_line=" long-if-alias enabled", parents=()), | ||
| ConfigLine(config_line=" ntp-client", parents=()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why doesn't this have a parent?
| @@ -0,0 +1,5 @@ | |||
| features = [ | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here.
| features = [ | ||
| {"name": "system", "ordered": False, "section": ["configure system"]}, | ||
| {"name": "snmp", "ordered": False, "section": ["configure snmp"]}, | ||
| {"name": "access port", "ordered": False, "section": [" configure access-port"]}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a standard way of doing this? We have traditionally only allowed root level elements? This may or may not be an issue with banner as I think about it.
| class ADVAFSP150F3ConfigParser(ADVAConfigParser): | ||
| """ADVA OS FSP-150 F3 ConfigParser.""" | ||
|
|
||
| comment_chars: t.List[str] = ["#", "home", "Preparing configuration file..."] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting home here seems reasonable. That being said, just want to document the significance. Can you add a comment here describing it?