Repository: ansible/ansible

Issue:
sros_config terminal_stdout regex does not cover Nuage VSC prompt case including '>'
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
sros_config

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.0.0
  config file = /root/nuage-metro/ansible.cfg
  configured module search path = [u'/root/nuage-metro/library']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"

Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).

-->
[DEPRECATION WARNING]: DEFAULT_TASK_INCLUDES_STATIC option, include itself is deprecated and this setting will not matter in the future . This feature will be removed in version 2.8. Deprecation warnings can be
 disabled by setting deprecation_warnings=False in ansible.cfg.
DEFAULT_CALLBACK_PLUGIN_PATH(/root/nuage-metro/ansible.cfg) = [u'/root/nuage-metro/callback_plugins']
DEFAULT_CALLBACK_WHITELIST(/root/nuage-metro/ansible.cfg) = ['report_failures']
DEFAULT_FILTER_PLUGIN_PATH(/root/nuage-metro/ansible.cfg) = [u'/root/nuage-metro/filter_plugins']
DEFAULT_HASH_BEHAVIOUR(/root/nuage-metro/ansible.cfg) = merge
DEFAULT_LOG_PATH(/root/nuage-metro/ansible.cfg) = /root/nuage-metro/ansible.log
DEFAULT_MODULE_PATH(/root/nuage-metro/ansible.cfg) = [u'/root/nuage-metro/library']
DEFAULT_ROLES_PATH(/root/nuage-metro/ansible.cfg) = [u'/root/nuage-metro/roles']
DEFAULT_TASK_INCLUDES_STATIC(/root/nuage-metro/ansible.cfg) = False
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
PERSISTENT_CONNECT_TIMEOUT(/root/nuage-metro/ansible.cfg) = 100
RETRY_FILES_ENABLED(/root/nuage-metro/ansible.cfg) = False


##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
CentOS 7.4

##### SUMMARY
The Nuage VSC controller returns the following prompt:
/configure system security tls-profile "vns-tls-profile" create ^M
*A:vsc.nuage.poc.local>config>sys>sec>tls-profile>#

the '>' included before the '#' character causes the prompt to fail matching against the regex

Potential fix:
in /usr/lib/python2.7/site-packages/ansible/plugins/terminal/sros.py

terminal_stdout_re = [
        re.compile(br"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}>?(?:>|#|\$) ?$"),
        re.compile(br"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$")
    ]

( add ">?" ) before '|#|\$'

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
Use sros_config to configure a TLS profile on VSC

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Configure VSC for VNS
    sros_config:
      lines:
        - 'configure system security tls-profile "vns-tls-profile" create'
      save: true
      provider: "{{ vsc_creds }}"
    delegate_to: localhost
    register: output
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
VSC config modified

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
Command times out, as there is never a match to the prompt

<!--- Paste verbatim command output between quotes below -->
```
2017-11-04 22:56:41,281 p=11602 u=root |  Command executed: /configure system security tls-profile "vns-tls-profile" create
2017-11-04 22:59:41,281 p=11602 u=root |  command timeout triggered, timeout value is 180 secs
2017-11-04 22:59:41,282 p=11602 u=root |  shutdown persistent connection requested
2017-11-04 22:59:41,282 p=11602 u=root |  closing local listener
2017-11-04 22:59:41,282 p=11602 u=root |  closing the connection
2017-11-04 22:59:41,282 p=11602 u=root |  closing ssh connection to device
2017-11-04 22:59:41,282 p=11602 u=root |  firing event: on_close_shell()
2017-11-04 22:59:41,282 paramiko.transport [chan 0] EOF sent (0)
2017-11-04 22:59:41,283 p=11602 u=root |  cli session is now closed
2017-11-04 22:59:41,284 paramiko.transport EOF in transport thread
2017-11-04 22:59:41,284 p=11602 u=root |  ssh connection has been closed successfully
2017-11-04 22:59:41,284 p=11602 u=root |  removing the local control socket
2017-11-04 22:59:41,284 p=11602 u=root |  shutdown complete
2017-11-04 22:59:41,285 p=11602 u=root |  Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/ansible/plugins/connection/network_cli.py", line 199, in send
    return self.receive(command, prompts, answer)
  File "/usr/lib/python2.7/site-packages/ansible/plugins/connection/network_cli.py", line 176, in receive
    data = self._shell.recv(256)
AttributeError: 'NoneType' object has no attribute 'recv'

2017-11-04 22:59:41,285 p=11602 u=root |  socket operation completed with rc 1
2017-11-04 22:59:41,286 p=11602 u=root |  Traceback (most recent call last):
  File "/usr/bin/ansible-connection", line 132, in run
    (s, addr) = self.socket.accept()
  File "/usr/lib64/python2.7/socket.py", line 202, in accept
    sock, addr = self._sock.accept()
  File "/usr/lib64/python2.7/socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor

```



Discussion:
cc @Qalthos @ganeshrn @gundalow @kedarX @privateip @rcarrillocruz @trishnaguha
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/plugins/terminal/sros.py b/lib/ansible/plugins/terminal/sros.py
--- a/lib/ansible/plugins/terminal/sros.py
+++ b/lib/ansible/plugins/terminal/sros.py
@@ -28,7 +28,7 @@
 class TerminalModule(TerminalBase):
 
     terminal_stdout_re = [
-        re.compile(br"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#|\$) ?$"),
+        re.compile(br"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#|\$|>#) ?$"),
         re.compile(br"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$")
     ]
 


Test patch: