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

Adding compatibility for Garderos GRS-based devices. #3417

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

enricostraehler
Copy link

Added support for Garderos GRS operating system: https://www.garderos.com/

Tests pass successfully. Warnings refer to deprecation of telnetlib in base_connection.

(netmiko-ffFHxTah-py3.11) user@machine:~/netmiko-fork-github/netmiko/tests$ py.test -v test_netmiko_show.py --test_device garderos_grs
====================================================================================================== test session starts ======================================================================================================
platform linux -- Python 3.11.2, pytest-7.1.2, pluggy-1.3.0 -- /home/user/virtualenvs/netmiko-ffFHxTah-py3.11/bin/python
cachedir: .pytest_cache
rootdir: /home/user/netmiko-fork-github/netmiko, configfile: setup.cfg
plugins: pylama-8.3.8
collected 25 items                                                                                                                                                                                                              

test_netmiko_show.py::test_failed_key SKIPPED (Not using SSH-keys)                                                                                                                                                        [  4%]
test_netmiko_show.py::test_disable_paging PASSED                                                                                                                                                                          [  8%]
test_netmiko_show.py::test_terminal_width PASSED                                                                                                                                                                          [ 12%]
test_netmiko_show.py::test_ssh_connect PASSED                                                                                                                                                                             [ 16%]
test_netmiko_show.py::test_ssh_connect_cm PASSED                                                                                                                                                                          [ 20%]
test_netmiko_show.py::test_send_command_timing PASSED                                                                                                                                                                     [ 24%]
test_netmiko_show.py::test_send_command_timing_no_cmd_verify SKIPPED                                                                                                                                                      [ 28%]
test_netmiko_show.py::test_send_command PASSED                                                                                                                                                                            [ 32%]
test_netmiko_show.py::test_send_command_no_cmd_verify SKIPPED                                                                                                                                                             [ 36%]
test_netmiko_show.py::test_complete_on_space_disabled SKIPPED                                                                                                                                                             [ 40%]
test_netmiko_show.py::test_send_command_textfsm SKIPPED (TextFSM/ntc-templates not supported on this platform)                                                                                                            [ 44%]
test_netmiko_show.py::test_send_command_ttp SKIPPED (TTP template not existing for this platform)                                                                                                                         [ 48%]
test_netmiko_show.py::test_send_command_genie SKIPPED (Genie not supported on this platform)                                                                                                                              [ 52%]
test_netmiko_show.py::test_send_multiline_timing SKIPPED                                                                                                                                                                  [ 56%]
test_netmiko_show.py::test_send_multiline SKIPPED                                                                                                                                                                         [ 60%]
test_netmiko_show.py::test_send_multiline_prompt SKIPPED                                                                                                                                                                  [ 64%]
test_netmiko_show.py::test_send_multiline_simple SKIPPED                                                                                                                                                                  [ 68%]
test_netmiko_show.py::test_base_prompt PASSED                                                                                                                                                                             [ 72%]
test_netmiko_show.py::test_strip_prompt PASSED                                                                                                                                                                            [ 76%]
test_netmiko_show.py::test_strip_command PASSED                                                                                                                                                                           [ 80%]
test_netmiko_show.py::test_normalize_linefeeds PASSED                                                                                                                                                                     [ 84%]
test_netmiko_show.py::test_clear_buffer PASSED                                                                                                                                                                            [ 88%]
test_netmiko_show.py::test_enable_mode PASSED                                                                                                                                                                             [ 92%]
test_netmiko_show.py::test_disconnect PASSED                                                                                                                                                                              [ 96%]
test_netmiko_show.py::test_disconnect_no_enable SKIPPED                                                                                                                                                                   [100%]

======================================================================================================= warnings summary ========================================================================================================
../netmiko/base_connection.py:30
  /home/user/netmiko-fork-github/netmiko/netmiko/base_connection.py:30: DeprecationWarning: 'telnetlib' is deprecated and slated for removal in Python 3.13
    import telnetlib

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================================================================================== short test summary info ====================================================================================================
SKIPPED [1] test_netmiko_show.py:25: Not using SSH-keys
SKIPPED [1] test_netmiko_show.py:88: Skipped
SKIPPED [1] test_netmiko_show.py:106: Skipped
SKIPPED [1] test_netmiko_show.py:128: Skipped
SKIPPED [1] test_netmiko_show.py:149: TextFSM/ntc-templates not supported on this platform
SKIPPED [1] test_netmiko_show.py:171: TTP template not existing for this platform
SKIPPED [1] test_netmiko_show.py:211: Genie not supported on this platform
SKIPPED [1] test_netmiko_show.py:231: Skipped
SKIPPED [1] test_netmiko_show.py:247: Skipped
SKIPPED [1] test_netmiko_show.py:272: Skipped
SKIPPED [1] test_netmiko_show.py:296: Skipped
SKIPPED [1] test_netmiko_show.py:401: Skipped
========================================================================================== 13 passed, 12 skipped, 1 warning in 25.23s ===========================================================================================
(netmiko-ffFHxTah-py3.11) user@machine:~/netmiko-fork-github/netmiko/tests$ py.test -v test_netmiko_config.py --test_device garderos_grs
====================================================================================================== test session starts ======================================================================================================
platform linux -- Python 3.11.2, pytest-7.1.2, pluggy-1.3.0 -- /home/user/virtualenvs/netmiko-ffFHxTah-py3.11/bin/python
cachedir: .pytest_cache
rootdir: /home/user/netmiko-fork-github/netmiko, configfile: setup.cfg
plugins: pylama-8.3.8
collected 13 items                                                                                                                                                                                                              

test_netmiko_config.py::test_ssh_connect PASSED                                                                                                                                                                           [  7%]
test_netmiko_config.py::test_enable_mode PASSED                                                                                                                                                                           [ 15%]
test_netmiko_config.py::test_config_mode PASSED                                                                                                                                                                           [ 23%]
test_netmiko_config.py::test_exit_config_mode PASSED                                                                                                                                                                      [ 30%]
test_netmiko_config.py::test_config_set PASSED                                                                                                                                                                            [ 38%]
test_netmiko_config.py::test_config_set_generator PASSED                                                                                                                                                                  [ 46%]
test_netmiko_config.py::test_config_set_longcommand PASSED                                                                                                                                                                [ 53%]
test_netmiko_config.py::test_config_hostname PASSED                                                                                                                                                                       [ 61%]
test_netmiko_config.py::test_config_from_file SKIPPED                                                                                                                                                                     [ 69%]
test_netmiko_config.py::test_config_error_pattern SKIPPED (No error_pattern defined.)                                                                                                                                     [ 76%]
test_netmiko_config.py::test_banner SKIPPED (No banner defined.)                                                                                                                                                          [ 84%]
test_netmiko_config.py::test_global_cmd_verify SKIPPED (No banner defined.)                                                                                                                                               [ 92%]
test_netmiko_config.py::test_disconnect PASSED                                                                                                                                                                            [100%]

======================================================================================================= warnings summary ========================================================================================================
../netmiko/base_connection.py:30
  /home/user/netmiko-fork-github/netmiko/netmiko/base_connection.py:30: DeprecationWarning: 'telnetlib' is deprecated and slated for removal in Python 3.13
    import telnetlib

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================================================================================== short test summary info ====================================================================================================
SKIPPED [1] test_netmiko_config.py:163: Skipped
SKIPPED [1] test_netmiko_config.py:175: No error_pattern defined.
SKIPPED [1] test_netmiko_config.py:209: No banner defined.
SKIPPED [1] test_netmiko_config.py:242: No banner defined.
============================================================================================ 9 passed, 4 skipped, 1 warning in 8.87s ============================================================================================

s[:index_last_occurrence].replace(control_seq, "")
+ "\n"
+ s[index_rest_of_string:]
)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have examples of what the output looks like before any modification? It seems strange to me that you just remove all of the \r\n\r sequences except for the last one?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, thanks for reviewing my code.
Back in November, I definitely had several routers that needed this fix - even if this looks strange. Unfortunately, I couldn't reproduce it today.
I suggest that I remove this part for now and submit a new PR. I might need to add it again later on if I discover this is getting an issue again.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if you see the output let me know. I somewhat suspect it is a Netmiko artifact (i.e. the newline conversion isn't working a 100% right and leaves some strange artifacts. I have seen something similar on Cisco NX-OS which I never fully worked out.

self.exit_config_mode()
# Return all results
# Will only be executed if no error occured
return config_results
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What issue do you run into with the standard send_config_set() method in Netmiko?

Why did you need to override it? I say this as it is not maintainable to have a custom-config method for each driver so we should really do everything in our power to use the parent method?

Is it needed for this?

        # Verify if configuration command executed successfully
        if command_result != "Set.":
            raise ConfigInvalidException(
                'Error executing configuration command "{}". Device said: {}'.format(
                    command_string, command_result
                )
            )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Garderos basically confirms every correct configuration command by the response "Set.". Otherwise, it will respond with a descriptive error message.

grs(config)# helloworld
Unknown.
grs(config)# hello=world
Attribute 'hello' not found in node ''.
grs(config)# system.hello=world
Attribute 'hello' not found in node 'system'.
grs(config)# system.name=???
Attribute 'system.name' incorrect: Incorrect format.
grs(config)# system.name=helloworld
Set.

In my understanding, the official implementation of send_config_set() only offers the possibility to blacklist certain error-related string patterns (using error_pattern), correct? However, it appears impossible to reverse the logic by only whitelisting the response "Set." and treating all other responses as errors.

Technically, in regex this would be possible with negative lookahead. Yet, this would only work if regex is matched against the mere respose of the configuration command. Unfortunately, send_config_set() matches error_pattern against the entire config session output (including responses to previously executed configuration commands), so this appears no solution to me. Please correct me if I'm mistaken.

My intention was to implement a "whitelist" version of send_config_set() since a blacklisting approach might not be exhaustive on Garderos GRS.

After all, I agree that code needs to be maintainable. So my suggestion would be that I stick to the error_pattern approach, only overriding the default regex value. I'll rework it and create a new PR.

Copy link
Owner

@ktbyers ktbyers May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I think we probably should put a whitelist version of error_pattern where it would error_pattern. In other words, make a version of error_pattern that is a positive match. If the positive match is not encountered then, raise an exception.

And put this in the base code (defaulted to False i.e. disabled), but then we can decide for Garderos-GRS whether to potentially enable it by default for that driver.

# Will only be executed if no error occured
return config_results

def ssh_connect(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose this? Probably should be outside of Netmiko.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention was to have a nested SSH connection inside the netmiko session without the need of using JumpHosts or Redispatch. I thought this could be useful to others, too.
I suggest to remove this from the driver and move it to the user code.

)
return output_current.strip()

def ssh_send_command(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Purpose? Probably should be outside of Netmiko driver (i.e. in end-user code).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

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

Successfully merging this pull request may close these issues.

None yet

2 participants