14
14
DatabaseRequestedEvent ,
15
15
DatabaseRequires ,
16
16
)
17
+ from charms .mongodb .v0 .mongo import MongoConnection
17
18
from charms .mongodb .v1 .mongos import MongosConnection
18
- from ops .charm import CharmBase , EventBase , RelationBrokenEvent , RelationChangedEvent
19
+ from ops .charm import (
20
+ CharmBase ,
21
+ EventBase ,
22
+ RelationBrokenEvent ,
23
+ RelationChangedEvent ,
24
+ RelationCreatedEvent ,
25
+ )
19
26
from ops .framework import Object
20
27
from ops .model import (
21
28
ActiveStatus ,
24
31
StatusBase ,
25
32
WaitingStatus ,
26
33
)
34
+ from pymongo .errors import PyMongoError
27
35
28
36
from config import Config
29
37
43
51
44
52
# Increment this PATCH version before using `charmcraft publish-lib` or reset
45
53
# to 0 if you are raising the major API version
46
- LIBPATCH = 13
54
+ LIBPATCH = 14
47
55
48
56
49
57
class ClusterProvider (Object ):
50
58
"""Manage relations between the config server and mongos router on the config-server side."""
51
59
52
60
def __init__ (
53
- self , charm : CharmBase , relation_name : str = Config .Relations .CLUSTER_RELATIONS_NAME
61
+ self ,
62
+ charm : CharmBase ,
63
+ relation_name : str = Config .Relations .CLUSTER_RELATIONS_NAME ,
64
+ substrate : str = Config .Substrate .VM ,
54
65
) -> None :
55
66
"""Constructor for ShardingProvider object."""
67
+ self .substrate = substrate
56
68
self .relation_name = relation_name
57
69
self .charm = charm
58
70
self .database_provides = DatabaseProvides (self .charm , relation_name = self .relation_name )
@@ -179,7 +191,9 @@ def _on_relation_broken(self, event) -> None:
179
191
logger .info ("Skipping relation broken event, broken event due to scale down" )
180
192
return
181
193
182
- self .charm .client_relations .oversee_users (departed_relation_id , event )
194
+ # mongos-k8s router is in charge of removing its own users.
195
+ if self .substrate == Config .Substrate .VM :
196
+ self .charm .client_relations .oversee_users (departed_relation_id , event )
183
197
184
198
def update_config_server_db (self , event ):
185
199
"""Provides related mongos applications with new config server db."""
@@ -244,7 +258,7 @@ def __init__(
244
258
super ().__init__ (charm , self .relation_name )
245
259
self .framework .observe (
246
260
charm .on [self .relation_name ].relation_created ,
247
- self .database_requires . _on_relation_created_event ,
261
+ self ._on_relation_created_handler ,
248
262
)
249
263
250
264
self .framework .observe (
@@ -261,6 +275,11 @@ def __init__(
261
275
charm .on [self .relation_name ].relation_broken , self ._on_relation_broken
262
276
)
263
277
278
+ def _on_relation_created_handler (self , event : RelationCreatedEvent ) -> None :
279
+ logger .info ("Integrating to config-server" )
280
+ self .charm .status .set_and_share_status (WaitingStatus ("Connecting to config-server" ))
281
+ self .database_requires ._on_relation_created_event (event )
282
+
264
283
def _on_database_created (self , event ) -> None :
265
284
if self .charm .upgrade_in_progress :
266
285
logger .warning (
@@ -303,6 +322,8 @@ def _on_relation_changed(self, event) -> None:
303
322
304
323
# avoid restarting mongos when possible
305
324
if not updated_keyfile and not updated_config and self .is_mongos_running ():
325
+ # mongos-k8s router must update its users on start
326
+ self ._update_k8s_users (event )
306
327
return
307
328
308
329
# mongos is not available until it is using new secrets
@@ -321,6 +342,20 @@ def _on_relation_changed(self, event) -> None:
321
342
if self .charm .unit .is_leader ():
322
343
self .charm .mongos_initialised = True
323
344
345
+ # mongos-k8s router must update its users on start
346
+ self ._update_k8s_users (event )
347
+
348
+ def _update_k8s_users (self , event ) -> None :
349
+ if self .substrate != Config .Substrate .K8S :
350
+ return
351
+
352
+ # K8s can handle its 1:Many users after being initialized
353
+ try :
354
+ self .charm .client_relations .oversee_users (None , None )
355
+ except PyMongoError :
356
+ event .defer ()
357
+ logger .debug ("failed to add users on mongos-k8s router, will defer and try again." )
358
+
324
359
def _on_relation_broken (self , event : RelationBrokenEvent ) -> None :
325
360
# Only relation_deparated events can check if scaling down
326
361
if not self .charm .has_departed_run (event .relation .id ):
@@ -334,6 +369,13 @@ def _on_relation_broken(self, event: RelationBrokenEvent) -> None:
334
369
logger .info ("Skipping relation broken event, broken event due to scale down" )
335
370
return
336
371
372
+ try :
373
+ self .handle_mongos_k8s_users_removal ()
374
+ except PyMongoError :
375
+ logger .debug ("Trouble removing router users, will defer and try again" )
376
+ event .defer ()
377
+ return
378
+
337
379
self .charm .stop_mongos_service ()
338
380
logger .info ("Stopped mongos daemon" )
339
381
@@ -348,9 +390,24 @@ def _on_relation_broken(self, event: RelationBrokenEvent) -> None:
348
390
if self .substrate == Config .Substrate .VM :
349
391
self .charm .remove_connection_info ()
350
392
else :
351
- self .db_initialised = False
393
+ self .charm . db_initialised = False
352
394
353
395
# BEGIN: helper functions
396
+ def handle_mongos_k8s_users_removal (self ) -> None :
397
+ """Handles the removal of all client mongos-k8s users and the mongos-k8s admin user.
398
+
399
+ Raises:
400
+ PyMongoError
401
+ """
402
+ if not self .charm .unit .is_leader () or self .substrate != Config .Substrate .K8S :
403
+ return
404
+
405
+ self .charm .client_relations .remove_all_relational_users ()
406
+
407
+ # now that the client mongos users have been removed we can remove ourself
408
+ with MongoConnection (self .charm .mongo_config ) as mongo :
409
+ mongo .drop_user (self .charm .mongo_config .username )
410
+
354
411
def pass_hook_checks (self , event ):
355
412
"""Runs the pre-hooks checks for ClusterRequirer, returns True if all pass."""
356
413
if self .is_mongos_tls_missing ():
0 commit comments