# Buggy code
def main():
    """main entry point for module execution"""
    argument_spec = dict(
        src=dict(type="path"),
        replace_src=dict(),
        lines=dict(aliases=["commands"], type="list"),
        parents=dict(type="list"),
        before=dict(type="list"),
        after=dict(type="list"),
        match=dict(default="line", choices=["line", "strict", "exact", "none"]),
        replace=dict(default="line", choices=["line", "block", "config"]),
        running_config=dict(aliases=["config"]),
        intended_config=dict(),
        defaults=dict(type="bool", default=False),
        backup=dict(type="bool", default=False),
        save_when=dict(choices=["always", "never", "modified"], default="never"),
        diff_against=dict(choices=["running", "startup", "intended"]),
        diff_ignore_lines=dict(type="list"),
        # save is deprecated as of ans2.4, use save_when instead
        save=dict(default=False, type="bool", removed_in_version="2.4"),
        # force argument deprecated in ans2.2
        force=dict(default=False, type="bool", removed_in_version="2.2"),
    )

    argument_spec.update(nxos_argument_spec)

    mutually_exclusive = [
        ("lines", "src", "replace_src"),
        ("parents", "src"),
        ("save", "save_when"),
    ]

    required_if = [
        ("match", "strict", ["lines"]),
        ("match", "exact", ["lines"]),
        ("replace", "block", ["lines"]),
        ("replace", "config", ["replace_src"]),
        ("diff_against", "intended", ["intended_config"]),
    ]

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=mutually_exclusive,
        required_if=required_if,
        supports_check_mode=True,
    )

    warnings = list()
    nxos_check_args(module, warnings)

    result = {"changed": False, "warnings": warnings}

    config = None

    info = get_capabilities(module).get("device_info", {})
    os_platform = info.get("network_os_platform", "")

    if module.params["replace"] == "config":
        if "9K" not in os_platform:
            module.fail_json(
                msg="replace: config is supported only for Nexus 9K series switches"
            )

    if module.params["replace_src"]:
        if module.params["replace"] != "config":
            module.fail_json(msg="replace: config is required with replace_src")

    if module.params["backup"] or (
        module._diff and module.params["diff_against"] == "running"
    ):
        contents = get_config(module)
        config = NetworkConfig(indent=2, contents=contents)
        if module.params["backup"]:
            result["__backup__"] = contents

    if any(
        (module.params["src"], module.params["lines"], module.params["replace_src"])
    ):
        match = module.params["match"]
        replace = module.params["replace"]

        candidate = get_candidate(module)

        if match != "none" and replace != "config":
            config = get_running_config(module, config)
            path = module.params["parents"]
            configobjs = candidate.difference(
                config, match=match, replace=replace, path=path
            )
        else:
            configobjs = candidate.items

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

            if module.params["before"]:
                commands[:0] = module.params["before"]

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

            result["commands"] = commands
            result["updates"] = commands

            if not module.check_mode:
                load_config(module, commands)

            result["changed"] = True

    running_config = None
    startup_config = None

    diff_ignore_lines = module.params["diff_ignore_lines"]

    if module.params["save"]:
        module.params["save_when"] = "always"

    if module.params["save_when"] != "never":
        output = execute_show_commands(
            module, ["show running-config", "show startup-config"]
        )

        running_config = NetworkConfig(
            indent=1, contents=output[0], ignore_lines=diff_ignore_lines
        )
        startup_config = NetworkConfig(
            indent=1, contents=output[1], ignore_lines=diff_ignore_lines
        )

        if (
            running_config.sha1 != startup_config.sha1
            or module.params["save_when"] == "always"
        ):
            result["changed"] = True
            if not module.check_mode:
                cmd = {
                    "command": "copy running-config startup-config",
                    "output": "text",
                }
                run_commands(module, [cmd])
            else:
                module.warn(
                    "Skipping command `copy running-config startup-config` "
                    "due to check_mode.  Configuration not copied to "
                    "non-volatile storage"
                )

    if module._diff:
        if not running_config:
            output = execute_show_commands(module, "show running-config")
            contents = output[0]
        else:
            contents = running_config.config_text

        # recreate the object in order to process diff_ignore_lines
        running_config = NetworkConfig(
            indent=1, contents=contents, ignore_lines=diff_ignore_lines
        )

        if module.params["diff_against"] == "running":
            if module.check_mode:
                module.warn(
                    "unable to perform diff against running-config due to check mode"
                )
                contents = None
            else:
                contents = config.config_text

        elif module.params["diff_against"] == "startup":
            if not startup_config:
                output = execute_show_commands(module, "show startup-config")
                contents = output[0]
            else:
                contents = output[0]
                contents = startup_config.config_text

        elif module.params["diff_against"] == "intended":
            contents = module.params["intended_config"]

        if contents is not None:
            base_config = NetworkConfig(
                indent=1, contents=contents, ignore_lines=diff_ignore_lines
            )

            if running_config.sha1 != base_config.sha1:
                if module.params["diff_against"] == "intended":
                    before = running_config
                    after = base_config
                elif module.params["diff_against"] in ("startup", "running"):
                    before = base_config
                    after = running_config

                result.update(
                    {
                        "changed": True,
                        "diff": {"before": str(before), "after": str(after)},
                    }
                )

    module.exit_json(**result)


# Traceback (ansible.module_utils.connection.ConnectionError)
ansible-playbook 2.5.0b1
config file = /mnt/hgfs/Share/HCS/ansible.cfg
configured module search path = ['/home/ddean1/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/ddean1/ansible/lib/python3.5/site-packages/ansible
executable location = /home/ddean1/ansible/bin/ansible-playbook
python version = 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609]
Using /mnt/hgfs/Share/HCS/ansible.cfg as config file
SSH password:
Parsed /mnt/hgfs/Share/HCS/hosts inventory source with ini plugin

PLAYBOOK: Deploy_HCS_L2.yml ****************************************************************************************************************************
1 plays in Deploy_HCS_L2.yml

PLAY [Deploying NSDC as sec.20.hcs.mts.ca on MPLS PE] **************************************************************************************************
META: ran handlers

TASK [NXOS >> Pushing VRF for NSDC to device] **********************************************************************************************************
task path: /mnt/hgfs/Share/HCS/Deploy_HCS_L2.yml:5
Using module file /home/ddean1/ansible/lib/python3.5/site-packages/ansible/modules/network/nxos/nxos_config.py
<10.204.81.109> ESTABLISH LOCAL CONNECTION FOR USER: ddean1
<10.204.81.109> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<10.204.81.109> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830 `" &amp;&amp; echo ansible-tmp-1518678736.8799627-106707050074830="` echo /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830 `" ) &amp;&amp; sleep 0'
<10.204.81.109> PUT /home/ddean1/.ansible/tmp/ansible-local-57688c28_2z2i/tmpb_qici4g TO /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830/nxos_config.py
<10.204.81.109> EXEC /bin/sh -c 'chmod u+x /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830/ /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830/nxos_config.py &amp;&amp; sleep 0'
<10.204.81.109> EXEC /bin/sh -c '/usr/bin/python /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830/nxos_config.py &amp;&amp; sleep 0'
<10.204.81.109> EXEC /bin/sh -c 'rm -f -r /home/ddean1/.ansible/tmp/ansible-tmp-1518678736.8799627-106707050074830/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_M6YgkX/ansible_module_nxos_config.py", line 512, in <module>
main()
File "/tmp/ansible_M6YgkX/ansible_module_nxos_config.py", line 393, in main
info = get_capabilities(module).get('device_info', {})
File "/tmp/ansible_M6YgkX/ansible_modlib.zip/ansible/module_utils/network/nxos/nxos.py", line 474, in get_capabilities
File "/tmp/ansible_M6YgkX/ansible_modlib.zip/ansible/module_utils/network/nxos/nxos.py", line 225, in get_capabilities
File "/tmp/ansible_M6YgkX/ansible_modlib.zip/ansible/module_utils/connection.py", line 146, in __rpc__
ansible.module_utils.connection.ConnectionError: show version | json
^
% Invalid command at '^' marker.
wnpgmb02h3e-rsv03#

fatal: [wnpgmb02h3e-rsv03]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_M6YgkX/ansible_module_nxos_config.py\", line 512, in <module>\n    main()\n  File \"/tmp/ansible_M6YgkX/ansible_module_nxos_config.py\", line 393, in main\n    info = get_capabilities(module).get('device_info', {})\n  File \"/tmp/ansible_M6YgkX/ansible_modlib.zip/ansible/module_utils/network/nxos/nxos.py\", line 474, in get_capabilities\n  File \"/tmp/ansible_M6YgkX/ansible_modlib.zip/ansible/module_utils/network/nxos/nxos.py\", line 225, in get_capabilities\n  File \"/tmp/ansible_M6YgkX/ansible_modlib.zip/ansible/module_utils/connection.py\", line 146, in __rpc__\nansible.module_utils.connection.ConnectionError: show version | json\r\r\n                                  ^\r\n% Invalid command at '^' marker.\r\n\rwnpgmb02h3e-rsv03# \n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1
}

PLAY RECAP *********************************************************************************************************************************************
wnpgmb02h3e-rsv03          : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def main():
    """main entry point for module execution"""
    argument_spec = dict(
        src=dict(type="path"),
        replace_src=dict(),
        lines=dict(aliases=["commands"], type="list"),
        parents=dict(type="list"),
        before=dict(type="list"),
        after=dict(type="list"),
        match=dict(default="line", choices=["line", "strict", "exact", "none"]),
        replace=dict(default="line", choices=["line", "block", "config"]),
        running_config=dict(aliases=["config"]),
        intended_config=dict(),
        defaults=dict(type="bool", default=False),
        backup=dict(type="bool", default=False),
        save_when=dict(choices=["always", "never", "modified"], default="never"),
        diff_against=dict(choices=["running", "startup", "intended"]),
        diff_ignore_lines=dict(type="list"),
        # save is deprecated as of ans2.4, use save_when instead
        save=dict(default=False, type="bool", removed_in_version="2.4"),
        # force argument deprecated in ans2.2
        force=dict(default=False, type="bool", removed_in_version="2.2"),
    )

    argument_spec.update(nxos_argument_spec)

    mutually_exclusive = [
        ("lines", "src", "replace_src"),
        ("parents", "src"),
        ("save", "save_when"),
    ]

    required_if = [
        ("match", "strict", ["lines"]),
        ("match", "exact", ["lines"]),
        ("replace", "block", ["lines"]),
        ("replace", "config", ["replace_src"]),
        ("diff_against", "intended", ["intended_config"]),
    ]

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=mutually_exclusive,
        required_if=required_if,
        supports_check_mode=True,
    )

    warnings = list()
    nxos_check_args(module, warnings)

    result = {"changed": False, "warnings": warnings}

    config = None

    try:
        info = get_capabilities(module)
        api = info.get("network_api", "nxapi")
        device_info = info.get("device_info", {})
        os_platform = device_info.get("network_os_platform", "")
    except ConnectionError:
        api = ""
        os_platform = ""

    if api == "cliconf" and module.params["replace"] == "config":
        if "9K" not in os_platform:
            module.fail_json(
                msg="replace: config is supported only on Nexus 9K series switches"
            )

    if module.params["replace_src"]:
        if module.params["replace"] != "config":
            module.fail_json(msg="replace: config is required with replace_src")

    if module.params["backup"] or (
        module._diff and module.params["diff_against"] == "running"
    ):
        contents = get_config(module)
        config = NetworkConfig(indent=2, contents=contents)
        if module.params["backup"]:
            result["__backup__"] = contents

    if any(
        (module.params["src"], module.params["lines"], module.params["replace_src"])
    ):
        match = module.params["match"]
        replace = module.params["replace"]

        candidate = get_candidate(module)

        if match != "none" and replace != "config":
            config = get_running_config(module, config)
            path = module.params["parents"]
            configobjs = candidate.difference(
                config, match=match, replace=replace, path=path
            )
        else:
            configobjs = candidate.items

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

            if module.params["before"]:
                commands[:0] = module.params["before"]

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

            result["commands"] = commands
            result["updates"] = commands

            if not module.check_mode:
                load_config(module, commands)

            result["changed"] = True

    running_config = None
    startup_config = None

    diff_ignore_lines = module.params["diff_ignore_lines"]

    if module.params["save"]:
        module.params["save_when"] = "always"

    if module.params["save_when"] != "never":
        output = execute_show_commands(
            module, ["show running-config", "show startup-config"]
        )

        running_config = NetworkConfig(
            indent=1, contents=output[0], ignore_lines=diff_ignore_lines
        )
        startup_config = NetworkConfig(
            indent=1, contents=output[1], ignore_lines=diff_ignore_lines
        )

        if (
            running_config.sha1 != startup_config.sha1
            or module.params["save_when"] == "always"
        ):
            result["changed"] = True
            if not module.check_mode:
                cmd = {
                    "command": "copy running-config startup-config",
                    "output": "text",
                }
                run_commands(module, [cmd])
            else:
                module.warn(
                    "Skipping command `copy running-config startup-config` "
                    "due to check_mode.  Configuration not copied to "
                    "non-volatile storage"
                )

    if module._diff:
        if not running_config:
            output = execute_show_commands(module, "show running-config")
            contents = output[0]
        else:
            contents = running_config.config_text

        # recreate the object in order to process diff_ignore_lines
        running_config = NetworkConfig(
            indent=1, contents=contents, ignore_lines=diff_ignore_lines
        )

        if module.params["diff_against"] == "running":
            if module.check_mode:
                module.warn(
                    "unable to perform diff against running-config due to check mode"
                )
                contents = None
            else:
                contents = config.config_text

        elif module.params["diff_against"] == "startup":
            if not startup_config:
                output = execute_show_commands(module, "show startup-config")
                contents = output[0]
            else:
                contents = output[0]
                contents = startup_config.config_text

        elif module.params["diff_against"] == "intended":
            contents = module.params["intended_config"]

        if contents is not None:
            base_config = NetworkConfig(
                indent=1, contents=contents, ignore_lines=diff_ignore_lines
            )

            if running_config.sha1 != base_config.sha1:
                if module.params["diff_against"] == "intended":
                    before = running_config
                    after = base_config
                elif module.params["diff_against"] in ("startup", "running"):
                    before = base_config
                    after = running_config

                result.update(
                    {
                        "changed": True,
                        "diff": {"before": str(before), "after": str(after)},
                    }
                )

    module.exit_json(**result)