Repository: ansible/ansible

Issue:
junos module run does not throw proper error for wrong connection type
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
Always add information AFTER of these html comments.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report


##### COMPONENT NAME
<!---
Insert below this comment the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
junos_*
##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
2.5
```

##### 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).
-->

##### 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.
-->

##### SUMMARY
<!--- Explain the problem briefly -->
If a junos module doesn't support a given connection type it should throw an appropriate error.
##### 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.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
- name: Config using the core module
  hosts: junos
  tasks:
    - name: Get junos facts
      junos_facts:
        gather_subset: config
        config_format: json
      register: result
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Should throw a proper error

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [Gathering Facts] *****************************************************************************************
task path: /Users/home/junos_facts.yml:2
<vsrx> attempting to start connection
<vsrx> using connection plugin network_cli
<vsrx> local domain socket does not exist, starting it
<vsrx> control socket path is /Users/home/.ansible/pc/81e2f5c003
<vsrx>
The full traceback is:
Traceback (most recent call last):
  File "/Users/home/ansible/bin/ansible-connection", line 70, in start
    self.connection._connect()
  File "/Users/home/ansible/lib/ansible/plugins/connection/network_cli.py", line 292, in _connect
    self._ssh_shell = ssh.ssh.invoke_shell()
  File "/Library/Python/2.7/site-packages/paramiko/client.py", line 467, in invoke_shell
    chan.get_pty(term, width, height, width_pixels, height_pixels)
  File "/Library/Python/2.7/site-packages/paramiko/channel.py", line 60, in _check
    return func(self, *args, **kwds)
  File "/Library/Python/2.7/site-packages/paramiko/channel.py", line 182, in get_pty
    self._wait_for_event()
  File "/Library/Python/2.7/site-packages/paramiko/channel.py", line 1162, in _wait_for_event
    raise e
SSHException: Channel closed.

fatal: [vsrx]: FAILED! => {
    "msg": "Channel closed."
}
```



Discussion:
Files identified in the description:
None

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
!component +lib/ansible/plugins/connection/network_cli.py
Files identified in the description:
* [lib/ansible/plugins/connection/network_cli.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/network_cli.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @Qalthos @gdpak @gundalow @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/action/junos.py b/lib/ansible/plugins/action/junos.py
--- a/lib/ansible/plugins/action/junos.py
+++ b/lib/ansible/plugins/action/junos.py
@@ -37,6 +37,8 @@
     from ansible.utils.display import Display
     display = Display()
 
+CLI_SUPPORTED_MODULES = ['junos_netconf', 'junos_command']
+
 
 class ActionModule(_ActionModule):
 
@@ -54,6 +56,13 @@ def run(self, tmp=None, task_vars=None):
             pc = copy.deepcopy(self._play_context)
             pc.network_os = 'junos'
             pc.remote_addr = provider['host'] or self._play_context.remote_addr
+
+            if (provider['transport'] == 'cli' and self._task.action not in CLI_SUPPORTED_MODULES) or \
+                    (provider['transport'] == 'netconf' and self._task.action == 'junos_netconf'):
+                return {'failed': True, 'msg': "Transport type '%s' is not valid for '%s' module. "
+                                               "Please see http://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"
+                                               % (provider['transport'], self._task.action)}
+
             if self._task.action == 'junos_netconf' or (provider['transport'] == 'cli' and self._task.action == 'junos_command'):
                 pc.connection = 'network_cli'
                 pc.port = int(provider['port'] or self._play_context.port or 22)
@@ -81,8 +90,11 @@ def run(self, tmp=None, task_vars=None):
             provider = self._task.args.get('provider', {})
             if any(provider.values()):
                 display.warning('provider is unnecessary when using connection=%s and will be ignored' % self._play_context.connection)
-        else:
-            return {'failed': True, 'msg': 'Connection type %s is not valid for this module' % self._play_context.connection}
+
+            if self._play_context.connection == 'network_cli' and self._task.action not in CLI_SUPPORTED_MODULES:
+                return {'failed': True, 'msg': "Connection type '%s' is not valid for '%s' module. "
+                                               "Please see http://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"
+                                               % (self._play_context.connection, self._task.action)}
 
         if (self._play_context.connection == 'local' and pc.connection == 'network_cli') or self._play_context.connection == 'network_cli':
             # make sure we are in the right cli context which should be


Test patch: