66from urllib .parse import parse_qs , urlparse
77
88import contextlib
9+ import logging
910import pymysql
1011import re
1112
13+ LOGGER = logging .getLogger (__name__ )
14+
1215DEFAULT_MYSQL_PORT = 3306
1316
1417ROUTINE_DEFINER_RE = re .compile ("^CREATE DEFINER *= *(`.*?`@`.*?`) +(.*$)" )
@@ -30,14 +33,23 @@ class MySQLConnectionInfo:
3033 username : str
3134 password : str
3235 ssl : Optional [bool ] = True
36+ sslca : Optional [str ] = None
37+ sslcert : Optional [str ] = None
38+ sslkey : Optional [str ] = None
3339
3440 name : Optional [str ] = None
3541
3642 _version : Optional [str ] = None
3743 _global_grants : Optional [List [str ]] = None
3844
3945 @staticmethod
40- def from_uri (uri : str , name : Optional [str ] = None ):
46+ def from_uri (
47+ uri : str ,
48+ name : Optional [str ] = None ,
49+ sslca : Optional [str ] = None ,
50+ sslcert : Optional [str ] = None ,
51+ sslkey : Optional [str ] = None
52+ ):
4153 try :
4254 res = urlparse (uri , scheme = "mysql" )
4355 if res .scheme != "mysql" or not res .username or not res .password or not res .hostname :
@@ -49,13 +61,31 @@ def from_uri(uri: str, name: Optional[str] = None):
4961 port = res .port or DEFAULT_MYSQL_PORT
5062 options = parse_qs (res .query )
5163 ssl = not (options and options .get ("ssl-mode" , ["DISABLE" ]) == ["DISABLE" ])
52- return MySQLConnectionInfo (
53- hostname = res .hostname , port = port , username = res .username , password = res .password , ssl = ssl , name = name
54- )
64+
65+ LOGGER .debug ("from_uri - sslca:[%s], sslcert:[%s], sslkey:[%s]" , sslca , sslcert , sslkey )
66+ if sslca and sslcert and sslkey :
67+ return MySQLConnectionInfo (
68+ hostname = res .hostname ,
69+ port = port ,
70+ username = res .username ,
71+ password = res .password ,
72+ ssl = ssl ,
73+ sslca = sslca ,
74+ sslcert = sslcert ,
75+ sslkey = sslkey ,
76+ name = name
77+ )
78+ else :
79+ return MySQLConnectionInfo (
80+ hostname = res .hostname , port = port , username = res .username , password = res .password , ssl = ssl , name = name
81+ )
5582
5683 def to_uri (self ):
5784 ssl_mode = "DISABLE" if not self .ssl else "REQUIRE"
58- return f"mysql://{ self .username } :{ self .password } @{ self .hostname } :{ self .port } /?ssl-mode={ ssl_mode } "
85+ ssl_auth = f"&ssl-ca={ self .sslca } &ssl-cert={ self .sslcert } &ssl-key={ self .sslkey } " \
86+ if self .sslca and self .sslcert and self .sslcert else ""
87+ LOGGER .debug ("ssl_auth:[%s]]" , ssl_auth )
88+ return f"mysql://{ self .username } :{ self .password } @{ self .hostname } :{ self .port } /?ssl-mode={ ssl_mode } { ssl_auth } "
5989
6090 def repr (self ):
6191 return self .name
@@ -64,18 +94,37 @@ def _connect(self):
6494 ssl = None
6595 if self .ssl :
6696 ssl = {"require" : True }
67- return pymysql .connect (
68- charset = "utf8mb4" ,
69- connect_timeout = config .MYSQL_CONNECTION_TIMEOUT ,
70- cursorclass = pymysql .cursors .DictCursor ,
71- host = self .hostname ,
72- password = self .password ,
73- read_timeout = config .MYSQL_READ_TIMEOUT ,
74- port = self .port ,
75- ssl = ssl ,
76- user = self .username ,
77- write_timeout = config .MYSQL_WRITE_TIMEOUT ,
78- )
97+
98+ if self .sslca and self .sslcert and self .sslkey :
99+ LOGGER .debug ("connect [%s]- sslca:[%s], sslcert:[%s], sslkey:[%s]" ,
100+ self .name , self .sslca , self .sslcert , self .sslkey )
101+ return pymysql .connect (
102+ charset = "utf8mb4" ,
103+ connect_timeout = config .MYSQL_CONNECTION_TIMEOUT ,
104+ cursorclass = pymysql .cursors .DictCursor ,
105+ host = self .hostname ,
106+ password = self .password ,
107+ read_timeout = config .MYSQL_READ_TIMEOUT ,
108+ port = self .port ,
109+ ssl_ca = self .sslca ,
110+ ssl_cert = self .sslcert ,
111+ ssl_key = self .sslkey ,
112+ user = self .username ,
113+ write_timeout = config .MYSQL_WRITE_TIMEOUT ,
114+ )
115+ else :
116+ return pymysql .connect (
117+ charset = "utf8mb4" ,
118+ connect_timeout = config .MYSQL_CONNECTION_TIMEOUT ,
119+ cursorclass = pymysql .cursors .DictCursor ,
120+ host = self .hostname ,
121+ password = self .password ,
122+ read_timeout = config .MYSQL_READ_TIMEOUT ,
123+ port = self .port ,
124+ ssl = ssl ,
125+ user = self .username ,
126+ write_timeout = config .MYSQL_WRITE_TIMEOUT ,
127+ )
79128
80129 @property
81130 def version (self ) -> str :
0 commit comments