2 # Copyright 2022 Canonical Ltd.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
16 # For those usages not covered by the Apache License, Version 2.0 please
17 # contact: legal@canonical.com
19 # To get in touch with the maintainers, please contact:
20 # osm-charmers@lists.launchpad.net
27 class BaseRelationClient(ops
.framework
.Object
):
31 charm
: ops
.charm
.CharmBase
,
33 mandatory_fields
: list = [],
35 super().__init
__(charm
, relation_name
)
36 self
.relation_name
= relation_name
37 self
.mandatory_fields
= mandatory_fields
38 self
._update
_relation
()
40 def get_data_from_unit(self
, key
: str):
42 # This update relation doesn't seem to be needed, but I added it because apparently
43 # the data is empty in the unit tests.
44 # In reality, the constructor is called in every hook.
45 # In the unit tests when doing an update_relation_data, apparently it is not called.
46 self
._update
_relation
()
48 for unit
in self
.relation
.units
:
49 data
= self
.relation
.data
[unit
].get(key
)
53 def get_data_from_app(self
, key
: str):
54 if not self
.relation
or self
.relation
.app
not in self
.relation
.data
:
55 # This update relation doesn't seem to be needed, but I added it because apparently
56 # the data is empty in the unit tests.
57 # In reality, the constructor is called in every hook.
58 # In the unit tests when doing an update_relation_data, apparently it is not called.
59 self
._update
_relation
()
60 if self
.relation
and self
.relation
.app
in self
.relation
.data
:
61 data
= self
.relation
.data
[self
.relation
.app
].get(key
)
65 def is_missing_data_in_unit(self
):
66 return not all([self
.get_data_from_unit(field
) for field
in self
.mandatory_fields
])
68 def is_missing_data_in_app(self
):
69 return not all([self
.get_data_from_app(field
) for field
in self
.mandatory_fields
])
71 def _update_relation(self
):
72 self
.relation
= self
.framework
.model
.get_relation(self
.relation_name
)
75 class MysqlClient(BaseRelationClient
):
76 """Requires side of a Mysql Endpoint"""
78 mandatory_fields
= ["host", "port", "user", "password", "root_password"]
80 def __init__(self
, charm
: ops
.charm
.CharmBase
, relation_name
: str):
81 super().__init
__(charm
, relation_name
, self
.mandatory_fields
)
85 return self
.get_data_from_unit("host")
89 return self
.get_data_from_unit("port")
93 return self
.get_data_from_unit("user")
97 return self
.get_data_from_unit("password")
100 def root_password(self
):
101 return self
.get_data_from_unit("root_password")
105 return self
.get_data_from_unit("database")
107 def get_root_uri(self
, database
: str):
109 Get the URI for the mysql connection with the root user credentials
110 :param: database: Database name
111 :return: A string with the following format:
112 mysql://root:<root_password>@<mysql_host>:<mysql_port>/<database>
114 return "mysql://root:{}@{}:{}/{}".format(
115 self
.root_password
, self
.host
, self
.port
, database
120 Get the URI for the mysql connection with the standard user credentials
121 :param: database: Database name
122 :return: A string with the following format:
123 mysql://<user>:<password>@<mysql_host>:<mysql_port>/<database>
125 return "mysql://{}:{}@{}:{}/{}".format(
126 self
.user
, self
.password
, self
.host
, self
.port
, self
.database