From 21dcaa43499714977cc18bd6c383d038b8d32aa3 Mon Sep 17 00:00:00 2001 From: Ganesh Nalawade Date: Mon, 30 Jul 2018 10:24:58 +0530 Subject: [PATCH] Handle ConnectionError exception in network modules (#43353) * Handle ConnectionError exception in network modules * Catch ConnectionError expection and fail module in case expection is raised. * Fix CI failure --- lib/ansible/module_utils/network/eos/eos.py | 20 ++- lib/ansible/module_utils/network/ios/ios.py | 17 ++- .../module_utils/network/iosxr/iosxr.py | 130 ++++++++++-------- .../module_utils/network/junos/junos.py | 86 ++++++++---- lib/ansible/module_utils/network/nxos/nxos.py | 19 ++- lib/ansible/module_utils/network/vyos/vyos.py | 23 +++- lib/ansible/modules/network/eos/eos_config.py | 10 +- lib/ansible/modules/network/ios/ios_config.py | 9 +- .../modules/network/junos/junos_command.py | 6 +- .../modules/network/junos/junos_netconf.py | 11 +- .../modules/network/junos/junos_user.py | 8 +- .../modules/network/nxos/nxos_config.py | 11 +- .../modules/network/vyos/vyos_config.py | 8 +- 13 files changed, 241 insertions(+), 117 deletions(-) diff --git a/lib/ansible/module_utils/network/eos/eos.py b/lib/ansible/module_utils/network/eos/eos.py index 4dcb1d4d8a..61a98e0c40 100644 --- a/lib/ansible/module_utils/network/eos/eos.py +++ b/lib/ansible/module_utils/network/eos/eos.py @@ -135,7 +135,11 @@ class Cli: return self._device_configs[cmd] except KeyError: conn = self._get_connection() - out = conn.get_config(filter=flags) + try: + out = conn.get_config(filter=flags) + except ConnectionError as exc: + self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + cfg = to_text(out, errors='surrogate_then_replace').strip() self._device_configs[cmd] = cfg return cfg @@ -144,7 +148,11 @@ class Cli: """Run list of commands on remote device and return results """ connection = self._get_connection() - return connection.run_commands(commands=commands, check_rc=check_rc) + try: + response = connection.run_commands(commands=commands, check_rc=check_rc) + except ConnectionError as exc: + self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response def load_config(self, commands, commit=False, replace=False): """Loads the config commands onto the remote device @@ -164,8 +172,12 @@ class Cli: def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'): conn = self._get_connection() - return conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path, - diff_replace=diff_replace) + try: + diff = conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path, + diff_replace=diff_replace) + except ConnectionError as exc: + self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return diff class Eapi: diff --git a/lib/ansible/module_utils/network/ios/ios.py b/lib/ansible/module_utils/network/ios/ios.py index d9318cd024..4ccee0fbf6 100644 --- a/lib/ansible/module_utils/network/ios/ios.py +++ b/lib/ansible/module_utils/network/ios/ios.py @@ -26,6 +26,7 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # import json + from ansible.module_utils._text import to_text from ansible.module_utils.basic import env_fallback, return_values from ansible.module_utils.network.common.utils import to_list, ComplexList @@ -81,8 +82,10 @@ def get_connection(module): def get_capabilities(module): if hasattr(module, '_ios_capabilities'): return module._ios_capabilities - - capabilities = Connection(module._socket_path).get_capabilities() + try: + capabilities = Connection(module._socket_path).get_capabilities() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) module._ios_capabilities = json.loads(capabilities) return module._ios_capabilities @@ -93,7 +96,10 @@ def check_args(module, warnings): def get_defaults_flag(module): connection = get_connection(module) - out = connection.get_defaults_flag() + try: + out = connection.get_defaults_flag() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) return to_text(out, errors='surrogate_then_replace').strip() @@ -104,7 +110,10 @@ def get_config(module, flags=None): return _DEVICE_CONFIGS[flag_str] except KeyError: connection = get_connection(module) - out = connection.get_config(filter=flags) + try: + out = connection.get_config(filter=flags) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) cfg = to_text(out, errors='surrogate_then_replace').strip() _DEVICE_CONFIGS[flag_str] = cfg return cfg diff --git a/lib/ansible/module_utils/network/iosxr/iosxr.py b/lib/ansible/module_utils/network/iosxr/iosxr.py index c8068fb36b..69e9e20369 100644 --- a/lib/ansible/module_utils/network/iosxr/iosxr.py +++ b/lib/ansible/module_utils/network/iosxr/iosxr.py @@ -30,12 +30,11 @@ import json import re from difflib import Differ from copy import deepcopy -from time import sleep from ansible.module_utils._text import to_text, to_bytes from ansible.module_utils.basic import env_fallback from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.connection import Connection +from ansible.module_utils.connection import Connection, ConnectionError from ansible.module_utils.network.common.netconf import NetconfConnection try: @@ -126,8 +125,10 @@ def get_connection(module): def get_device_capabilities(module): if hasattr(module, 'capabilities'): return module.capabilities - - capabilities = Connection(module._socket_path).get_capabilities() + try: + capabilities = Connection(module._socket_path).get_capabilities() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) module.capabilities = json.loads(capabilities) return module.capabilities @@ -317,7 +318,11 @@ def get_config_diff(module, running=None, candidate=None): conn = get_connection(module) if is_cliconf(module): - return conn.get('show commit changes diff') + try: + response = conn.get('show commit changes diff') + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response elif is_netconf(module): if running and candidate: running_data = running.split("\n", 1)[1].rsplit("\n", 1)[0] @@ -332,21 +337,26 @@ def get_config_diff(module, running=None, candidate=None): def discard_config(module): conn = get_connection(module) - conn.discard_changes() + try: + conn.discard_changes() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) def commit_config(module, comment=None, confirmed=False, confirm_timeout=None, persist=False, check=False, label=None): conn = get_connection(module) reply = None - - if check: - reply = conn.validate() - else: - if is_netconf(module): - reply = conn.commit(confirmed=confirmed, timeout=confirm_timeout, persist=persist) - elif is_cliconf(module): - reply = conn.commit(comment=comment, label=label) + try: + if check: + reply = conn.validate() + else: + if is_netconf(module): + reply = conn.commit(confirmed=confirmed, timeout=confirm_timeout, persist=persist) + elif is_cliconf(module): + reply = conn.commit(comment=comment, label=label) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) return reply @@ -355,7 +365,10 @@ def get_oper(module, filter=None): conn = get_connection(module) if filter is not None: - response = conn.get(filter) + try: + response = conn.get(filter) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) else: return None @@ -366,12 +379,14 @@ def get_config(module, config_filter=None, source='running'): conn = get_connection(module) # Note: Does not cache config in favour of latest config on every get operation. - out = conn.get_config(source=source, filter=config_filter) - if is_netconf(module): - out = to_xml(conn.get_config(source=source, filter=config_filter)) - - cfg = out.strip() + try: + out = conn.get_config(source=source, filter=config_filter) + if is_netconf(module): + out = to_xml(conn.get_config(source=source, filter=config_filter)) + cfg = out.strip() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) return cfg @@ -408,7 +423,7 @@ def load_config(module, command_filter, commit=False, replace=False, else: discard_config(module) except ConnectionError as exc: - module.fail_json(msg=to_text(exc)) + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) finally: # conn.unlock(target = 'candidate') pass @@ -418,40 +433,39 @@ def load_config(module, command_filter, commit=False, replace=False, cmd_filter = deepcopy(command_filter) # If label is present check if label already exist before entering # config mode - if label: - old_label = check_existing_commit_labels(conn, label) - if old_label: - module.fail_json( - msg='commit label {%s} is already used for' - ' an earlier commit, please choose a different label' - ' and rerun task' % label - ) - cmd_filter.insert(0, 'configure terminal') - if admin: - cmd_filter.insert(0, 'admin') - try: - conn.edit_config(cmd_filter) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc)) - - if module._diff: - diff = get_config_diff(module) - - if replace: - cmd = list() - cmd.append({'command': 'commit replace', - 'prompt': 'This commit will replace or remove the entire running configuration', - 'answer': 'yes'}) - cmd.append('end') - conn.edit_config(cmd) - elif commit: - commit_config(module, comment=comment, label=label) - conn.edit_config('end') + if label: + old_label = check_existing_commit_labels(conn, label) + if old_label: + module.fail_json( + msg='commit label {%s} is already used for' + ' an earlier commit, please choose a different label' + ' and rerun task' % label + ) + cmd_filter.insert(0, 'configure terminal') if admin: - conn.edit_config('exit') - else: - conn.discard_changes() + cmd_filter.insert(0, 'admin') + + conn.edit_config(cmd_filter) + if module._diff: + diff = get_config_diff(module) + + if replace: + cmd = list() + cmd.append({'command': 'commit replace', + 'prompt': 'This commit will replace or remove the entire running configuration', + 'answer': 'yes'}) + cmd.append('end') + conn.edit_config(cmd) + elif commit: + commit_config(module, comment=comment, label=label) + conn.edit_config('end') + if admin: + conn.edit_config('exit') + else: + conn.discard_changes() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) return diff @@ -493,9 +507,15 @@ def run_command(module, commands): def copy_file(module, src, dst, proto='scp'): conn = get_connection(module) - conn.copy_file(source=src, destination=dst, proto=proto) + try: + conn.copy_file(source=src, destination=dst, proto=proto) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) def get_file(module, src, dst, proto='scp'): conn = get_connection(module) - conn.get_file(source=src, destination=dst, proto=proto) + try: + conn.get_file(source=src, destination=dst, proto=proto) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) diff --git a/lib/ansible/module_utils/network/junos/junos.py b/lib/ansible/module_utils/network/junos/junos.py index bf65ef97db..02efb1744d 100644 --- a/lib/ansible/module_utils/network/junos/junos.py +++ b/lib/ansible/module_utils/network/junos/junos.py @@ -22,7 +22,7 @@ from contextlib import contextmanager from copy import deepcopy from ansible.module_utils.basic import env_fallback, return_values -from ansible.module_utils.connection import Connection +from ansible.module_utils.connection import Connection, ConnectionError from ansible.module_utils.network.common.netconf import NetconfConnection from ansible.module_utils._text import to_text @@ -93,7 +93,10 @@ def get_capabilities(module): if hasattr(module, '_junos_capabilities'): return module._junos_capabilities - capabilities = Connection(module._socket_path).get_capabilities() + try: + capabilities = Connection(module._socket_path).get_capabilities() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) module._junos_capabilities = json.loads(capabilities) return module._junos_capabilities @@ -125,12 +128,15 @@ def load_configuration(module, candidate=None, action='merge', rollback=None, fo module.fail_json(msg='format must be text when action is set') conn = get_connection(module) - if rollback is not None: - _validate_rollback_id(module, rollback) - obj = Element('load-configuration', {'rollback': str(rollback)}) - conn.execute_rpc(tostring(obj)) - else: - return conn.load_configuration(config=candidate, action=action, format=format) + try: + if rollback is not None: + _validate_rollback_id(module, rollback) + obj = Element('load-configuration', {'rollback': str(rollback)}) + conn.execute_rpc(tostring(obj)) + else: + return conn.load_configuration(config=candidate, action=action, format=format) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) def get_configuration(module, compare=False, format='xml', rollback='0', filter=None): @@ -138,26 +144,30 @@ def get_configuration(module, compare=False, format='xml', rollback='0', filter= module.fail_json(msg='invalid config format specified') conn = get_connection(module) - if compare: - xattrs = {'format': format} - _validate_rollback_id(module, rollback) - xattrs['compare'] = 'rollback' - xattrs['rollback'] = str(rollback) - reply = conn.execute_rpc(tostring(Element('get-configuration', xattrs))) - else: - reply = conn.get_configuration(format=format, filter=filter) - + try: + if compare: + xattrs = {'format': format} + _validate_rollback_id(module, rollback) + xattrs['compare'] = 'rollback' + xattrs['rollback'] = str(rollback) + reply = conn.execute_rpc(tostring(Element('get-configuration', xattrs))) + else: + reply = conn.get_configuration(format=format, filter=filter) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) return reply def commit_configuration(module, confirm=False, check=False, comment=None, confirm_timeout=None, synchronize=False, at_time=None, exit=False): conn = get_connection(module) - if check: - reply = conn.validate() - else: - reply = conn.commit(confirmed=confirm, timeout=confirm_timeout, comment=comment, synchronize=synchronize, at_time=at_time) - + try: + if check: + reply = conn.validate() + else: + reply = conn.commit(confirmed=confirm, timeout=confirm_timeout, comment=comment, synchronize=synchronize, at_time=at_time) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) return reply @@ -165,17 +175,29 @@ def command(module, cmd, format='text', rpc_only=False): conn = get_connection(module) if rpc_only: cmd += ' | display xml rpc' - return conn.command(command=cmd, format=format) + try: + response = conn.command(command=cmd, format=format) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response -def lock_configuration(x): - conn = get_connection(x) - return conn.lock() +def lock_configuration(module): + conn = get_connection(module) + try: + response = conn.lock() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response -def unlock_configuration(x): - conn = get_connection(x) - return conn.unlock() +def unlock_configuration(module): + conn = get_connection(module) + try: + response = conn.unlock() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response @contextmanager @@ -189,7 +211,11 @@ def locked_config(module): def discard_changes(module): conn = get_connection(module) - return conn.discard_changes() + try: + response = conn.discard_changes() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response def get_diff(module, rollback='0'): diff --git a/lib/ansible/module_utils/network/nxos/nxos.py b/lib/ansible/module_utils/network/nxos/nxos.py index 304e36b811..bc591c4456 100644 --- a/lib/ansible/module_utils/network/nxos/nxos.py +++ b/lib/ansible/module_utils/network/nxos/nxos.py @@ -139,7 +139,11 @@ class Cli: return self._device_configs[cmd] except KeyError: connection = self._get_connection() - out = connection.get_config(filter=flags) + try: + out = connection.get_config(filter=flags) + except ConnectionError as exc: + self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + cfg = to_text(out, errors='surrogate_then_replace').strip() self._device_configs[cmd] = cfg return cfg @@ -188,8 +192,12 @@ class Cli: def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'): conn = self._get_connection() - return conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path, - diff_replace=diff_replace) + try: + response = conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path, + diff_replace=diff_replace) + except ConnectionError as exc: + self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response def get_capabilities(self): """Returns platform info of the remove device @@ -198,7 +206,10 @@ class Cli: return self._module._capabilities connection = self._get_connection() - capabilities = connection.get_capabilities() + try: + capabilities = connection.get_capabilities() + except ConnectionError as exc: + self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) self._module._capabilities = json.loads(capabilities) return self._module._capabilities diff --git a/lib/ansible/module_utils/network/vyos/vyos.py b/lib/ansible/module_utils/network/vyos/vyos.py index 50ce73fa64..ac54cf1cc8 100644 --- a/lib/ansible/module_utils/network/vyos/vyos.py +++ b/lib/ansible/module_utils/network/vyos/vyos.py @@ -81,7 +81,11 @@ def get_capabilities(module): if hasattr(module, '_vyos_capabilities'): return module._vyos_capabilities - capabilities = Connection(module._socket_path).get_capabilities() + try: + capabilities = Connection(module._socket_path).get_capabilities() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + module._vyos_capabilities = json.loads(capabilities) return module._vyos_capabilities @@ -93,7 +97,10 @@ def get_config(module): return _DEVICE_CONFIGS else: connection = get_connection(module) - out = connection.get_config() + try: + out = connection.get_config() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) cfg = to_text(out, errors='surrogate_then_replace').strip() _DEVICE_CONFIGS = cfg return cfg @@ -101,15 +108,19 @@ def get_config(module): def run_commands(module, commands, check_rc=True): connection = get_connection(module) - return connection.run_commands(commands=commands, check_rc=check_rc) + try: + response = connection.run_commands(commands=commands, check_rc=check_rc) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + return response def load_config(module, commands, commit=False, comment=None): connection = get_connection(module) try: - resp = connection.edit_config(candidate=commands, commit=commit, comment=comment) + response = connection.edit_config(candidate=commands, commit=commit, comment=comment) except ConnectionError as exc: - module.fail_json(msg=to_text(exc)) + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - return resp.get('diff') + return response.get('diff') diff --git a/lib/ansible/modules/network/eos/eos_config.py b/lib/ansible/modules/network/eos/eos_config.py index d9093d01a2..a473464c65 100644 --- a/lib/ansible/modules/network/eos/eos_config.py +++ b/lib/ansible/modules/network/eos/eos_config.py @@ -264,7 +264,9 @@ backup_path: type: string sample: /playbooks/ansible/backup/eos_config.2016-07-16@22:28:34 """ +from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import ConnectionError from ansible.module_utils.network.common.config import NetworkConfig, dumps from ansible.module_utils.network.eos.eos import get_config, load_config, get_connection from ansible.module_utils.network.eos.eos import run_commands @@ -382,8 +384,12 @@ def main(): candidate = get_candidate(module) running = get_running_config(module, contents, flags=flags) - response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, - diff_replace=replace) + try: + response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, + diff_replace=replace) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + config_diff = response['config_diff'] if config_diff: diff --git a/lib/ansible/modules/network/ios/ios_config.py b/lib/ansible/modules/network/ios/ios_config.py index 7e9745d91b..6459025dc0 100644 --- a/lib/ansible/modules/network/ios/ios_config.py +++ b/lib/ansible/modules/network/ios/ios_config.py @@ -293,6 +293,8 @@ backup_path: """ import json +from ansible.module_utils._text import to_text +from ansible.module_utils.connection import ConnectionError from ansible.module_utils.network.ios.ios import run_commands, get_config from ansible.module_utils.network.ios.ios import get_defaults_flag, get_connection from ansible.module_utils.network.ios.ios import ios_argument_spec @@ -419,9 +421,12 @@ def main(): candidate = get_candidate_config(module) running = get_running_config(module, contents, flags=flags) + try: + response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, + diff_replace=replace) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, - diff_replace=replace) config_diff = response['config_diff'] banner_diff = response['banner_diff'] diff --git a/lib/ansible/modules/network/junos/junos_command.py b/lib/ansible/modules/network/junos/junos_command.py index f8419f8fd6..15575a9920 100644 --- a/lib/ansible/modules/network/junos/junos_command.py +++ b/lib/ansible/modules/network/junos/junos_command.py @@ -164,6 +164,7 @@ import shlex from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_text +from ansible.module_utils.connection import ConnectionError from ansible.module_utils.network.common.netconf import exec_rpc from ansible.module_utils.network.junos.junos import junos_argument_spec, get_configuration, get_connection, get_capabilities, tostring from ansible.module_utils.network.common.parsing import Conditional, FailedConditionalError @@ -373,7 +374,10 @@ def main(): if ('display json' not in cmd) and ('display xml' not in cmd): if display and display != 'text': cmd += ' | display {0}'.format(display) - output.append(conn.get(command=cmd)) + try: + output.append(conn.get(command=cmd)) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) lines = [out.split('\n') for out in output] result = {'changed': False, 'stdout': output, 'stdout_lines': lines} diff --git a/lib/ansible/modules/network/junos/junos_netconf.py b/lib/ansible/modules/network/junos/junos_netconf.py index 0d0723a0ba..c4698c95a7 100644 --- a/lib/ansible/modules/network/junos/junos_netconf.py +++ b/lib/ansible/modules/network/junos/junos_netconf.py @@ -77,6 +77,8 @@ commands: """ import re +from ansible.module_utils._text import to_text +from ansible.module_utils.connection import ConnectionError from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.network.junos.junos import junos_argument_spec, get_connection from ansible.module_utils.network.junos.junos import commit_configuration, discard_changes @@ -146,9 +148,12 @@ def map_params_to_obj(module): def load_config(module, config, commit=False): conn = get_connection(module) + try: + conn.edit_config(to_list(config) + ['top']) + diff = conn.compare_configuration() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - conn.edit_config(to_list(config) + ['top']) - diff = conn.compare_configuration() if diff: if commit: commit_configuration(module) @@ -156,7 +161,7 @@ def load_config(module, config, commit=False): else: discard_changes(module) - return str(diff).strip() + return to_text(diff, errors='surrogate_then_replace').strip() def main(): diff --git a/lib/ansible/modules/network/junos/junos_user.py b/lib/ansible/modules/network/junos/junos_user.py index c5fe313bef..89033e043d 100644 --- a/lib/ansible/modules/network/junos/junos_user.py +++ b/lib/ansible/modules/network/junos/junos_user.py @@ -138,7 +138,9 @@ from functools import partial from copy import deepcopy +from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import ConnectionError from ansible.module_utils.network.common.utils import remove_default_spec from ansible.module_utils.network.junos.junos import junos_argument_spec, get_connection, tostring from ansible.module_utils.network.junos.junos import commit_configuration, discard_changes @@ -160,7 +162,11 @@ def handle_purge(module, want): login = SubElement(element, 'login') conn = get_connection(module) - reply = conn.execute_rpc(tostring(Element('get-configuration')), ignore_warning=False) + try: + reply = conn.execute_rpc(tostring(Element('get-configuration')), ignore_warning=False) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + users = reply.xpath('configuration/system/login/user/name') if users: for item in users: diff --git a/lib/ansible/modules/network/nxos/nxos_config.py b/lib/ansible/modules/network/nxos/nxos_config.py index 5782061e67..70a8e34438 100644 --- a/lib/ansible/modules/network/nxos/nxos_config.py +++ b/lib/ansible/modules/network/nxos/nxos_config.py @@ -276,8 +276,7 @@ backup_path: type: string sample: /playbooks/ansible/backup/nxos_config.2016-07-16@22:28:34 """ - - +from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.connection import ConnectionError from ansible.module_utils.network.common.config import NetworkConfig, dumps @@ -436,8 +435,12 @@ def main(): result['changed'] = True else: - response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, - diff_replace=replace) + try: + response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, + diff_replace=replace) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + config_diff = response['config_diff'] if config_diff: commands = config_diff.split('\n') diff --git a/lib/ansible/modules/network/vyos/vyos_config.py b/lib/ansible/modules/network/vyos/vyos_config.py index c4d776b96b..4a097d6aaf 100644 --- a/lib/ansible/modules/network/vyos/vyos_config.py +++ b/lib/ansible/modules/network/vyos/vyos_config.py @@ -131,7 +131,9 @@ backup_path: """ import re +from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import ConnectionError from ansible.module_utils.network.vyos.vyos import load_config, get_config, run_commands from ansible.module_utils.network.vyos.vyos import vyos_argument_spec, get_connection @@ -208,7 +210,11 @@ def run(module, result): # create loadable config that includes only the configuration updates connection = get_connection(module) - response = connection.get_diff(candidate=candidate, running=config, diff_match=module.params['match']) + try: + response = connection.get_diff(candidate=candidate, running=config, diff_match=module.params['match']) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + commands = response.get('config_diff') sanitize_config(commands, result)