Merge branch 'cassandra-3.11' into cassandra-4.0.0

This commit is contained in:
Ekaterina Dimitrova 2021-06-12 14:00:03 -04:00
commit d69a7e4b8a
5 changed files with 95 additions and 5 deletions

View File

@ -18,6 +18,7 @@ Merged from 3.11:
* Nodetool garbagecollect should retain SSTableLevel for LCS (CASSANDRA-16634)
* Ignore stale acks received in the shadow round (CASSANDRA-16588)
Merged from 3.0:
* CQL shell should prefer newer TLS version by default (CASSANDRA-16695)
* Ensure that existing empty rows are properly returned (CASSANDRA-16671)
* Failure to execute queries should emit a KPI other than read timeout/unavailable so it can be alerted/tracked (CASSANDRA-16581)
* Don't wait on schema versions from replacement target when replacing a node (CASSANDRA-16692)

View File

@ -48,6 +48,18 @@ def ssl_settings(host, config_file, env=os.environ):
except configparser.Error:
return None
def get_best_tls_protocol(ssl_ver_str):
# newer python versions suggest to use PROTOCOL_TLS to negotiate the highest TLS version.
# older protocol versions have been deprecated:
# https://docs.python.org/2/library/ssl.html#ssl.PROTOCOL_TLS
# https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLS
if ssl_ver_str:
return getattr(ssl, "PROTOCOL_%s" % ssl_ver_str, None)
for protocol in ['PROTOCOL_TLS', 'PROTOCOL_TLSv1_2', 'PROTOCOL_TLSv1_1', 'PROTOCOL_TLSv1']:
if hasattr(ssl, protocol):
return getattr(ssl, protocol)
return None
ssl_validate = env.get('SSL_VALIDATE')
if ssl_validate is None:
ssl_validate = get_option('ssl', 'validate')
@ -56,13 +68,11 @@ def ssl_settings(host, config_file, env=os.environ):
ssl_version_str = env.get('SSL_VERSION')
if ssl_version_str is None:
ssl_version_str = get_option('ssl', 'version')
if ssl_version_str is None:
ssl_version_str = "TLSv1"
ssl_version = getattr(ssl, "PROTOCOL_%s" % ssl_version_str, None)
ssl_version = get_best_tls_protocol(ssl_version_str)
if ssl_version is None:
sys.exit("%s is not a valid SSL protocol, please use one of SSLv23, "
"TLSv1, TLSv1.1, or TLSv1.2" % (ssl_version_str,))
sys.exit("%s is not a valid SSL protocol, please use one of "
"TLS, TLSv1_2, TLSv1_1, or TLSv1" % (ssl_version_str,))
ssl_certfile = env.get('SSL_CERTFILE')
if ssl_certfile is None:

View File

@ -0,0 +1,2 @@
[ssl]
version = TLSv1

View File

@ -0,0 +1,2 @@
[ssl]
version = invalid_ssl

View File

@ -0,0 +1,75 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from cassandra.policies import SimpleConvictionPolicy
from cassandra.pool import Host
from cqlshlib.sslhandling import ssl_settings
from nose.tools import assert_raises
import unittest
import os
import ssl
class SslSettingsTest(unittest.TestCase):
def setUp(self):
os.environ['SSL_VALIDATE'] = 'False'
self.config_file = 'test_config'
self.host = Host('10.0.0.1', SimpleConvictionPolicy, 9000)
def tearDown(self):
del os.environ['SSL_VALIDATE']
try:
del os.environ['SSL_VERSION']
except KeyError:
pass
def _test_ssl_version_from_env(self, version):
"""
Getting SSL version string from env variable SSL_VERSION.
"""
os.environ['SSL_VERSION'] = version
ssl_ret_val = ssl_settings(self.host, self.config_file)
assert ssl_ret_val is not None
assert ssl_ret_val.get('ssl_version') == getattr(ssl, 'PROTOCOL_%s' % version)
def test_ssl_versions_from_env(self):
versions = ['TLS', 'TLSv1_1', 'TLSv1_2', 'TLSv1']
for version in versions:
self._test_ssl_version_from_env(version)
def test_invalid_ssl_versions_from_env(self):
msg = "invalid_ssl is not a valid SSL protocol, please use one of TLSv1, TLSv1_1, or TLSv1_2"
with assert_raises(SystemExit) as error:
self._test_ssl_version_from_env('invalid_ssl')
assert msg == error.exception.message
def test_default_ssl_version(self):
ssl_ret_val = ssl_settings(self.host, self.config_file)
assert ssl_ret_val is not None
assert ssl_ret_val.get('ssl_version') == getattr(ssl, 'PROTOCOL_TLS')
def test_ssl_version_config(self):
ssl_ret_val = ssl_settings(self.host, os.path.join('test', 'config', 'sslhandling.config'))
assert ssl_ret_val is not None
assert ssl_ret_val.get('ssl_version') == getattr(ssl, 'PROTOCOL_TLSv1')
def test_invalid_ssl_version_config(self):
msg = "invalid_ssl is not a valid SSL protocol, please use one of TLSv1, TLSv1_1, or TLSv1_2"
with assert_raises(SystemExit) as error:
ssl_settings(self.host, os.path.join('test', 'config', 'sslhandling_invalid.config'))
assert msg in error.exception.message