Repository: ansible/ansible
Pull request: Fix vyos sending `'None'` to device
##### SUMMARY
<!--- Describe the change, including rationale and design decisions -->

<!---
If you are fixing an existing issue, please include "Fixes #nnn" in your
commit message and your description; but you should still explain what
the change does.
-->
Fixes #33804

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bugfix Pull Request

##### COMPONENT NAME
<!--- Name of the module/plugin/module/task -->
vyos

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
2.5
```


Problem statement:
vyos_facts: Invalid command: [None]
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
vyos_facts

##### ANSIBLE VERSION
```
ansible 2.5.0 (devel ff525ab3d1) last updated 2017/12/12 09:41:06 (GMT +100)

```

##### SUMMARY
<!--- Explain the problem briefly -->

##### STEPS TO REPRODUCE
```yaml
[vyos]
vyos01.example.net ansible_connection=network_cli ansible_network_os=vyos ansible_user=ansible ansible_ssh_pass=ansible

    - name: Gather facts (vyos)
      vyos_facts:
      when: ansible_network_os == 'vyos'
```

##### EXPECTED RESULTS

##### ACTUAL RESULTS
```
TASK [Gather facts (vyos)] ***********************************************************************************************************************************************************************************************************************
task path: /home/johnb/git/ansible-inc/gundalows-test-cases/net-usecase-1-facts-v4/net-usecase-1-facts.yml:16
skipping: [eos01.example.net] => {
    "changed": false, 
    "skip_reason": "Conditional result was False"
}
<vyos01.example.net> attempting to start connection
<vyos01.example.net> using connection plugin network_cli
<vyos01.example.net> local domain socket does not exist, starting it
<vyos01.example.net> control socket path is /home/johnb/.ansible/pc/473589d267
<vyos01.example.net> connection to remote device started successfully
<vyos01.example.net> local domain socket listeners started successfully
<vyos01.example.net> local domain socket path is /home/johnb/.ansible/pc/473589d267
Using module file /home/johnb/git/ansible-inc/ansible-workspace-4/lib/ansible/modules/network/vyos/vyos_facts.py
<vyos01.example.net> ESTABLISH LOCAL CONNECTION FOR USER: johnb
<vyos01.example.net> EXEC /bin/sh -c 'echo ~ && sleep 0'
<vyos01.example.net> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861 `" && echo ansible-tmp-1513071920.48-103347042615861="` echo /home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861 `" ) && sleep 0'
<vyos01.example.net> PUT /tmp/tmpcpJLro TO /home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861/vyos_facts.py
<vyos01.example.net> EXEC /bin/sh -c 'chmod u+x /home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861/ /home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861/vyos_facts.py && sleep 0'
<vyos01.example.net> EXEC /bin/sh -c '/usr/bin/python /home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861/vyos_facts.py; rm -rf "/home/johnb/.ansible/tmp/ansible-tmp-1513071920.48-103347042615861/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py", line 320, in <module>
    main()
  File "/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py", line 308, in main
    inst.populate()
  File "/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py", line 194, in populate
    super(Neighbors, self).populate()
  File "/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py", line 117, in populate
    self.responses = run_commands(self.module, list(self.COMMANDS))
  File "/tmp/ansible_mEbZ4z/ansible_modlib.zip/ansible/module_utils/network/vyos/vyos.py", line 117, in run_commands
  File "/tmp/ansible_mEbZ4z/ansible_modlib.zip/ansible/module_utils/connection.py", line 146, in __rpc__
ansible.module_utils.connection.ConnectionError:  VMware, Inc.
      Model:        VMware Virtual Platform
      Asset ID:     No Asset Tag
-------------------------------------------------------------------------------
ansible@an-vyos-01:~$ None

  Invalid command: [None]

ansible@an-vyos-01:~$ 

fatal: [vyos01.example.net]: FAILED! => {
    "changed": false, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py\", line 320, in <module>\n    main()\n  File \"/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py\", line 308, in main\n    inst.populate()\n  File \"/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py\", line 194, in populate\n    super(Neighbors, self).populate()\n  File \"/tmp/ansible_mEbZ4z/ansible_module_vyos_facts.py\", line 117, in populate\n    self.responses = run_commands(self.module, list(self.COMMANDS))\n  File \"/tmp/ansible_mEbZ4z/ansible_modlib.zip/ansible/module_utils/network/vyos/vyos.py\", line 117, in run_commands\n  File \"/tmp/ansible_mEbZ4z/ansible_modlib.zip/ansible/module_utils/connection.py\", line 146, in __rpc__\nansible.module_utils.connection.ConnectionError:  VMware, Inc.\r\n      Model:        VMware Virtual Platform\r\n      Asset ID:     No Asset Tag\r\n-------------------------------------------------------------------------------\r\nansible@an-vyos-01:~$ None\r\n\r\n  Invalid command: [None]\r\n\r\nansible@an-vyos-01:~$ \n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE", 
    "rc": 0
}

```

Hints from issue discussion:
Files identified in the description:
* [lib/ansible/modules/network/vyos/vyos_facts.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/vyos/vyos_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 @Qalthos @qalthos
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
This might be VMware specific I was testing against rdu2 (VMware)
It may work on KVM

Commit message: Fix vyos sending `'None'` to device

Patch to review:
diff --git a/lib/ansible/plugins/cliconf/vyos.py b/lib/ansible/plugins/cliconf/vyos.py
index 84c137f9cfb255..9386298d9b8ac3 100644
--- a/lib/ansible/plugins/cliconf/vyos.py
+++ b/lib/ansible/plugins/cliconf/vyos.py
@@ -59,7 +59,13 @@ def edit_config(self, command):
             self.send_command(cmd)
 
     def get(self, command, prompt=None, answer=None, sendonly=False):
-        return self.send_command(to_bytes(command), prompt=to_bytes(prompt), answer=to_bytes(answer), sendonly=sendonly)
+        # Avoid setting either value to b'None'
+        if prompt is not None:
+            prompt = to_bytes(prompt)
+        if answer is not None:
+            answer = to_bytes(answer)
+
+        return self.send_command(to_bytes(command), prompt=prompt, answer=answer, sendonly=sendonly)
 
     def commit(self, comment=None):
         if comment:


Code review comments:
diff_hunk: @@ -59,7 +59,13 @@ def edit_config(self, command):
             self.send_command(cmd)
 
     def get(self, command, prompt=None, answer=None, sendonly=False):
-        return self.send_command(to_bytes(command), prompt=to_bytes(prompt), answer=to_bytes(answer), sendonly=sendonly)
+        # Avoid setting either value to b'None'
+        if prompt is not None:
+            prompt = to_bytes(prompt)
+        if answer is not None:
+            answer = to_bytes(answer)
+
+        return self.send_command(to_bytes(command), prompt=prompt, answer=answer, sendonly=sendonly)
path: lib/ansible/plugins/cliconf/vyos.py
text: @user1:
Is conversion to `to_bytes`  required while passing parameters to `send_command()`
Command conversion to bytes is handled here in [network_cli.py file at L288](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/network_cli.py#L288)
and for prompt and answer it is done at [L305 in network_cli.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/network_cli.py#L305)

@author:
Probably not. `send()` has other issues, though, so I'll pull those in instead