Overload network_cli.py / Issue with stderr

25 views
Skip to first unread message

Yann

unread,
Apr 10, 2020, 4:11:33 AM4/10/20
to Ansible Development
Hi,

In my team we are using several custom modules based on network_cli / cliconf.

For one of our manufacturer, we have a issue with the method "_find_prompt" of the "network_cli.py", we would like to know if its possible to overload "network_cli.py" and how ?

For now, we put a modified "network_cli.py" on the module folder called "connection_plugins", but we would like to only overload the method "_find_prompt".


About the issue that we face :
In a custom module, you have to set, in the terminal_plugins, some info about the "stderr" and "stdout".
For example :
stderr = "command unknown"
stdout = "MyPrompt >"

When stderr match, an error should be raise.
And the data are catched until the "stdout" match.

When you have a chunk of data like : ["Command unknown", "MyPrompt >"]
=> No problem, an error is raise

BUT, when you have several chunk of data like :
1st chunk : ["Command unknown", "Lorem", "ipsum"]
2st chunk : ["Lorem2", "MyPrompt >"]

In this case no error is raise !

So I have two questions :)

* How to deal with this kind of behaviour ?
* How to overload a specific function in "network_cli.py" ?


Thanks :)

Ganesh Nalawade

unread,
Apr 10, 2020, 4:42:37 AM4/10/20
to Yann, Ansible Development

From Ansible version 2.9 onwards you can configure a list of terminal regex (ansible_terminal_stderr_re and ansible_terminal_stdout_re) to identify if the response is an error or valid output. 

--
You received this message because you are subscribed to the Google Groups "Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-deve...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-devel/c33895c4-b69e-4336-a795-e59cbe496dd3%40googlegroups.com.


--
Regards,
Ganesh B. Nalawade


Message has been deleted

Yann

unread,
Apr 10, 2020, 5:03:11 AM4/10/20
to Ansible Development
Thx for the answer.

But the problem is the same when it return several chunck of data :

1st chunk : ["Command unknown", "Lorem", "ipsum"]
2st chunk : ["Lorem2", "MyPrompt >"]

In this case no error is raise, because between the 2 chunk, the variable : is_error_message is set to False

In network_cli.py

def receive([...])
[...]
if self._find_prompt(window): # window = chunk of data
          # expected True; else still wait chunk of data

def _find_prompt(self, response):
'''Searches the buffered response for a matching command prompt
'''
errored_response = None
is_error_message = False

for regex in self._terminal_stderr_re: # First chunk - match / Second chunk - no match
if regex.search(response):
is_error_message = True

# Check if error response ends with command prompt if not
# receive it buffered prompt
for regex in self._terminal_stdout_re: # First chunk - no match - so errored_response is not set
match = regex.search(response)
if match:
errored_response = response
self._matched_pattern = regex.pattern
self._matched_prompt = match.group()
self._log_messages("matched error regex '%s' from response '%s'" % (self._matched_pattern, errored_response))
break

if not is_error_message: # Second chunk, is_error_message was reset to False, so the condition are True.
for regex in self._terminal_stdout_re:
match = regex.search(response)
if match:
self._matched_pattern = regex.pattern
self._matched_prompt = match.group()
self._log_messages("matched cli prompt '%s' with regex '%s' from response '%s'" % (self._matched_prompt, self._matched_pattern, response))
if not errored_response:
return True # Finally return "Everything is okkayyy"

if errored_response: # First chunk - errored_response is still None -> not triggered - no error raise
raise AnsibleConnectionFailure(errored_response)

return False


That's why I would like to overload this method.


Le vendredi 10 avril 2020 10:42:37 UTC+2, Ganesh Nalawade a écrit :

From Ansible version 2.9 onwards you can configure a list of terminal regex (ansible_terminal_stderr_re and ansible_terminal_stdout_re) to identify if the response is an error or valid output. 

On Fri, Apr 10, 2020 at 1:41 PM Yann <yann.v...@gmail.com> wrote:
Hi,

In my team we are using several custom modules based on network_cli / cliconf.

For one of our manufacturer, we have a issue with the method "_find_prompt" of the "network_cli.py", we would like to know if its possible to overload "network_cli.py" and how ?

For now, we put a modified "network_cli.py" on the module folder called "connection_plugins", but we would like to only overload the method "_find_prompt".


About the issue that we face :
In a custom module, you have to set, in the terminal_plugins, some info about the "stderr" and "stdout".
For example :
stderr = "command unknown"
stdout = "MyPrompt >"

When stderr match, an error should be raise.
And the data are catched until the "stdout" match.

When you have a chunk of data like : ["Command unknown", "MyPrompt >"]
=> No problem, an error is raise

BUT, when you have several chunk of data like :
1st chunk : ["Command unknown", "Lorem", "ipsum"]
2st chunk : ["Lorem2", "MyPrompt >"]

In this case no error is raise !

So I have two questions :)

* How to deal with this kind of behaviour ?
* How to overload a specific function in "network_cli.py" ?


Thanks :)

--
You received this message because you are subscribed to the Google Groups "Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansibl...@googlegroups.com.

Ganesh Nalawade

unread,
Apr 10, 2020, 5:09:55 AM4/10/20
to Yann, Ansible Development

The regex match is done for each chunk (256 bytes) received to identify if the chunk has error/prompt string.
Based on your problem description, if the first chunk matches the error regex it will raise an error exception and not read second chunk at all.

However, if the error string is split across two chunks, in that case, it might not detect the error string as the default error regex won't match. 
For such case regex can be configured to handle this scenario

To unsubscribe from this group and stop receiving emails from it, send an email to ansible-deve...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-devel/9b2a9624-2050-4da5-891d-616cd2f0e6d9%40googlegroups.com.



Ganesh Nalawade

unread,
Apr 10, 2020, 5:25:41 AM4/10/20
to Yann, Ansible Development

Ah, I missed your earlier email.
Yes, that's right observation. One way to get around the issue is to configure the ansible_terminal_stdout_re for a given task to match the error and prompt in first chunk itself.
 However, I agree that is not the best of the solution.
Please raise an issue here https://github.com/ansible-collections/ansible.netcommon/issues to track it.

Yann

unread,
Apr 10, 2020, 7:04:34 AM4/10/20
to Ansible Development
Okay :)

I raise this issue.

Thanks for you assistance.

Le vendredi 10 avril 2020 11:25:41 UTC+2, Ganesh Nalawade a écrit :

Ah, I missed your earlier email.
Yes, that's right observation. One way to get around the issue is to configure the ansible_terminal_stdout_re for a given task to match the error and prompt in first chunk itself.
 However, I agree that is not the best of the solution.
Please raise an issue here https://github.com/ansible-collections/ansible.netcommon/issues to track it.

On Fri, Apr 10, 2020 at 2:39 PM Ganesh Nalawade <gane...@gmail.com> wrote:

The regex match is done for each chunk (256 bytes) received to identify if the chunk has error/prompt string.
Based on your problem description, if the first chunk matches the error regex it will raise an error exception and not read second chunk at all.

However, if the error string is split across two chunks, in that case, it might not detect the error string as the default error regex won't match. 
For such case regex can be configured to handle this scenario

Reply all
Reply to author
Forward
0 new messages