2

I am stuck getting ssl to work with the Python Cassandra driver and eventlet. We are using Python 3.4, eventlet 18.3 and Cassandra driver 3.0.0. Eventlet without ssl and ssl without eventlet both work.

Has anybody got the combination of ssl, cassandra and eventlet to work with Python? If so, what versions?

A code example may be too much to ask for, but would be very helpful.

Followup Feb 18 2016: Sorry for being so terse. Here is some code, all with Python3:

First, the simplest possible Cassandra client. No eventlet, no ssl. It works:

from cassandra.cluster import Cluster
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=None)
session = cluster.connect('<keyspace>')
print("OK, session:", session)

Next, eventlet. No threads, so eventlet is pointless here. But it works:

from cassandra.cluster import Cluster
from cassandra.io.eventletreactor import EventletConnection
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=EventletConnection)
session = cluster.connect('<keyspace>')
print("OK, session:", session)

Next, ssl, no eventlet. This also works:

import ssl
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=None,
                  ssl_options=dict(ca_certs='<certfile>',
                                   cert_reqs=ssl.CERT_REQUIRED,
                                   ssl_version=ssl.PROTOCOL_TLSv1),
                  auth_provider=PlainTextAuthProvider(username='<user>',
                                                      password='<pass>'))
session = cluster.connect('<keyspace>')
print("OK, session:", session)

Finally, ssl and eventlet. This fails:

import ssl
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from cassandra.io.eventletreactor import EventletConnection
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=EventletConnection,
                  ssl_options=dict(ca_certs='<certfile>',
                                   cert_reqs=ssl.CERT_REQUIRED,
                                   ssl_version=ssl.PROTOCOL_TLSv1),
                  auth_provider=PlainTextAuthProvider(username='<user>',
                                                      password='<pass>'))
session = cluster.connect('<keyspace>')
print("OK, session:", session)

The backtrace shows that we are using eventlet.green.ssl:

Traceback (most recent call last):
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/hubs/poll.py", line 115, in wait
    listener.cb(fileno)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/select.py", line 55, in on_read
    current.switch(([original], [], []))
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/greenthread.py", line 214, in main
    result = function(*args, **kwargs)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/cassandra/io/eventletreactor.py", line 98, in <lambda>
    self._read_watcher = eventlet.spawn(lambda: self.handle_read())
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/cassandra/io/eventletreactor.py", line 153, in handle_read
    buf = self._socket.recv(self.in_buffer_size)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/ssl.py", line 198, in recv
    read = self.read(buflen)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/ssl.py", line 138, in read
    super(GreenSSLSocket, self).read, *args, **kwargs)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/ssl.py", line 112, in _call_trampolining
    return func(*a, **kw)
  File "/home/jk/python-org/dst/python-3.5.1/lib/python3.5/ssl.py", line 786, in read
    return self._sslobj.read(len, buffer)
TypeError: must be read-write bytes-like object, not None
Removing descriptor: 5
Traceback (most recent call last):
  File "so4.py", line 13, in <module>
    session = cluster.connect('<keyspace>')
  File "cassandra/cluster.py", line 824, in cassandra.cluster.Cluster.connect (cassandra/cluster.c:11354)
  File "cassandra/cluster.py", line 850, in cassandra.cluster.Cluster.connect (cassandra/cluster.c:11176)
  File "cassandra/cluster.py", line 844, in cassandra.cluster.Cluster.connect (cassandra/cluster.c:11056)
  File "cassandra/cluster.py", line 2041, in cassandra.cluster.ControlConnection.connect (cassandra/cluster.c:36224)
  File "cassandra/cluster.py", line 2076, in cassandra.cluster.ControlConnection._reconnect_internal (cassandra/cluster.c:37080)
cassandra.cluster.NoHostAvailable: ('Unable to connect to any servers', {'<ip>': OperationTimedOut('errors=Timed out creating connection (5 seconds), last_host=None',)})

Again, no actual threads. But our real system does use them.

I didn't see any difference if I included eventlet.monkey_patch() in the setup. The real system does.

  • I am stuck getting useful technical details from this question. Even vague description of what you expect and what happens instead would be very helpful. Exact steps to reproduce, code and error message may be too much to ask for, but I ask never the less. Please, show something. – temoto Feb 15 '16 at 19:54
  • Noticed that this question now has > 1k views. This may have something to do with a more recent problem with eventlet and cassandra. In short - it doesn't work with Python 3.7, and as I am writing this, there is no solution. See https://github.com/eventlet/eventlet/issues/526 – Jon Kåre Hellan Sep 03 '19 at 13:33

1 Answers1

1

This seems to be caused by the cassandra-drivers eventlet code using select.select() on a ssl socket. This causes problems as described here: select and ssl in python

This issue is fixed in https://github.com/datastax/python-driver/pull/485

Community
  • 1
  • 1
sigmunda
  • 26
  • 2