Skip to content

Commit 0978187

Browse files
Address PR feedback
1 parent 03d4ed4 commit 0978187

6 files changed

+55
-40
lines changed

src/abstract_charm.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,11 @@ def _exposed_read_only_endpoint(self) -> str:
110110
"""The exposed read-only endpoint"""
111111

112112
@abc.abstractmethod
113-
def is_externally_accessible(self, event=None) -> typing.Optional[bool]:
114-
"""Whether endpoints should be externally accessible"""
113+
def is_externally_accessible(self, *, event) -> typing.Optional[bool]:
114+
"""Whether endpoints should be externally accessible.
115+
116+
Only defined in vm charm to return True/False. In k8s charm, returns None.
117+
"""
115118

116119
@property
117120
def _tls_certificate_saved(self) -> bool:
@@ -208,7 +211,7 @@ def set_status(self, *, event, app=True, unit=True) -> None:
208211
logger.debug(f"Set unit status to {self.unit.status}")
209212

210213
@abc.abstractmethod
211-
def wait_until_mysql_router_ready(self) -> None:
214+
def wait_until_mysql_router_ready(self, *, event) -> None:
212215
"""Wait until a connection to MySQL Router is possible.
213216
214217
Retry every 5 seconds for up to 30 seconds.
@@ -268,6 +271,7 @@ def reconcile(self, event=None) -> None: # noqa: C901
268271
if self._upgrade.unit_state == "outdated":
269272
if self._upgrade.authorized:
270273
self._upgrade.upgrade_unit(
274+
event=event,
271275
workload_=workload_,
272276
tls=self._tls_certificate_saved,
273277
exporter_config=self._cos_exporter_config(event),
@@ -310,6 +314,7 @@ def reconcile(self, event=None) -> None: # noqa: C901
310314
)
311315
if workload_.container_ready:
312316
workload_.reconcile(
317+
event=event,
313318
tls=self._tls_certificate_saved,
314319
unit_name=self.unit.name,
315320
exporter_config=self._cos_exporter_config(event),

src/machine_charm.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,21 @@ def _exposed_read_write_endpoint(self) -> str:
8383
def _exposed_read_only_endpoint(self) -> str:
8484
return f"{self.host_address}:{self._READ_ONLY_PORT}"
8585

86-
def is_externally_accessible(self, event=None) -> typing.Optional[bool]:
86+
def is_externally_accessible(self, *, event) -> typing.Optional[bool]:
8787
return self._database_provides.external_connectivity(event)
8888

8989
def _reconcile_node_port(self, *, event) -> None:
9090
"""Only applies to Kubernetes charm, so no-op."""
9191
pass
9292

9393
def _reconcile_ports(self, *, event) -> None:
94-
if self.is_externally_accessible(event):
94+
if self.is_externally_accessible(event=event):
9595
ports = [self._READ_WRITE_PORT, self._READ_ONLY_PORT]
9696
else:
9797
ports = []
9898
self.unit.set_ports(*ports)
9999

100-
def wait_until_mysql_router_ready(self) -> None:
100+
def wait_until_mysql_router_ready(self, *, event) -> None:
101101
logger.debug("Waiting until MySQL Router is ready")
102102
self.unit.status = ops.MaintenanceStatus("MySQL Router starting")
103103
try:
@@ -107,7 +107,7 @@ def wait_until_mysql_router_ready(self) -> None:
107107
wait=tenacity.wait_fixed(5),
108108
):
109109
with attempt:
110-
if self.is_externally_accessible():
110+
if self.is_externally_accessible(event=event):
111111
for port in (
112112
self._READ_WRITE_PORT,
113113
self._READ_ONLY_PORT,
@@ -173,7 +173,7 @@ def _on_force_upgrade_action(self, event: ops.ActionEvent) -> None:
173173
logger.debug("Forcing upgrade")
174174
event.log(f"Forcefully upgrading {self.unit.name}")
175175
self._upgrade.upgrade_unit(
176-
workload_=self.get_workload(event=None), tls=self._tls_certificate_saved
176+
event=event, workload_=self.get_workload(event=None), tls=self._tls_certificate_saved
177177
)
178178
self.reconcile()
179179
event.set_results({"result": f"Forcefully upgraded {self.unit.name}"})

src/machine_upgrade.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,14 @@ def authorized(self) -> bool:
158158
def upgrade_unit(
159159
self,
160160
*,
161+
event,
161162
workload_: workload.Workload,
162163
tls: bool,
163164
exporter_config: "relations.cos.ExporterConfig",
164165
) -> None:
165166
logger.debug(f"Upgrading {self.authorized=}")
166167
self.unit_state = "upgrading"
167-
workload_.upgrade(unit=self._unit, tls=tls, exporter_config=exporter_config)
168+
workload_.upgrade(event=event, unit=self._unit, tls=tls, exporter_config=exporter_config)
168169
self._unit_workload_container_version = snap.REVISION
169170
self._unit_workload_version = self._current_versions["workload"]
170171
logger.debug(

src/machine_workload.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,21 @@
1111

1212
import workload
1313

14+
if typing.TYPE_CHECKING:
15+
import relations.database_requires
16+
1417
logger = logging.getLogger(__name__)
1518

1619

1720
class AuthenticatedMachineWorkload(workload.AuthenticatedWorkload):
1821
"""Workload with connection to MySQL cluster and with Unix sockets enabled"""
1922

2023
# TODO python3.10 min version: Use `list` instead of `typing.List`
21-
def _get_bootstrap_command(self, password: str) -> typing.List[str]:
22-
command = super()._get_bootstrap_command(password)
23-
if self._charm.is_externally_accessible():
24+
def _get_bootstrap_command(
25+
self, *, event, connection_info: "relations.database_requires.ConnectionInformation"
26+
) -> typing.List[str]:
27+
command = super()._get_bootstrap_command(connection_info)
28+
if self._charm.is_externally_accessible(event=event):
2429
command.extend(
2530
[
2631
"--conf-bind-address",
@@ -65,7 +70,7 @@ def _update_configured_socket_file_locations(self) -> None:
6570
self._container.router_config_file.write_text(output.getvalue())
6671
logger.debug("Updated configured socket file locations")
6772

68-
def _bootstrap_router(self, *, tls: bool) -> None:
69-
super()._bootstrap_router(tls=tls)
70-
if not self._charm.is_externally_accessible():
73+
def _bootstrap_router(self, *, event, tls: bool) -> None:
74+
super()._bootstrap_router(event=event, tls=tls)
75+
if not self._charm.is_externally_accessible(event=event):
7176
self._update_configured_socket_file_locations()

src/relations/tls.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ def save_certificate(self, event: tls_certificates.CertificateAvailableEvent) ->
111111
logger.debug(f"Saved TLS certificate {event=}")
112112
self._charm.reconcile(event=None)
113113

114-
def _generate_csr(self, key: bytes) -> bytes:
114+
def _generate_csr(self, *, event, key: bytes) -> bytes:
115115
"""Generate certificate signing request (CSR)."""
116116
sans_ip = ["127.0.0.1"] # needed for the HTTP server when related with COS
117-
if self._charm.is_externally_accessible():
117+
if self._charm.is_externally_accessible(event=event):
118118
sans_ip.append(self._charm.host_address)
119119

120120
return tls_certificates.generate_csr(
@@ -124,23 +124,23 @@ def _generate_csr(self, key: bytes) -> bytes:
124124
sans_ip=sans_ip,
125125
)
126126

127-
def request_certificate_creation(self):
127+
def request_certificate_creation(self, *, event):
128128
"""Request new TLS certificate from related provider charm."""
129129
logger.debug("Requesting TLS certificate creation")
130-
csr = self._generate_csr(self.key.encode("utf-8"))
130+
csr = self._generate_csr(event=event, key=self.key.encode("utf-8"))
131131
self._interface.request_certificate_creation(certificate_signing_request=csr)
132132
self._secrets.set_value(
133133
relations.secrets.UNIT_SCOPE, _TLS_REQUESTED_CSR, csr.decode("utf-8")
134134
)
135135
logger.debug("Requested TLS certificate creation")
136136

137-
def request_certificate_renewal(self):
137+
def request_certificate_renewal(self, *, event):
138138
"""Request TLS certificate renewal from related provider charm."""
139139
logger.debug("Requesting TLS certificate renewal")
140140
old_csr = self._secrets.get_value(relations.secrets.UNIT_SCOPE, _TLS_ACTIVE_CSR).encode(
141141
"utf-8"
142142
)
143-
new_csr = self._generate_csr(self.key.encode("utf-8"))
143+
new_csr = self._generate_csr(event=event, key=self.key.encode("utf-8"))
144144
self._interface.request_certificate_renewal(
145145
old_certificate_signing_request=old_csr, new_certificate_signing_request=new_csr
146146
)
@@ -252,7 +252,7 @@ def _on_set_tls_private_key(self, event: ops.ActionEvent) -> None:
252252
logger.debug("No TLS certificate relation active. Skipped certificate request")
253253
else:
254254
try:
255-
self._relation.request_certificate_creation()
255+
self._relation.request_certificate_creation(event=event)
256256
except Exception as e:
257257
event.fail(f"Failed to request certificate: {e}")
258258
logger.exception(
@@ -261,9 +261,9 @@ def _on_set_tls_private_key(self, event: ops.ActionEvent) -> None:
261261
raise
262262
logger.debug("Handled set TLS private key action")
263263

264-
def _on_tls_relation_created(self, _) -> None:
264+
def _on_tls_relation_created(self, event) -> None:
265265
"""Request certificate when TLS relation created."""
266-
self._relation.request_certificate_creation()
266+
self._relation.request_certificate_creation(event)
267267

268268
def _on_tls_relation_broken(self, _) -> None:
269269
"""Delete TLS certificate."""
@@ -283,4 +283,4 @@ def _on_certificate_expiring(self, event: tls_certificates.CertificateExpiringEv
283283
logger.warning("Unknown certificate expiring")
284284
return
285285

286-
self._relation.request_certificate_renewal()
286+
self._relation.request_certificate_renewal(event)

src/workload.py

+19-15
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def version(self) -> str:
7777
return ""
7878

7979
def upgrade(
80-
self, *, unit: ops.Unit, tls: bool, exporter_config: "relations.cos.ExporterConfig"
80+
self, *, event, unit: ops.Unit, tls: bool, exporter_config: "relations.cos.ExporterConfig"
8181
) -> None:
8282
"""Upgrade MySQL Router.
8383
@@ -157,6 +157,7 @@ def _disable_router(self) -> None:
157157
def reconcile(
158158
self,
159159
*,
160+
event,
160161
tls: bool,
161162
unit_name: str,
162163
exporter_config: "relations.cos.ExporterConfig",
@@ -253,15 +254,17 @@ def _get_bootstrap_command(
253254
"--conf-use-gr-notifications",
254255
]
255256

256-
def _bootstrap_router(self, *, tls: bool) -> None:
257+
def _bootstrap_router(self, *, event, tls: bool) -> None:
257258
"""Bootstrap MySQL Router."""
258259
logger.debug(
259260
f"Bootstrapping router {tls=}, {self._connection_info.host=}, {self._connection_info.port=}"
260261
)
261262
# Redact password from log
262-
logged_command = self._get_bootstrap_command(self._connection_info.redacted)
263+
logged_command = self._get_bootstrap_command(
264+
event=event, connection_info=self._connection_info.redacted
265+
)
263266

264-
command = self._get_bootstrap_command(self._connection_info)
267+
command = self._get_bootstrap_command(event=event, connection_info=self._connection_info)
265268
try:
266269
self._container.run_mysql_router(command, timeout=30)
267270
except container.CalledProcessError as e:
@@ -311,31 +314,31 @@ def _router_username(self) -> str:
311314
"""
312315
return self._parse_username_from_config(self._container.router_config_file.read_text())
313316

314-
def _restart(self, *, tls: bool) -> None:
317+
def _restart(self, *, event, tls: bool) -> None:
315318
"""Restart MySQL Router to enable or disable TLS."""
316319
logger.debug("Restarting MySQL Router")
317320
assert self._container.mysql_router_service_enabled is True
318321
self._container.update_mysql_router_service(enabled=True, tls=tls)
319322
logger.debug("Restarted MySQL Router")
320-
self._charm.wait_until_mysql_router_ready()
323+
self._charm.wait_until_mysql_router_ready(event)
321324
# wait_until_mysql_router_ready will set WaitingStatus—override it with current charm
322325
# status
323326
self._charm.set_status(event=None)
324327

325-
def _enable_router(self, *, tls: bool, unit_name: str) -> None:
328+
def _enable_router(self, *, event, tls: bool, unit_name: str) -> None:
326329
"""Enable router after setting up all the necessary prerequisites."""
327330
logger.debug("Enabling MySQL Router service")
328331
self._cleanup_after_upgrade_or_potential_container_restart()
329332
# create an empty credentials file, if the file does not exist
330333
self._container.create_router_rest_api_credentials_file()
331-
self._bootstrap_router(tls=tls)
334+
self._bootstrap_router(event=event, tls=tls)
332335
self.shell.add_attributes_to_mysql_router_user(
333336
username=self._router_username, router_id=self._router_id, unit_name=unit_name
334337
)
335338
self._container.update_mysql_router_service(enabled=True, tls=tls)
336339
self._logrotate.enable()
337340
logger.debug("Enabled MySQL Router service")
338-
self._charm.wait_until_mysql_router_ready()
341+
self._charm.wait_until_mysql_router_ready(event)
339342

340343
def _enable_exporter(
341344
self, *, tls: bool, exporter_config: "relations.cos.ExporterConfig"
@@ -356,6 +359,7 @@ def _enable_exporter(
356359
def reconcile(
357360
self,
358361
*,
362+
event,
359363
tls: bool,
360364
unit_name: str,
361365
exporter_config: "relations.cos.ExporterConfig",
@@ -376,23 +380,23 @@ def reconcile(
376380
key=key, certificate=certificate, certificate_authority=certificate_authority
377381
)
378382
if custom_certificate != certificate and self._container.mysql_router_service_enabled:
379-
self._restart(tls=tls)
383+
self._restart(event=event, tls=tls)
380384
else:
381385
self._disable_tls()
382386
if custom_certificate and self._container.mysql_router_service_enabled:
383-
self._restart(tls=tls)
387+
self._restart(event=event, tls=tls)
384388

385389
# If the host or port changes, MySQL Router will receive topology change
386390
# notifications from MySQL.
387391
# Therefore, if the host or port changes, we do not need to restart MySQL Router.
388-
is_charm_exposed = self._charm.is_externally_accessible()
392+
is_charm_exposed = self._charm.is_externally_accessible(event=event)
389393
socket_file_exists = self._container.path("/run/mysqlrouter/mysql.sock").exists()
390394
require_rebootstrap = is_charm_exposed == socket_file_exists
391395
if require_rebootstrap:
392396
self._disable_router()
393397

394398
if not self._container.mysql_router_service_enabled:
395-
self._enable_router(tls=tls, unit_name=unit_name)
399+
self._enable_router(event=event, tls=tls, unit_name=unit_name)
396400

397401
if (not self._container.mysql_router_exporter_service_enabled and exporter_config) or (
398402
self._container.mysql_router_exporter_service_enabled
@@ -417,7 +421,7 @@ def status(self) -> typing.Optional[ops.StatusBase]:
417421
)
418422

419423
def upgrade(
420-
self, *, unit: ops.Unit, tls: bool, exporter_config: "relations.cos.ExporterConfig"
424+
self, *, event, unit: ops.Unit, tls: bool, exporter_config: "relations.cos.ExporterConfig"
421425
) -> None:
422426
enabled = self._container.mysql_router_service_enabled
423427
exporter_enabled = self._container.mysql_router_exporter_service_enabled
@@ -429,7 +433,7 @@ def upgrade(
429433
super().upgrade(unit=unit, tls=tls, exporter_config=exporter_config)
430434
if enabled:
431435
logger.debug("Re-enabling MySQL Router service after upgrade")
432-
self._enable_router(tls=tls, unit_name=unit.name)
436+
self._enable_router(event=event, tls=tls, unit_name=unit.name)
433437
if exporter_enabled:
434438
self._enable_exporter(tls=tls, exporter_config=exporter_config)
435439

0 commit comments

Comments
 (0)