From 3c35f67e50f272a5933b562bcfcbf77f56aa746a Mon Sep 17 00:00:00 2001 From: Mia Altieri <32723809+MiaAltieri@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:29:34 +0100 Subject: [PATCH] [DPE-3832] Fix incorrect statuses for Adding shards (#383) ## Issue #380 - Shards incorrectly report `Adding shard to config-server` when they cannot reach the config-server. This may occur for three reasons: 1. The shard is truly getting added to the config-server and it does not have access to the config-server 2. The shard is getting its cluster password updated 3. The shard is getting updating TLS In cases 2&3, the shard is not getting added to the cluster and so this status is wrong ## Solution Report that the shard is getting added to the cluster only when it is truly getting added for the first time. Reporting this status in `relation-changed` does not make sense since this hook is used to manage changes in the sharding interface. Therefore it makes the most sense to report this when the shard is actually getting added to the cluster (i.e. relation-joined) --- lib/charms/mongodb/v1/shards_interface.py | 30 +++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/charms/mongodb/v1/shards_interface.py b/lib/charms/mongodb/v1/shards_interface.py index 4203b5f08..bfdd38eb0 100644 --- a/lib/charms/mongodb/v1/shards_interface.py +++ b/lib/charms/mongodb/v1/shards_interface.py @@ -56,7 +56,7 @@ # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 11 +LIBPATCH = 12 KEYFILE_KEY = "key-file" HOSTS_KEY = "host" OPERATOR_PASSWORD_KEY = MongoDBUser.get_password_key_name_for_user(OperatorUser.get_username()) @@ -328,10 +328,10 @@ def get_config_server_status(self) -> Optional[StatusBase]: return BlockedStatus("sharding interface cannot be used by replicas") if self.model.relations[LEGACY_REL_NAME]: - return BlockedStatus(f"relation {LEGACY_REL_NAME} to shard not supported.") + return BlockedStatus(f"Sharding roles do not support {LEGACY_REL_NAME} interface.") if self.model.relations[REL_NAME]: - return BlockedStatus(f"relation {REL_NAME} to shard not supported.") + return BlockedStatus(f"Sharding roles do not support {REL_NAME} interface.") if not self.is_mongos_running(): return BlockedStatus("Internal mongos is not running.") @@ -510,6 +510,9 @@ def __init__( super().__init__(charm, self.relation_name) + self.framework.observe( + charm.on[self.relation_name].relation_joined, self._on_relation_joined + ) self.framework.observe( charm.on[self.relation_name].relation_changed, self._on_relation_changed ) @@ -634,20 +637,18 @@ def sync_cluster_passwords( # after updating the password of the backup user, restart pbm with correct password self.charm._connect_pbm_agent() + def _on_relation_joined(self, _): + """Sets status and flags in relation data relevant to sharding.""" + # if re-using an old shard, re-set flags. + self.charm.unit_peer_data["drained"] = json.dumps(False) + self.charm.unit.status = MaintenanceStatus("Adding shard to config-server") + def _on_relation_changed(self, event): """Retrieves secrets from config-server and updates them within the shard.""" if not self.pass_hook_checks(event): logger.info("Skipping relation joined event: hook checks re not passed") return - # if re-using an old shard, re-set drained flag. - self.charm.unit_peer_data["drained"] = json.dumps(False) - - # relation-changed events can be used for other purposes (not only adding the shard), i.e. - # password rotation, secret rotation, mongos hosts rotation - if self._is_mongos_reachable() and not self._is_added_to_cluster(): - self.charm.unit.status = MaintenanceStatus("Adding shard to config-server") - # shards rely on the config server for shared cluster secrets key_file_enabled, tls_enabled = self.get_membership_auth_modes(event) if not key_file_enabled and not tls_enabled: @@ -804,10 +805,10 @@ def get_relations_statuses(self) -> Optional[StatusBase]: return BlockedStatus("sharding interface cannot be used by replicas") if self.model.get_relation(LEGACY_REL_NAME): - return BlockedStatus(f"relation {LEGACY_REL_NAME} to shard not supported.") + return BlockedStatus(f"Sharding roles do not support {LEGACY_REL_NAME} interface.") if self.model.get_relation(REL_NAME): - return BlockedStatus(f"relation {REL_NAME} to shard not supported.") + return BlockedStatus(f"Sharding roles do not support {REL_NAME} interface.") if not self.model.get_relation(self.relation_name) and not self.charm.drained: return BlockedStatus("missing relation to config server") @@ -853,6 +854,9 @@ def get_shard_status(self) -> Optional[StatusBase]: if not self._is_mongos_reachable(): return BlockedStatus("Config server unreachable") + if not self.cluster_password_synced(): + return WaitingStatus("Waiting to sync passwords across the cluster") + if not self._is_added_to_cluster(): return MaintenanceStatus("Adding shard to config-server")