From 50e776877dc23c802f44dde5195bec52f08f0b84 Mon Sep 17 00:00:00 2001
From: Nathaniel Case <this.is@nathanielca.se>
Date: Thu, 14 Jun 2018 09:45:54 -0400
Subject: [PATCH] Check for ConnectionError on change of config or commands
 (#41504)

---
 .../module_utils/network/edgeos/edgeos.py     | 12 ++++++++---
 lib/ansible/module_utils/network/ios/ios.py   | 11 ++++++----
 .../module_utils/network/iosxr/iosxr.py       | 20 +++++++++++++++----
 lib/ansible/module_utils/network/nxos/nxos.py |  6 +++++-
 lib/ansible/module_utils/network/vyos/vyos.py | 10 ++++++++--
 5 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/lib/ansible/module_utils/network/edgeos/edgeos.py b/lib/ansible/module_utils/network/edgeos/edgeos.py
index 7a72626492a..50e53986362 100644
--- a/lib/ansible/module_utils/network/edgeos/edgeos.py
+++ b/lib/ansible/module_utils/network/edgeos/edgeos.py
@@ -83,7 +83,10 @@ def run_commands(module, commands, check_rc=True):
             prompt = None
             answer = None
 
-        out = connection.get(command, prompt, answer)
+        try:
+            out = connection.get(command, prompt, answer)
+        except ConnectionError as exc:
+            module.fail_json(msg=to_text(exc))
 
         try:
             out = to_text(out, errors='surrogate_or_strict')
@@ -99,7 +102,10 @@ def run_commands(module, commands, check_rc=True):
 def load_config(module, commands, commit=False, comment=None):
     connection = get_connection(module)
 
-    out = connection.edit_config(commands)
+    try:
+        out = connection.edit_config(commands)
+    except ConnectionError as exc:
+        module.fail_json(msg=to_text(exc))
 
     diff = None
     if module._diff:
@@ -113,7 +119,7 @@ def load_config(module, commands, commit=False, comment=None):
     if commit:
         try:
             out = connection.commit(comment)
-        except:
+        except ConnectionError:
             connection.discard_changes()
             module.fail_json(msg='commit failed: %s' % out)
 
diff --git a/lib/ansible/module_utils/network/ios/ios.py b/lib/ansible/module_utils/network/ios/ios.py
index bb4d857b198..af4a1485f26 100644
--- a/lib/ansible/module_utils/network/ios/ios.py
+++ b/lib/ansible/module_utils/network/ios/ios.py
@@ -146,11 +146,11 @@ def run_commands(module, commands, check_rc=True):
 
         try:
             out = connection.get(command, prompt, answer)
-        except ConnectionError as e:
+        except ConnectionError as exc:
             if check_rc:
-                raise
+                module.fail_json(msg=to_text(exc))
             else:
-                out = e
+                out = exc
 
         try:
             out = to_text(out, errors='surrogate_or_strict')
@@ -165,4 +165,7 @@ def run_commands(module, commands, check_rc=True):
 def load_config(module, commands):
     connection = get_connection(module)
 
-    return connection.edit_config(commands)
+    try:
+        return connection.edit_config(commands)
+    except ConnectionError as exc:
+        module.fail_json(msg=to_text(exc))
diff --git a/lib/ansible/module_utils/network/iosxr/iosxr.py b/lib/ansible/module_utils/network/iosxr/iosxr.py
index 50cf3be17e1..c7ee88321e6 100644
--- a/lib/ansible/module_utils/network/iosxr/iosxr.py
+++ b/lib/ansible/module_utils/network/iosxr/iosxr.py
@@ -401,6 +401,8 @@ def load_config(module, command_filter, commit=False, replace=False,
                 commit_config(module)
             else:
                 discard_config(module)
+        except ConnectionError as exc:
+            module.fail_json(msg=to_text(exc))
         finally:
             # conn.unlock(target = 'candidate')
             pass
@@ -411,7 +413,11 @@ def load_config(module, command_filter, commit=False, replace=False,
         cmd_filter.insert(0, 'configure terminal')
         if admin:
             cmd_filter.insert(0, 'admin')
-        conn.edit_config(cmd_filter)
+
+        try:
+            conn.edit_config(cmd_filter)
+        except ConnectionError:
+            module.fail_json(msg=to_text(exc))
 
         if module._diff:
             diff = get_config_diff(module)
@@ -454,12 +460,18 @@ def run_command(module, commands):
             sendonly = False
             newline = True
 
-        out = conn.get(command=command, prompt=prompt, answer=answer, sendonly=sendonly, newline=newline)
+        try:
+            out = conn.get(command=command, prompt=prompt, answer=answer, sendonly=sendonly, newline=newline)
+        except ConnectionError as exc:
+            module.fail_json(msg=to_text(exc))
 
         try:
-            responses.append(to_text(out, errors='surrogate_or_strict'))
+            out = to_text(out, errors='surrogate_or_strict')
         except UnicodeError:
-            module.fail_json(msg=u'failed to decode output from {0}:{1}'.format(cmd, to_text(out)))
+            module.fail_json(msg=u'Failed to decode output from {0}: {1}'.format(cmd, to_text(out)))
+
+        responses.append(out)
+
     return responses
 
 
diff --git a/lib/ansible/module_utils/network/nxos/nxos.py b/lib/ansible/module_utils/network/nxos/nxos.py
index 10f72a7dfd0..52718283a38 100644
--- a/lib/ansible/module_utils/network/nxos/nxos.py
+++ b/lib/ansible/module_utils/network/nxos/nxos.py
@@ -147,7 +147,11 @@ class Cli:
         """Run list of commands on remote device and return results
         """
         connection = self._get_connection()
-        return connection.run_commands(commands, check_rc)
+
+        try:
+            return connection.run_commands(commands, check_rc)
+        except ConnectionError as exc:
+            self._module.fail_json(msg=to_text(exc))
 
     def load_config(self, config, return_error=False, opts=None):
         """Sends configuration commands to the remote device
diff --git a/lib/ansible/module_utils/network/vyos/vyos.py b/lib/ansible/module_utils/network/vyos/vyos.py
index 660156da692..04646d1186c 100644
--- a/lib/ansible/module_utils/network/vyos/vyos.py
+++ b/lib/ansible/module_utils/network/vyos/vyos.py
@@ -114,7 +114,10 @@ def run_commands(module, commands, check_rc=True):
             prompt = None
             answer = None
 
-        out = connection.get(command, prompt, answer)
+        try:
+            out = connection.get(command, prompt, answer)
+        except ConnectionError as exc:
+            module.fail_json(msg=to_text(exc))
 
         try:
             out = to_text(out, errors='surrogate_or_strict')
@@ -129,7 +132,10 @@ def run_commands(module, commands, check_rc=True):
 def load_config(module, commands, commit=False, comment=None):
     connection = get_connection(module)
 
-    out = connection.edit_config(commands)
+    try:
+        out = connection.edit_config(commands)
+    except ConnectionError as exc:
+        module.fail_json(msg=to_text(exc))
 
     diff = None
     if module._diff: