Repository: dask/distributed

Issue:
get_client() not working from TLS-enabled worker
Hi,

it seems that ``worker.get_client()`` does not work from a worker that uses SSL.

to reproduce use environment from #2282 and run the following small example:
```python
# use venv/bin/python so you have the same version as worker/scheduler
from distributed import Client
from distributed.security import Security

s = Security(tls_ca_file="dask.pem", tls_client_cert="dask.pem", tls_client_key="dask.pem")
c = Client("tls://localhost:8786", security=s)

# To validate that this is only a TLS issue use the following client (against a non-ssl dask environment) instead:
# c=Client("localhost:8786")

def schedule_from_client():
    # this is run on the worker
    from dask.distributed import get_client
    def schedule_from_worker():
        return "worker scheduled me"

    client = get_client()  # get a client from the worker and schedule the function above
    # schedule the function  using the client
    result = client.get({"schedule_from_worker": (schedule_from_worker,)}, ["schedule_from_worker"], sync=True, pure=False) 
    return result


result = c.get({"schedule_from_client": (schedule_from_client,)}, ["schedule_from_client"], sync=True, pure=False)
print(result)

```
**Versions**: ``distributed==1.23.2, dask==0.19.2, tornado==5.1.1``
**Expected Result:** (this is what you get running without TLS): ``[['worker scheduled me']]``
**Actual Result**: [full stacktrace](https://github.com/dask/distributed/files/2449869/output.txt)
```
[...] venv/local/lib/python2.7/site-packages/distributed/comm/tcp.py", line 303, in _expect_tls_context
    raise TypeError("TLS expects a `ssl_context` argument of type "
```
I'm going to try and build an even more minimal reproducer as @mrocklin did in #2282. If I succeed I'll adapt the issue.

**edit:** slight modification of the reproducer for readability.



Discussion:
I tried building a minimal example into a unit test like in the comments of #2282. Interestingly ``get_client()`` does not raise when run in the local_cluster environment used for the unit tests with tls. Nevertheless with the setup of an actual cluster as described in the issue description #2282 ``get_client()``  from a worker reproducibly raises the Exception above. 

My guess is that some local state leaks between client and worker in the unit test scenario allowing the worker to correctly connect using TLS. The leak cant happen in the real-world scenario where worker, scheduler and client run in different processes, exposing the error.

Resolving patch:
diff --git a/distributed/client.py b/distributed/client.py
--- a/distributed/client.py
+++ b/distributed/client.py
@@ -543,7 +543,12 @@ def __init__(self, address=None, loop=None, timeout=no_default,
         self.security = security or Security()
         self.scheduler_comm = None
         assert isinstance(self.security, Security)
-        self.connection_args = self.security.get_connection_args('client')
+
+        if name == 'worker':
+            self.connection_args = self.security.get_connection_args('worker')
+        else:
+            self.connection_args = self.security.get_connection_args('client')
+
         self._connecting_to_scheduler = False
         self._asynchronous = asynchronous
         self._should_close_loop = not loop


Test patch: