# Buggy code
def run(module, result):
    match = module.params["match"]
    replace = module.params["replace"]
    replace_config = replace == "config"
    path = module.params["parents"]
    comment = module.params["comment"]
    admin = module.params["admin"]
    check_mode = module.check_mode

    candidate_config = get_candidate(module)
    running_config = get_running_config(module)

    commands = None
    if match != "none" and replace != "config":
        commands = candidate_config.difference(
            running_config, path=path, match=match, replace=replace
        )
    elif replace_config:
        can_config = candidate_config.difference(
            running_config, path=path, match=match, replace=replace
        )
        candidate = dumps(can_config, "commands").split("\n")
        run_config = running_config.difference(
            candidate_config, path=path, match=match, replace=replace
        )
        running = dumps(run_config, "commands").split("\n")

        if len(candidate) > 1 or len(running) > 1:
            ret = copy_file_to_node(module)
            if not ret:
                module.fail_json(msg="Copy of config file to the node failed")

            commands = ["load harddisk:/ansible_config.txt"]
    else:
        commands = candidate_config.items

    if commands:
        if not replace_config:
            commands = dumps(commands, "commands").split("\n")

        if any((module.params["lines"], module.params["src"])):
            if module.params["before"]:
                commands[:0] = module.params["before"]

            if module.params["after"]:
                commands.extend(module.params["after"])

            result["commands"] = commands

        commit = not check_mode
        diff = load_config(
            module,
            commands,
            commit=commit,
            replace=replace_config,
            comment=comment,
            admin=admin,
        )
        if diff:
            result["diff"] = dict(prepared=diff)

        result["changed"] = True


# Traceback (ansible.module_utils.connection.ConnectionError)
dynd097:multi_roles wblack$ ansible-playbook -i hosts xr-agg-ncs55k-config-push.yml --diff --check --user <Redacted> -k -vvv
ansible-playbook 2.5.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/Users/wblack/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/Cellar/ansible/2.5.0/libexec/lib/python2.7/site-packages/ansible
executable location = /usr/local/bin/ansible-playbook
python version = 2.7.14 (default, Apr  6 2018, 13:28:11) [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1)]
Using /etc/ansible/ansible.cfg as config file
SSH password:
Parsed /Users/wblack/Desktop/Development/automated-config/ansible/multi_roles/hosts inventory source with ini plugin

PLAYBOOK: xr-agg-ncs55k-config-push.yml ***************************************************************************************************************************************************
1 plays in xr-agg-ncs55k-config-push.yml

PLAY [Starting IOS-XR NCS5500 AGG config push process] ************************************************************************************************************************************
META: ran handlers

TASK [xr-agg-ncs55k-config-push : Push NCS55K AGG configs to svl-agg8] ********************************************************************************************************************
task path: /Users/wblack/Desktop/Development/automated-config/ansible/multi_roles/roles/xr-agg-ncs55k-config-push/tasks/main.yml:2
Using module file /usr/local/Cellar/ansible/2.5.0/libexec/lib/python2.7/site-packages/ansible/modules/network/iosxr/iosxr_config.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: wblack
<127.0.0.1> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111 `" &amp;&amp; echo ansible-tmp-1524722578.51-48392908457111="` echo /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111 `" ) &amp;&amp; sleep 0'
<127.0.0.1> PUT /Users/wblack/.ansible/tmp/ansible-local-50608I8IpYm/tmp5BtrRJ TO /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111/iosxr_config.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111/ /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111/iosxr_config.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111/iosxr_config.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /Users/wblack/.ansible/tmp/ansible-tmp-1524722578.51-48392908457111/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 343, in <module>
main()
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 337, in main
run(module, result)
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 245, in run
running_config = get_running_config(module)
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 221, in get_running_config
contents = get_config(module)
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/network/iosxr/iosxr.py", line 370, in get_config
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/network/iosxr/iosxr.py", line 113, in get_connection
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/network/iosxr/iosxr.py", line 129, in get_device_capabilities
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/connection.py", line 146, in __rpc__
ansible.module_utils.connection.ConnectionError: show version brief
^
% Invalid input detected at '^' marker.
RP/0/RP0/CPU0:svl-agg8#

fatal: [svl-agg8]: FAILED! => {
"changed": false,
"rc": 1
}

MSG:

MODULE FAILURE


MODULE_STDERR:

Traceback (most recent call last):
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 343, in <module>
main()
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 337, in main
run(module, result)
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 245, in run
running_config = get_running_config(module)
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_module_iosxr_config.py", line 221, in get_running_config
contents = get_config(module)
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/network/iosxr/iosxr.py", line 370, in get_config
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/network/iosxr/iosxr.py", line 113, in get_connection
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/network/iosxr/iosxr.py", line 129, in get_device_capabilities
File "/var/folders/72/96cc119x5j720g_392ms8tz40000gn/T/ansible_MeNxHV/ansible_modlib.zip/ansible/module_utils/connection.py", line 146, in __rpc__
ansible.module_utils.connection.ConnectionError: show version brief
^
% Invalid input detected at '^' marker.
RP/0/RP0/CPU0:svl-agg8#


to retry, use: --limit @/Users/wblack/Desktop/Development/automated-config/ansible/multi_roles/xr-agg-ncs55k-config-push.retry

PLAY RECAP ********************************************************************************************************************************************************************************
svl-agg8                   : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def run(module, result):
    match = module.params["match"]
    replace = module.params["replace"]
    replace_config = replace == "config"
    path = module.params["parents"]
    comment = module.params["comment"]
    admin = module.params["admin"]
    check_mode = module.check_mode

    candidate_config = get_candidate(module)
    running_config = get_running_config(module)

    sanitize_candidate_config(candidate_config.items)
    sanitize_running_config(running_config.items)

    commands = None
    if match != "none" and replace != "config":
        commands = candidate_config.difference(
            running_config, path=path, match=match, replace=replace
        )
    elif replace_config:
        can_config = candidate_config.difference(
            running_config, path=path, match=match, replace=replace
        )
        candidate = dumps(can_config, "commands").split("\n")
        run_config = running_config.difference(
            candidate_config, path=path, match=match, replace=replace
        )
        running = dumps(run_config, "commands").split("\n")

        if len(candidate) > 1 or len(running) > 1:
            ret = copy_file_to_node(module)
            if not ret:
                module.fail_json(msg="Copy of config file to the node failed")

            commands = ["load harddisk:/ansible_config.txt"]
    else:
        commands = candidate_config.items

    if commands:
        if not replace_config:
            commands = dumps(commands, "commands").split("\n")

        if any((module.params["lines"], module.params["src"])):
            if module.params["before"]:
                commands[:0] = module.params["before"]

            if module.params["after"]:
                commands.extend(module.params["after"])

            result["commands"] = commands

        commit = not check_mode
        diff = load_config(
            module,
            commands,
            commit=commit,
            replace=replace_config,
            comment=comment,
            admin=admin,
        )
        if diff:
            result["diff"] = dict(prepared=diff)

        result["changed"] = True