Enable MySQL TLS

Enable passing the certificate authority on the relation in order to
enable TLS communication to the MySQL DB.

In order to enable MySQL to use TLS for client connections all that
is required is the CA certificate. A certificate and key may be used
for client certificate authentication. However, since almost all
deployments will not use certificate authentication, focusing on the CA as SSL
data complete makes sense.

Change-Id: I785afe7f64cb57caa857178d529e3cabdcf63517
This commit is contained in:
David Ames
2020-06-30 15:24:52 -07:00
parent c31027400a
commit b2ed9aa73c
3 changed files with 7 additions and 5 deletions

View File

@@ -76,7 +76,8 @@ class MySQLSharedProvides(reactive.Endpoint):
def set_db_connection_info( def set_db_connection_info(
self, relation_id, db_host, password, self, relation_id, db_host, password,
allowed_units=None, prefix=None, wait_timeout=None, db_port=3306): allowed_units=None, prefix=None, wait_timeout=None, db_port=3306,
ssl_ca=None):
# Implementations of shared-db pre-date the json encoded era of # Implementations of shared-db pre-date the json encoded era of
# interface layers. In order not to have to update dozens of charms, # interface layers. In order not to have to update dozens of charms,
# publish in raw data # publish in raw data
@@ -87,6 +88,8 @@ class MySQLSharedProvides(reactive.Endpoint):
if wait_timeout: if wait_timeout:
self.relations[relation_id].to_publish_raw["wait_timeout"] = ( self.relations[relation_id].to_publish_raw["wait_timeout"] = (
wait_timeout) wait_timeout)
if ssl_ca:
self.relations[relation_id].to_publish_raw["ssl_ca"] = ssl_ca
if not prefix: if not prefix:
self.relations[relation_id].to_publish_raw["password"] = password self.relations[relation_id].to_publish_raw["password"] = password
self.relations[relation_id].to_publish_raw[ self.relations[relation_id].to_publish_raw[

View File

@@ -205,10 +205,8 @@ class MySQLSharedRequires(RelationBase):
""" """
Check if optional ssl data provided by mysql is complete. Check if optional ssl data provided by mysql is complete.
""" """
# Note: ssl_ca can also be set but isn't required
data = { data = {
'ssl_cert': self.ssl_cert(), 'ssl_ca': self.ssl_ca(),
'ssl_key': self.ssl_key(),
} }
if all(data.values()): if all(data.values()):
return True return True

View File

@@ -182,10 +182,11 @@ class TestMySQLSharedRequires(unittest.TestCase):
assert self.mysql_shared.access_network_data_complete() is False assert self.mysql_shared.access_network_data_complete() is False
def test_ssl_data_incomplete(self): def test_ssl_data_incomplete(self):
self.patch_mysql_shared('ssl_ca', "Certificate Authority")
self.patch_mysql_shared('ssl_cert', "somecert") self.patch_mysql_shared('ssl_cert', "somecert")
self.patch_mysql_shared('ssl_key', "somekey") self.patch_mysql_shared('ssl_key', "somekey")
assert self.mysql_shared.ssl_data_complete() is True assert self.mysql_shared.ssl_data_complete() is True
self.ssl_key.return_value = None self.ssl_ca.return_value = None
assert self.mysql_shared.ssl_data_complete() is False assert self.mysql_shared.ssl_data_complete() is False
def test_local_accessors(self): def test_local_accessors(self):