Repository: ansible/ansible

Issue:
iosxr_facts fails when run using ansible_connection=netconf
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
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
-->
iosxr_facts

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.6.0 (iosxr_smoke c2a063a5c0) last updated 2018/03/09 13:10:21 (GMT -400)
  config file = None
  configured module search path = [u'/Users/david/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/david/code/ansible/lib/ansible
  executable location = /Users/david/code/ansible/bin/ansible
  python version = 2.7.10 (default, Jul 15 2017, 17:16:57) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)]
```

##### 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).
-->

iosxr.yaml
```yaml
ansible_connection: netconf
ansible_network_os: iosxr
ansible_user: ________
ansible_ssh_pass: ________
ansible_become: yes
ansible_become_method: enable
ansible_ssh_port: 22
```

Note: The device is configured to run netconf on port 22

##### 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 -->
iosxr_facts fails when run using `ansible_connection: netconf`

Likely related to #37362

##### 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 -->

Run the following task using the netconf plugin:
```yaml
    - iosxr_facts:
        gather_subset: config
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
iosxr_facts should run normally

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [iosxr_facts] ************************************************************************************************************
task path: /Users/david/code/test/iosxr.yaml:14
<iosxr01> attempting to start connection
<iosxr01> using connection plugin netconf
<iosxr01> found existing local domain socket, using it!
<iosxr01>
<iosxr01> local domain socket path is /Users/david/.ansible/pc/2093d821ad
Using module file /Users/david/code/ansible/lib/ansible/modules/network/iosxr/iosxr_facts.py
<iosxr01> ESTABLISH LOCAL CONNECTION FOR USER: david
<iosxr01> EXEC /bin/sh -c 'echo ~ && sleep 0'
<iosxr01> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792 `" && echo ansible-tmp-1520963288.35-147305335847792="` echo /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792 `" ) && sleep 0'
<iosxr01> PUT /Users/david/.ansible/tmp/ansible-local-11008a_HxpT/tmpjBHr5Y TO /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792/iosxr_facts.py
<iosxr01> EXEC /bin/sh -c 'chmod u+x /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792/ /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792/iosxr_facts.py && sleep 0'
<iosxr01> EXEC /bin/sh -c '/Users/david/code/venv/bin/python /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792/iosxr_facts.py && sleep 0'
<iosxr01> EXEC /bin/sh -c 'rm -f -r /Users/david/.ansible/tmp/ansible-tmp-1520963288.35-147305335847792/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_o00lZu/ansible_module_iosxr_facts.py", line 423, in <module>
    main()
  File "/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_o00lZu/ansible_module_iosxr_facts.py", line 412, in main
    module.exit_json(out=module.from_json(results))
UnboundLocalError: local variable 'results' referenced before assignment

fatal: [iosxr01]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_o00lZu/ansible_module_iosxr_facts.py\", line 423, in <module>\n    main()\n  File \"/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_o00lZu/ansible_module_iosxr_facts.py\", line 412, in main\n    module.exit_json(out=module.from_json(results))\nUnboundLocalError: local variable 'results' referenced before assignment\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 1
}
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/network/iosxr/iosxr_facts.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/iosxr/iosxr_facts.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 @gdpak @kedarX @privateip @rcarrillocruz
[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/iosxr.py b/lib/ansible/plugins/action/iosxr.py
--- a/lib/ansible/plugins/action/iosxr.py
+++ b/lib/ansible/plugins/action/iosxr.py
@@ -42,12 +42,12 @@ def run(self, tmp=None, task_vars=None):
         del tmp  # tmp no longer has any effect
 
         socket_path = None
+        force_cli = self._task.action in ('iosxr_netconf', 'iosxr_config', 'iosxr_command', 'iosxr_facts')
 
         if self._play_context.connection == 'local':
             provider = load_provider(iosxr_provider_spec, self._task.args)
             pc = copy.deepcopy(self._play_context)
-            if self._task.action in ['iosxr_netconf', 'iosxr_config', 'iosxr_command'] or \
-                    (provider['transport'] == 'cli'):
+            if force_cli or provider['transport'] == 'cli':
                 pc.connection = 'network_cli'
                 pc.port = int(provider['port'] or self._play_context.port or 22)
             elif provider['transport'] == 'netconf':
@@ -75,6 +75,9 @@ def run(self, tmp=None, task_vars=None):
 
             task_vars['ansible_socket'] = socket_path
         elif self._play_context.connection in ('netconf', 'network_cli'):
+            if force_cli and self._play_context.connection != 'network_cli':
+                return {'failed': True, 'msg': 'Connection type %s is not valid for module %s' %
+                        (self._play_context.connection, self._task.action)}
             provider = self._task.args.get('provider', {})
             if any(provider.values()):
                 display.warning('provider is unnecessary when using {0} and will be ignored'.format(self._play_context.connection))
diff --git a/lib/ansible/plugins/netconf/iosxr.py b/lib/ansible/plugins/netconf/iosxr.py
--- a/lib/ansible/plugins/netconf/iosxr.py
+++ b/lib/ansible/plugins/netconf/iosxr.py
@@ -73,7 +73,6 @@ def transform_reply():
     if sys.version < '3':
         return reply
     else:
-        print("utf8")
         return reply.encode('UTF-8')
 
 


Test patch: