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
):
30 charm
: ops
.charm
.CharmBase
,
32 mandatory_fields
: list = [],
34 super().__init
__(charm
, relation_name
)
35 self
.relation_name
= relation_name
36 self
.mandatory_fields
= mandatory_fields
37 self
._update
_relation
()
39 def get_data_from_unit(self
, key
: str):
41 # This update relation doesn't seem to be needed, but I added it because apparently
42 # the data is empty in the unit tests.
43 # In reality, the constructor is called in every hook.
44 # In the unit tests when doing an update_relation_data, apparently it is not called.
45 self
._update
_relation
()
47 for unit
in self
.relation
.units
:
48 data
= self
.relation
.data
[unit
].get(key
)
52 def get_data_from_app(self
, key
: str):
53 if not self
.relation
or self
.relation
.app
not in self
.relation
.data
:
54 # This update relation doesn't seem to be needed, but I added it because apparently
55 # the data is empty in the unit tests.
56 # In reality, the constructor is called in every hook.
57 # In the unit tests when doing an update_relation_data, apparently it is not called.
58 self
._update
_relation
()
59 if self
.relation
and self
.relation
.app
in self
.relation
.data
:
60 data
= self
.relation
.data
[self
.relation
.app
].get(key
)
64 def is_missing_data_in_unit(self
):
65 return not all([self
.get_data_from_unit(field
) for field
in self
.mandatory_fields
])
67 def is_missing_data_in_app(self
):
68 return not all([self
.get_data_from_app(field
) for field
in self
.mandatory_fields
])
70 def _update_relation(self
):
71 self
.relation
= self
.framework
.model
.get_relation(self
.relation_name
)
74 class MysqlClient(BaseRelationClient
):
75 """Requires side of a Mysql Endpoint"""
77 mandatory_fields
= ["host", "port", "user", "password", "root_password"]
79 def __init__(self
, charm
: ops
.charm
.CharmBase
, relation_name
: str):
80 super().__init
__(charm
, relation_name
, self
.mandatory_fields
)
84 return self
.get_data_from_unit("host")
88 return self
.get_data_from_unit("port")
92 return self
.get_data_from_unit("user")
96 return self
.get_data_from_unit("password")
99 def root_password(self
):
100 return self
.get_data_from_unit("root_password")
104 return self
.get_data_from_unit("database")
106 def get_root_uri(self
, database
: str):
108 Get the URI for the mysql connection with the root user credentials
109 :param: database: Database name
110 :return: A string with the following format:
111 mysql://root:<root_password>@<mysql_host>:<mysql_port>/<database>
113 return "mysql://root:{}@{}:{}/{}".format(
114 self
.root_password
, self
.host
, self
.port
, database
119 Get the URI for the mysql connection with the standard user credentials
120 :param: database: Database name
121 :return: A string with the following format:
122 mysql://<user>:<password>@<mysql_host>:<mysql_port>/<database>
124 return "mysql://{}:{}@{}:{}/{}".format(
125 self
.user
, self
.password
, self
.host
, self
.port
, self
.database