Skip to content

Commit ccdfffd

Browse files
committed
Adjust connect arguments to enable SSL using SQLAlchemy DB URI
1 parent 064e341 commit ccdfffd

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Unreleased
1313

1414
- Adjusted connect arguments to accept credentials within the HTTP URI.
1515

16+
- Adjusted connect arguments to enable SSL using SQLAlchemy DB URI.
17+
1618
2020/09/28 0.26.0
1719
=================
1820

src/crate/client/sqlalchemy/dialect.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from sqlalchemy import types as sqltypes
2626
from sqlalchemy.engine import default, reflection
2727
from sqlalchemy.sql import functions
28+
from sqlalchemy.util import asbool, to_list
2829

2930
from .compiler import (
3031
CrateCompiler,
@@ -194,8 +195,16 @@ def connect(self, host=None, port=None, *args, **kwargs):
194195
server = '{0}:{1}'.format(host, port or '4200')
195196
if 'servers' in kwargs:
196197
server = kwargs.pop('servers')
197-
if server:
198-
return self.dbapi.connect(servers=server, **kwargs)
198+
servers = to_list(server)
199+
if servers:
200+
# Evaluate "ssl" connection URI query parameter.
201+
# TODO: Evaluate more parameters like `ssl_ca`, `ssl_key`, `ssl_cert`,
202+
# `ssl_capath` and `ssl_cipher`.
203+
if "ssl" in kwargs:
204+
use_ssl = asbool(kwargs.pop("ssl"))
205+
if use_ssl:
206+
servers = ["https://" + server for server in servers]
207+
return self.dbapi.connect(servers=servers, **kwargs)
199208
return self.dbapi.connect(**kwargs)
200209

201210
def _get_default_schema_name(self, connection):

src/crate/client/sqlalchemy/tests/connection_test.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,45 @@
2525

2626
class SqlAlchemyConnectionTest(TestCase):
2727

28-
def setUp(self):
29-
self.engine = sa.create_engine('crate://')
30-
self.connection = self.engine.connect()
31-
3228
def test_default_connection(self):
3329
engine = sa.create_engine('crate://')
3430
conn = engine.raw_connection()
3531
self.assertEqual("<Connection <Client ['http://127.0.0.1:4200']>>",
3632
repr(conn.connection))
3733

38-
def test_connection_server(self):
34+
def test_connection_server_uri_http(self):
3935
engine = sa.create_engine(
4036
"crate://otherhost:19201")
4137
conn = engine.raw_connection()
4238
self.assertEqual("<Connection <Client ['http://otherhost:19201']>>",
4339
repr(conn.connection))
4440

45-
def test_connection_multiple_server(self):
41+
def test_connection_server_uri_https(self):
42+
engine = sa.create_engine(
43+
"crate://otherhost:19201/?ssl=true")
44+
conn = engine.raw_connection()
45+
self.assertEqual("<Connection <Client ['https://otherhost:19201']>>",
46+
repr(conn.connection))
47+
48+
def test_connection_server_uri_https_with_trusted_user(self):
49+
engine = sa.create_engine(
50+
"crate://foo@otherhost:19201/?ssl=true")
51+
conn = engine.raw_connection()
52+
self.assertEqual("<Connection <Client ['https://otherhost:19201']>>",
53+
repr(conn.connection))
54+
self.assertEqual(conn.connection.client.username, "foo")
55+
self.assertEqual(conn.connection.client.password, None)
56+
57+
def test_connection_server_uri_https_with_credentials(self):
58+
engine = sa.create_engine(
59+
"crate://foo:bar@otherhost:19201/?ssl=true")
60+
conn = engine.raw_connection()
61+
self.assertEqual("<Connection <Client ['https://otherhost:19201']>>",
62+
repr(conn.connection))
63+
self.assertEqual(conn.connection.client.username, "foo")
64+
self.assertEqual(conn.connection.client.password, "bar")
65+
66+
def test_connection_multiple_server_http(self):
4667
engine = sa.create_engine(
4768
"crate://", connect_args={
4869
'servers': ['localhost:4201', 'localhost:4202']
@@ -53,3 +74,16 @@ def test_connection_multiple_server(self):
5374
"<Connection <Client ['http://localhost:4201', " +
5475
"'http://localhost:4202']>>",
5576
repr(conn.connection))
77+
78+
def test_connection_multiple_server_https(self):
79+
engine = sa.create_engine(
80+
"crate://", connect_args={
81+
'servers': ['localhost:4201', 'localhost:4202'],
82+
'ssl': True,
83+
}
84+
)
85+
conn = engine.raw_connection()
86+
self.assertEqual(
87+
"<Connection <Client ['https://localhost:4201', " +
88+
"'https://localhost:4202']>>",
89+
repr(conn.connection))

0 commit comments

Comments
 (0)