# Buggy code
def run(self, tmp=None, task_vars=None):
    del tmp  # tmp no longer has any effect

    module = module_loader._load_module_source(
        self._task.action, module_loader.find_plugin(self._task.action)
    )
    if not getattr(module, "USE_PERSISTENT_CONNECTION", False):
        return super(ActionModule, self).run(task_vars=task_vars)

    socket_path = None

    if self._play_context.connection == "local":
        provider = load_provider(junos_provider_spec, self._task.args)
        pc = copy.deepcopy(self._play_context)
        pc.network_os = "junos"
        pc.remote_addr = provider["host"] or self._play_context.remote_addr

        if (
            provider["transport"] == "cli"
            and self._task.action not in CLI_SUPPORTED_MODULES
        ):
            return {
                "failed": True,
                "msg": "Transport type '%s' is not valid for '%s' module. "
                "Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"
                % (provider["transport"], self._task.action),
            }

        if self._task.action == "junos_netconf" or (
            provider["transport"] == "cli" and self._task.action == "junos_command"
        ):
            pc.connection = "network_cli"
            pc.port = int(provider["port"] or self._play_context.port or 22)
        else:
            pc.connection = "netconf"
            pc.port = int(provider["port"] or self._play_context.port or 830)

        pc.remote_user = provider["username"] or self._play_context.connection_user
        pc.password = provider["password"] or self._play_context.password
        pc.private_key_file = (
            provider["ssh_keyfile"] or self._play_context.private_key_file
        )
        pc.timeout = int(provider["timeout"]) if provider["timeout"] else None

        display.vvv(
            "using connection plugin %s (was local)" % pc.connection, pc.remote_addr
        )
        connection = self._shared_loader_obj.connection_loader.get(
            "persistent", pc, sys.stdin
        )

        if connection._play_context.timeout is None:
            connection._play_context.timeout = connection.get_option(
                "persistent_command_timeout"
            )

        socket_path = connection.run()
        display.vvvv("socket_path: %s" % socket_path, pc.remote_addr)
        if not socket_path:
            return {
                "failed": True,
                "msg": "unable to open shell. Please see: "
                + "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell",
            }

        task_vars["ansible_socket"] = socket_path
    elif self._play_context.connection in ("netconf", "network_cli"):
        provider = self._task.args.get("provider", {})
        if any(provider.values()):
            display.warning(
                "provider is unnecessary when using %s and will be ignored"
                % self._play_context.connection
            )
            del self._task.args["provider"]

        if (
            self._play_context.connection == "network_cli"
            and self._task.action not in CLI_SUPPORTED_MODULES
        ) or (
            self._play_context.connection == "netconf"
            and self._task.action == "junos_netconf"
        ):
            return {
                "failed": True,
                "msg": "Connection type '%s' is not valid for '%s' module. "
                "Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"
                % (self._play_context.connection, self._task.action),
            }

    if (
        self._play_context.connection == "local" and pc.connection == "network_cli"
    ) or self._play_context.connection == "network_cli":
        # make sure we are in the right cli context which should be
        # enable mode and not config module
        if socket_path is None:
            socket_path = self._connection.socket_path

        conn = Connection(socket_path)
        out = conn.get_prompt()
        while to_text(out, errors="surrogate_then_replace").strip().endswith("#"):
            display.vvvv(
                "wrong context, sending exit to device", self._play_context.remote_addr
            )
            conn.send_command("exit")
            out = conn.get_prompt()

    result = super(ActionModule, self).run(None, task_vars)
    return result


# Traceback (ValueError)
sveinov@causality:~/ansible$ ansible-playbook main.yml -vvvv
ansible-playbook 2.6.0
config file = /home/sveinov/ansible/ansible.cfg
configured module search path = [u'/home/sveinov/ansible/library']
ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
executable location = /usr/local/bin/ansible-playbook
python version = 2.7.15 (default, May  1 2018, 05:55:50) [GCC 7.3.0]
Using /home/sveinov/ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /home/sveinov/ansible/inventory/labb.yml inventory source with yaml plugin
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python2.7/dist-packages/ansible/plugins/callback/default.pyc
____________________
< PLAYBOOK: main.yml >
--------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

1 plays in main.yml
___________________________
< PLAY [Main site playbook] >
---------------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

META: ran handlers
________________________
< TASK [Gathering facts] >
------------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

task path: /home/sveinov/ansible/main.yml:9
<10.0.0.10> attempting to start connection
<10.0.0.10> using connection plugin netconf
<10.0.0.10> local domain socket does not exist, starting it
<10.0.0.10> control socket path is /home/sveinov/.ansible/pc/86ca832b46
<10.0.0.10> connection to remote device started successfully
<10.0.0.10> local domain socket listeners started successfully
<10.0.0.10>
<10.0.0.10> local domain socket path is /home/sveinov/.ansible/pc/86ca832b46
<10.0.0.10> ESTABLISH LOCAL CONNECTION FOR USER: sveinov
<10.0.0.10> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323 `" &amp;&amp; echo ansible-tmp-1530696521.94-262612295735323="` echo /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323 `" ) &amp;&amp; sleep 0'
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/network/junos/junos_facts.py
<10.0.0.10> PUT /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/tmphv8FzM TO /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323/junos_facts.py
<10.0.0.10> EXEC /bin/sh -c 'chmod u+x /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323/ /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323/junos_facts.py &amp;&amp; sleep 0'
<10.0.0.10> EXEC /bin/sh -c '/usr/bin/python /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323/junos_facts.py &amp;&amp; sleep 0'
<10.0.0.10> EXEC /bin/sh -c 'rm -f -r /home/sveinov/.ansible/tmp/ansible-local-3634_KSsU6/ansible-tmp-1530696521.94-262612295735323/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_WHmIeb/ansible_module_junos_facts.py", line 379, in <module>
main()
File "/tmp/ansible_WHmIeb/ansible_module_junos_facts.py", line 371, in main
ansible_facts.update(Facts(module).populate())
File "/tmp/ansible_WHmIeb/ansible_module_junos_facts.py", line 275, in populate
device = self._connect(self.module)
File "/tmp/ansible_WHmIeb/ansible_module_junos_facts.py", line 265, in _connect
device = Device(host, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py", line 1140, in __init__
raise ValueError("You must provide the 'host' value")
ValueError: You must provide the 'host' value

fatal: [mx204]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_WHmIeb/ansible_module_junos_facts.py\", line 379, in <module>\n    main()\n  File \"/tmp/ansible_WHmIeb/ansible_module_junos_facts.py\", line 371, in main\n    ansible_facts.update(Facts(module).populate())\n  File \"/tmp/ansible_WHmIeb/ansible_module_junos_facts.py\", line 275, in populate\n    device = self._connect(self.module)\n  File \"/tmp/ansible_WHmIeb/ansible_module_junos_facts.py\", line 265, in _connect\n    device = Device(host, **kwargs)\n  File \"/usr/local/lib/python2.7/dist-packages/jnpr/junos/device.py\", line 1140, in __init__\n    raise ValueError(\"You must provide the 'host' value\")\nValueError: You must provide the 'host' value\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1
}
to retry, use: --limit @/home/sveinov/ansible/main.retry
____________
< PLAY RECAP >
------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

mx204                      : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def run(self, tmp=None, task_vars=None):
    del tmp  # tmp no longer has any effect

    module = module_loader._load_module_source(
        self._task.action, module_loader.find_plugin(self._task.action)
    )
    if not getattr(module, "USE_PERSISTENT_CONNECTION", False):
        return super(ActionModule, self).run(task_vars=task_vars)

    socket_path = None

    if self._play_context.connection == "local":
        provider = load_provider(junos_provider_spec, self._task.args)
        pc = copy.deepcopy(self._play_context)
        pc.network_os = "junos"
        pc.remote_addr = provider["host"] or self._play_context.remote_addr

        if (
            provider["transport"] == "cli"
            and self._task.action not in CLI_SUPPORTED_MODULES
        ):
            return {
                "failed": True,
                "msg": "Transport type '%s' is not valid for '%s' module. "
                "Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"
                % (provider["transport"], self._task.action),
            }

        if self._task.action == "junos_netconf" or (
            provider["transport"] == "cli" and self._task.action == "junos_command"
        ):
            pc.connection = "network_cli"
            pc.port = int(provider["port"] or self._play_context.port or 22)
        else:
            pc.connection = "netconf"
            pc.port = int(provider["port"] or self._play_context.port or 830)

        pc.remote_user = provider["username"] or self._play_context.connection_user
        pc.password = provider["password"] or self._play_context.password
        pc.private_key_file = (
            provider["ssh_keyfile"] or self._play_context.private_key_file
        )
        pc.timeout = int(provider["timeout"]) if provider["timeout"] else None

        display.vvv(
            "using connection plugin %s (was local)" % pc.connection, pc.remote_addr
        )
        connection = self._shared_loader_obj.connection_loader.get(
            "persistent", pc, sys.stdin
        )

        if connection._play_context.timeout is None:
            connection._play_context.timeout = connection.get_option(
                "persistent_command_timeout"
            )

        socket_path = connection.run()
        display.vvvv("socket_path: %s" % socket_path, pc.remote_addr)
        if not socket_path:
            return {
                "failed": True,
                "msg": "unable to open shell. Please see: "
                + "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell",
            }

        task_vars["ansible_socket"] = socket_path
    elif self._play_context.connection in ("netconf", "network_cli"):
        provider = self._task.args.get("provider", {})
        if any(provider.values()):
            # for legacy reasons provider value is required for junos_facts(optional) and junos_package
            # modules as it uses junos_eznc library to connect to remote host
            if not (
                self._task.action == "junos_facts"
                or self._task.action == "junos_package"
            ):
                display.warning(
                    "provider is unnecessary when using %s and will be ignored"
                    % self._play_context.connection
                )
                del self._task.args["provider"]

        if (
            self._play_context.connection == "network_cli"
            and self._task.action not in CLI_SUPPORTED_MODULES
        ) or (
            self._play_context.connection == "netconf"
            and self._task.action == "junos_netconf"
        ):
            return {
                "failed": True,
                "msg": "Connection type '%s' is not valid for '%s' module. "
                "Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"
                % (self._play_context.connection, self._task.action),
            }

    if (
        self._play_context.connection == "local" and pc.connection == "network_cli"
    ) or self._play_context.connection == "network_cli":
        # make sure we are in the right cli context which should be
        # enable mode and not config module
        if socket_path is None:
            socket_path = self._connection.socket_path

        conn = Connection(socket_path)
        out = conn.get_prompt()
        while to_text(out, errors="surrogate_then_replace").strip().endswith("#"):
            display.vvvv(
                "wrong context, sending exit to device", self._play_context.remote_addr
            )
            conn.send_command("exit")
            out = conn.get_prompt()

    result = super(ActionModule, self).run(None, task_vars)
    return result