Files
charm-interface-mysql-shared/provides.py
David Ames b2ed9aa73c 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
2020-06-30 15:24:52 -07:00

102 lines
3.9 KiB
Python

# Copyright 2019 Canonical Ltd
#
# Licensed 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 charms import reactive
import charmhelpers.contrib.network.ip as ch_net_ip
class MySQLSharedProvides(reactive.Endpoint):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ingress_address = ch_net_ip.get_relation_ip(self.endpoint_name)
def relation_ids(self):
return [x.relation_id for x in self.relations]
def set_ingress_address(self):
for relation in self.relations:
relation.to_publish_raw["ingress-address"] = self.ingress_address
relation.to_publish_raw["private-address"] = self.ingress_address
def available(self):
for unit in self.all_joined_units:
if unit.received['username']:
return True
for key in unit.received.keys():
if "_username" in key:
return True
return False
@reactive.when('endpoint.{endpoint_name}.joined')
def joined(self):
reactive.clear_flag(self.expand_name('{endpoint_name}.available'))
reactive.set_flag(self.expand_name('{endpoint_name}.connected'))
self.set_ingress_address()
@reactive.when('endpoint.{endpoint_name}.changed')
def changed(self):
flags = (
self.expand_name(
'endpoint.{endpoint_name}.changed.database'),
self.expand_name(
'endpoint.{endpoint_name}.changed.username'),
self.expand_name(
'endpoint.{endpoint_name}.changed.hostname'),
)
if reactive.all_flags_set(*flags):
for flag in flags:
reactive.clear_flag(flag)
if self.available():
reactive.set_flag(self.expand_name('{endpoint_name}.available'))
else:
reactive.clear_flag(self.expand_name('{endpoint_name}.available'))
@reactive.when_any('endpoint.{endpoint_name}.broken',
'endpoint.{endpoint_name}.departed')
def departed(self):
flags = (
self.expand_name('{endpoint_name}.connected'),
self.expand_name('{endpoint_name}.available'),
)
for flag in flags:
reactive.clear_flag(flag)
def set_db_connection_info(
self, relation_id, db_host, password,
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
# interface layers. In order not to have to update dozens of charms,
# publish in raw data
# No prefix for db_host and wait_timeout
self.relations[relation_id].to_publish_raw["db_host"] = db_host
self.relations[relation_id].to_publish_raw["db_port"] = db_port
if wait_timeout:
self.relations[relation_id].to_publish_raw["wait_timeout"] = (
wait_timeout)
if ssl_ca:
self.relations[relation_id].to_publish_raw["ssl_ca"] = ssl_ca
if not prefix:
self.relations[relation_id].to_publish_raw["password"] = password
self.relations[relation_id].to_publish_raw[
"allowed_units"] = allowed_units
else:
self.relations[relation_id].to_publish_raw[
"{}_password".format(prefix)] = password
self.relations[relation_id].to_publish_raw[
"{}_allowed_units".format(prefix)] = allowed_units