Skip to content

Commit 14050ab

Browse files
committed
Merge branch 'oss-next' into ngdg_master_ft
2 parents 97de684 + 4073c0a commit 14050ab

File tree

16 files changed

+392
-228
lines changed

16 files changed

+392
-228
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ Bug Fixes
130130
* Call ConnectionException with correct kwargs (PYTHON-1117)
131131
* Can't connect to clusters built from source because version parsing doesn't handle 'x.y-SNAPSHOT' (PYTHON-1118)
132132
* Discovered node doesn´t honor the configured Cluster port on connection (PYTHON-1127)
133+
* Exception when use pk__token__gt filter In python 3.7 (PYTHON-1121)
133134

134135
Other
135136
-----

build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ build:
288288
EVENT_LOOP_MANAGER=$EVENT_LOOP_MANAGER CASSANDRA_DIR=$CCM_INSTALL_DIR DSE_VERSION=$DSE_VERSION ADS_HOME=$HOME/ VERIFY_CYTHON=$FORCE_CYTHON nosetests -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=dse_results.xml tests/integration/advanced/ || true
289289
fi
290290
291-
echo "==========RUNNING ADVANCED AND CLOUD TESTS=========="
292-
EVENT_LOOP_MANAGER=$EVENT_LOOP_MANAGER CLOUD_PROXY_PATH="$HOME/proxy/" CASSANDRA_VERSION=$CCM_CASSANDRA_VERSION MAPPED_CASSANDRA_VERSION=$MAPPED_CASSANDRA_VERSION VERIFY_CYTHON=$FORCE_CYTHON nosetests -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=advanced_results.xml tests/integration/advanced/ || true
291+
echo "==========RUNNING CLOUD TESTS=========="
292+
EVENT_LOOP_MANAGER=$EVENT_LOOP_MANAGER CLOUD_PROXY_PATH="$HOME/proxy/" CASSANDRA_VERSION=$CCM_CASSANDRA_VERSION MAPPED_CASSANDRA_VERSION=$MAPPED_CASSANDRA_VERSION VERIFY_CYTHON=$FORCE_CYTHON nosetests -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=advanced_results.xml tests/integration/cloud/ || true
293293
294294
if [ -z "$EXCLUDE_LONG" ]; then
295295
echo "==========RUNNING LONG INTEGRATION TESTS=========="

cassandra/cluster.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838

3939
import weakref
4040
from weakref import WeakValueDictionary
41+
42+
try:
43+
from cassandra.io.twistedreactor import TwistedConnection
44+
except ImportError:
45+
TwistedConnection = None
46+
4147
try:
4248
from weakref import WeakSet
4349
except ImportError:
@@ -47,7 +53,7 @@
4753
OperationTimedOut, UnsupportedOperation,
4854
SchemaTargetType, DriverException, ProtocolVersion,
4955
UnresolvableContactPoints)
50-
from cassandra.auth import _proxy_execute_key
56+
from cassandra.auth import _proxy_execute_key, PlainTextAuthProvider
5157
from cassandra.connection import (ConnectionException, ConnectionShutdown,
5258
ConnectionHeartbeat, ProtocolVersionUnsupported,
5359
EndPoint, DefaultEndPoint, DefaultEndPointFactory,
@@ -1094,13 +1100,18 @@ def __init__(self,
10941100
10951101
Any of the mutable Cluster attributes may be set as keyword arguments to the constructor.
10961102
"""
1103+
if connection_class is not None:
1104+
self.connection_class = connection_class
10971105

10981106
if cloud is not None:
10991107
if contact_points is not _NOT_SET or endpoint_factory or ssl_context or ssl_options:
11001108
raise ValueError("contact_points, endpoint_factory, ssl_context, and ssl_options "
11011109
"cannot be specified with a cloud configuration")
11021110

1103-
cloud_config = dscloud.get_cloud_config(cloud)
1111+
cloud_config = dscloud.get_cloud_config(
1112+
cloud,
1113+
create_pyopenssl_context=self.connection_class is TwistedConnection
1114+
)
11041115

11051116
ssl_context = cloud_config.ssl_context
11061117
ssl_options = {'check_hostname': True}
@@ -1192,9 +1203,6 @@ def __init__(self,
11921203
raise TypeError("address_translator should not be a class, it should be an instance of that class")
11931204
self.address_translator = address_translator
11941205

1195-
if connection_class is not None:
1196-
self.connection_class = connection_class
1197-
11981206
if timestamp_generator is not None:
11991207
if not callable(timestamp_generator):
12001208
raise ValueError("timestamp_generator must be callable")

cassandra/datastax/cloud/__init__.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,34 +75,37 @@ def from_dict(cls, d):
7575
return c
7676

7777

78-
def get_cloud_config(cloud_config):
78+
def get_cloud_config(cloud_config, create_pyopenssl_context=False):
7979
if not _HAS_SSL:
8080
raise DriverException("A Python installation with SSL is required to connect to a cloud cluster.")
8181

8282
if 'secure_connect_bundle' not in cloud_config:
8383
raise ValueError("The cloud config doesn't have a secure_connect_bundle specified.")
8484

8585
try:
86-
config = read_cloud_config_from_zip(cloud_config)
86+
config = read_cloud_config_from_zip(cloud_config, create_pyopenssl_context)
8787
except BadZipFile:
8888
raise ValueError("Unable to open the zip file for the cloud config. Check your secure connect bundle.")
8989

90-
return read_metadata_info(config, cloud_config)
90+
config = read_metadata_info(config, cloud_config)
91+
if create_pyopenssl_context:
92+
config.ssl_context = config.pyopenssl_context
93+
return config
9194

9295

93-
def read_cloud_config_from_zip(cloud_config):
96+
def read_cloud_config_from_zip(cloud_config, create_pyopenssl_context):
9497
secure_bundle = cloud_config['secure_connect_bundle']
9598
with ZipFile(secure_bundle) as zipfile:
9699
base_dir = os.path.dirname(secure_bundle)
97100
tmp_dir = tempfile.mkdtemp(dir=base_dir)
98101
try:
99102
zipfile.extractall(path=tmp_dir)
100-
return parse_cloud_config(os.path.join(tmp_dir, 'config.json'), cloud_config)
103+
return parse_cloud_config(os.path.join(tmp_dir, 'config.json'), cloud_config, create_pyopenssl_context)
101104
finally:
102105
shutil.rmtree(tmp_dir)
103106

104107

105-
def parse_cloud_config(path, cloud_config):
108+
def parse_cloud_config(path, cloud_config, create_pyopenssl_context):
106109
with open(path, 'r') as stream:
107110
data = json.load(stream)
108111

@@ -116,7 +119,11 @@ def parse_cloud_config(path, cloud_config):
116119
ca_cert_location = os.path.join(config_dir, 'ca.crt')
117120
cert_location = os.path.join(config_dir, 'cert')
118121
key_location = os.path.join(config_dir, 'key')
122+
# Regardless of if we create a pyopenssl context, we still need the builtin one
123+
# to connect to the metadata service
119124
config.ssl_context = _ssl_context_from_cert(ca_cert_location, cert_location, key_location)
125+
if create_pyopenssl_context:
126+
config.pyopenssl_context = _pyopenssl_context_from_cert(ca_cert_location, cert_location, key_location)
120127

121128
return config
122129

@@ -165,3 +172,17 @@ def _ssl_context_from_cert(ca_cert_location, cert_location, key_location):
165172
ssl_context.load_cert_chain(certfile=cert_location, keyfile=key_location)
166173

167174
return ssl_context
175+
176+
177+
def _pyopenssl_context_from_cert(ca_cert_location, cert_location, key_location):
178+
try:
179+
from OpenSSL import SSL
180+
except ImportError:
181+
return None
182+
ssl_context = SSL.Context(SSL.TLSv1_METHOD)
183+
ssl_context.set_verify(SSL.VERIFY_PEER, callback=lambda _1, _2, _3, _4, ok: ok)
184+
ssl_context.use_certificate_file(cert_location)
185+
ssl_context.use_privatekey_file(key_location)
186+
ssl_context.load_verify_locations(ca_cert_location)
187+
188+
return ssl_context

0 commit comments

Comments
 (0)