Repository: ansible/ansible

Issue:
[WIP] Make network plugins PY3 complaint
<!---

-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report


##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
asa
dellos6
dellos9
dellos10
eos
ios
iosxr
junos
nxos
sros
vyos

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
2.4
```

##### CONFIGURATION
<!---
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.
-->

##### SUMMARY
<!--- Explain the problem briefly -->
Issue to track py3 compliance for network modules
##### 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

```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```

```



Discussion:
@ganeshrn Let me know if you need any help in this ? I would like to help here.

Resolving patch:
diff --git a/lib/ansible/module_utils/ios.py b/lib/ansible/module_utils/ios.py
--- a/lib/ansible/module_utils/ios.py
+++ b/lib/ansible/module_utils/ios.py
@@ -25,6 +25,7 @@
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
+from ansible.module_utils._text import to_text
 from ansible.module_utils.basic import env_fallback, return_values
 from ansible.module_utils.network_common import to_list, ComplexList
 from ansible.module_utils.connection import exec_command
@@ -43,20 +44,22 @@
     'provider': dict(type='dict'),
 }
 
+
 def check_args(module, warnings):
     provider = module.params['provider'] or {}
     for key in ios_argument_spec:
         if key not in ['provider', 'authorize'] and module.params[key]:
-            warnings.append('argument %s has been deprecated and will be '
-                    'removed in a future version' % key)
+            warnings.append('argument %s has been deprecated and will be removed in a future version' % key)
 
     if provider:
         for param in ('auth_pass', 'password'):
             if provider.get(param):
                 module.no_log_values.update(return_values(provider[param]))
 
+
 def get_defaults_flag(module):
     rc, out, err = exec_command(module, 'show running-config ?')
+    out = to_text(out, errors='surrogate_then_replace')
 
     commands = set()
     for line in out.splitlines():
@@ -68,6 +71,7 @@ def get_defaults_flag(module):
     else:
         return 'full'
 
+
 def get_config(module, flags=[]):
     cmd = 'show running-config '
     cmd += ' '.join(flags)
@@ -78,11 +82,12 @@ def get_config(module, flags=[]):
     except KeyError:
         rc, out, err = exec_command(module, cmd)
         if rc != 0:
-            module.fail_json(msg='unable to retrieve current config', stderr=err)
-        cfg = str(out).strip()
+            module.fail_json(msg='unable to retrieve current config', stderr=to_text(err, errors='surrogate_then_replace'))
+        cfg = to_text(out, errors='surrogate_then_replace').strip()
         _DEVICE_CONFIGS[cmd] = cfg
         return cfg
 
+
 def to_commands(module, commands):
     spec = {
         'command': dict(key=True),
@@ -100,21 +105,22 @@ def run_commands(module, commands, check_rc=True):
         cmd = module.jsonify(cmd)
         rc, out, err = exec_command(module, cmd)
         if check_rc and rc != 0:
-            module.fail_json(msg=err, rc=rc)
-        responses.append(out)
+            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), rc=rc)
+        responses.append(to_text(out, errors='surrogate_then_replace'))
     return responses
 
+
 def load_config(module, commands):
 
     rc, out, err = exec_command(module, 'configure terminal')
     if rc != 0:
-        module.fail_json(msg='unable to enter configuration mode', err=err)
+        module.fail_json(msg='unable to enter configuration mode', err=to_text(out, errors='surrogate_then_replace'))
 
     for command in to_list(commands):
         if command == 'end':
             continue
         rc, out, err = exec_command(module, command)
         if rc != 0:
-            module.fail_json(msg=err, command=command, rc=rc)
+            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)
 
     exec_command(module, 'end')
diff --git a/lib/ansible/plugins/terminal/ios.py b/lib/ansible/plugins/terminal/ios.py
--- a/lib/ansible/plugins/terminal/ios.py
+++ b/lib/ansible/plugins/terminal/ios.py
@@ -23,7 +23,7 @@
 import re
 
 from ansible.errors import AnsibleConnectionFailure
-from ansible.module_utils._text import to_bytes
+from ansible.module_utils._text import to_text, to_bytes
 from ansible.plugins.terminal import TerminalBase
 
 
@@ -36,7 +36,7 @@ class TerminalModule(TerminalBase):
 
     terminal_stderr_re = [
         re.compile(br"% ?Error"),
-        #re.compile(br"^% \w+", re.M),
+        # re.compile(br"^% \w+", re.M),
         re.compile(br"% ?Bad secret"),
         re.compile(br"invalid input", re.I),
         re.compile(br"(?:incomplete|ambiguous) command", re.I),


Test patch:
diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt
--- a/test/sanity/pep8/legacy-files.txt
+++ b/test/sanity/pep8/legacy-files.txt
@@ -66,7 +66,7 @@ lib/ansible/module_utils/gcdns.py
 lib/ansible/module_utils/gce.py
 lib/ansible/module_utils/gcp.py
 lib/ansible/module_utils/infinibox.py
-lib/ansible/module_utils/ios.py
+lib/ansible/module_utils/iosxr.py
 lib/ansible/module_utils/json_utils.py
 lib/ansible/module_utils/junos.py
 lib/ansible/module_utils/known_hosts.py
@@ -840,7 +840,7 @@ lib/ansible/plugins/strategy/free.py
 lib/ansible/plugins/strategy/linear.py
 lib/ansible/plugins/terminal/asa.py
 lib/ansible/plugins/terminal/eos.py
-lib/ansible/plugins/terminal/ios.py
+lib/ansible/plugins/terminal/iosxr.py
 lib/ansible/plugins/terminal/junos.py
 lib/ansible/plugins/terminal/nxos.py
 lib/ansible/plugins/test/core.py