| import os |
| import pytest |
| import logging |
| |
| from cassandra import ConsistencyLevel |
| from cassandra.cluster import NoHostAvailable |
| |
| from dtest import Tester, create_ks, create_cf |
| from tools.data import putget |
| from tools.misc import generate_ssl_stores |
| |
| since = pytest.mark.since |
| logger = logging.getLogger(__name__) |
| |
| |
| class TestNativeTransportSSL(Tester): |
| """ |
| Native transport integration tests, specifically for ssl and port configurations. |
| """ |
| |
| def test_connect_to_ssl(self): |
| """ |
| Connecting to SSL enabled native transport port should only be possible using SSL enabled client |
| """ |
| cluster = self._populateCluster(enableSSL=True) |
| node1 = cluster.nodelist()[0] |
| |
| cluster.start() |
| |
| try: # hack around assertRaise's lack of msg parameter |
| # try to connect without ssl options |
| self.patient_cql_connection(node1) |
| self.fail('Should not be able to connect to SSL socket without SSL enabled client') |
| except NoHostAvailable: |
| pass |
| |
| if cluster.version() >= '4.0': |
| assert len(node1.grep_log("javax.net.ssl.SSLHandshakeException")) > 0, \ |
| "Missing SSL handshake exception while connecting with non-SSL enabled client" |
| else: |
| assert len(node1.grep_log("io.netty.handler.ssl.NotSslRecordException.*")) > 0, \ |
| "Missing SSL handshake exception while connecting with non-SSL enabled client" |
| |
| # enabled ssl on the client and try again (this should work) |
| session = self.patient_cql_connection(node1, ssl_opts={'ca_certs': os.path.join(self.fixture_dtest_setup.test_path, 'ccm_node.cer')}) |
| self._putget(cluster, session) |
| |
| def test_connect_to_ssl_optional(self): |
| """ |
| Connecting to SSL optional native transport port must be possible with SSL and non-SSL native clients |
| @jira_ticket CASSANDRA-10559 |
| """ |
| cluster = self._populateCluster(enableSSL=True, sslOptional=True) |
| node1 = cluster.nodelist()[0] |
| |
| # try to connect without ssl options |
| cluster.start() |
| session = self.patient_cql_connection(node1) |
| self._putget(cluster, session) |
| |
| # enabled ssl on the client and try again (this should work) |
| session = self.patient_cql_connection(node1, ssl_opts={'ca_certs': os.path.join(self.fixture_dtest_setup.test_path, 'ccm_node.cer')}) |
| self._putget(cluster, session, ks='ks2') |
| |
| def test_use_custom_port(self): |
| """ |
| Connect to non-default native transport port |
| """ |
| cluster = self._populateCluster(nativePort=9567) |
| node1 = cluster.nodelist()[0] |
| |
| cluster.start() |
| try: # hack around assertRaise's lack of msg parameter |
| self.patient_cql_connection(node1) |
| self.fail('Should not be able to connect to non-default port') |
| except NoHostAvailable: |
| pass |
| |
| session = self.patient_cql_connection(node1, port=9567) |
| self._putget(cluster, session) |
| |
| @since('3.0') |
| def test_use_custom_ssl_port(self): |
| """ |
| Connect to additional ssl enabled native transport port |
| @jira_ticket CASSANDRA-9590 |
| """ |
| cluster = self._populateCluster(enableSSL=True, nativePortSSL=9666) |
| node1 = cluster.nodelist()[0] |
| cluster.start() |
| |
| # we should be able to connect to default non-ssl port |
| session = self.patient_cql_connection(node1) |
| self._putget(cluster, session) |
| |
| # connect to additional dedicated ssl port |
| session = self.patient_cql_connection(node1, port=9666, ssl_opts={'ca_certs': os.path.join(self.fixture_dtest_setup.test_path, 'ccm_node.cer')}) |
| self._putget(cluster, session, ks='ks2') |
| |
| def _populateCluster(self, enableSSL=False, nativePort=None, nativePortSSL=None, sslOptional=False): |
| cluster = self.cluster |
| |
| if enableSSL: |
| generate_ssl_stores(self.fixture_dtest_setup.test_path) |
| # C* versions before 3.0 (CASSANDRA-10559) do not know about |
| # 'client_encryption_options.optional' - so we must not add that parameter |
| if sslOptional: |
| cluster.set_configuration_options({ |
| 'client_encryption_options': { |
| 'enabled': True, |
| 'optional': sslOptional, |
| 'keystore': os.path.join(self.fixture_dtest_setup.test_path, 'keystore.jks'), |
| 'keystore_password': 'cassandra' |
| } |
| }) |
| else: |
| cluster.set_configuration_options({ |
| 'client_encryption_options': { |
| 'enabled': True, |
| 'keystore': os.path.join(self.fixture_dtest_setup.test_path, 'keystore.jks'), |
| 'keystore_password': 'cassandra' |
| } |
| }) |
| |
| if nativePort: |
| cluster.set_configuration_options({ |
| 'native_transport_port': nativePort |
| }) |
| |
| if nativePortSSL: |
| cluster.set_configuration_options({ |
| 'native_transport_port_ssl': nativePortSSL |
| }) |
| |
| cluster.populate(1) |
| return cluster |
| |
| def _putget(self, cluster, session, ks='ks', cf='cf'): |
| create_ks(session, ks, 1) |
| create_cf(session, cf, compression=None) |
| putget(cluster, session, cl=ConsistencyLevel.ONE) |