Skip to content

Commit

Permalink
Pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
MiaAltieri committed Sep 28, 2023
1 parent 3f5d3d2 commit 6213835
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
39 changes: 28 additions & 11 deletions lib/charms/mongodb/v0/shards_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from charms.mongodb.v0.users import MongoDBUser, OperatorUser
from ops.charm import CharmBase
from ops.framework import Object
from ops.model import BlockedStatus, MaintenanceStatus
from ops.model import BlockedStatus, MaintenanceStatus, WaitingStatus
from tenacity import RetryError, Retrying, stop_after_delay, wait_fixed

from config import Config
Expand Down Expand Up @@ -53,7 +53,7 @@ def __init__(
def _on_relation_joined(self, event):
"""Handles providing shards with secrets and adding shards to the config server."""
if self.charm.is_role(Config.Role.REPLICATION):
self.unit.status = BlockedStatus("role replication does not support sharding")
self.charm.unit.status = BlockedStatus("role replication does not support sharding")
logger.error("sharding interface not supported with config role=replication")
return

Expand All @@ -75,7 +75,7 @@ def _on_relation_joined(self, event):
{
OPERATOR_PASSWORD_KEY: self.charm.get_secret(
Config.Relations.APP_SCOPE,
MongoDBUser.get_password_key_name_for_user("operator"),
MongoDBUser.get_password_key_name_for_user(OperatorUser.get_username()),
),
KEYFILE_KEY: self.charm.get_secret(
Config.Relations.APP_SCOPE, Config.Secrets.SECRET_KEYFILE_NAME
Expand Down Expand Up @@ -123,7 +123,7 @@ def __init__(
def _on_relation_changed(self, event):
"""Retrieves secrets from config-server and updates them within the shard."""
if self.charm.is_role(Config.Role.REPLICATION):
self.unit.status = BlockedStatus("role replication does not support sharding")
self.charm.unit.status = BlockedStatus("role replication does not support sharding")
logger.error("sharding interface not supported with config role=replication")
return

Expand All @@ -139,31 +139,45 @@ def _on_relation_changed(self, event):
# shards rely on the config server for secrets
relation_data = event.relation.data[event.app]
self.update_keyfile(key_file_contents=relation_data.get(KEYFILE_KEY))

# restart on high loaded databases can be very slow (e.g. up to 10-20 minutes).
with MongoDBConnection(self.charm.mongodb_config) as mongo:
if not mongo.is_ready:
logger.info("shard has not started yet, deferfing")
self.charm.unit.status = WaitingStatus("Waiting for MongoDB to start")
event.defer()
return

self.charm.unit.status = MaintenanceStatus("Adding shard to config-server")

if not self.charm.unit.is_leader():
return

try:
self.update_operator_password(new_password=relation_data.get(OPERATOR_PASSWORD_KEY))
except RetryError:
self.charm.unit.status = BlockedStatus("Shard not added to config-server")
return

self.charm.unit.status = MaintenanceStatus("Adding shard to config-server")

# TODO future PR, leader unit verifies shard was added to cluster
if not self.charm.unit.is_leader():
return

def update_operator_password(self, new_password: str) -> None:
"""Updates the password for the operator user.
Raises:
RetryError
"""
if not new_password or not self.charm.unit.is_leader():
return

current_password = (
self.charm.get_secret(
Config.Relations.APP_SCOPE, MongoDBUser.get_password_key_name_for_user("operator")
Config.Relations.APP_SCOPE,
MongoDBUser.get_password_key_name_for_user(OperatorUser.get_username()),
),
)

if not new_password or new_password == current_password or not self.charm.unit.is_leader():
if new_password == current_password:
return

# updating operator password, usually comes after keyfile was updated, hence, the mongodb
Expand Down Expand Up @@ -192,7 +206,10 @@ def update_operator_password(self, new_password: str) -> None:

def update_keyfile(self, key_file_contents: str) -> None:
"""Updates keyfile on all units."""
if not key_file_contents:
# keyfile is set by leader in application data, application data does not necessarily
# match what is on the machine.
current_key_file = self.charm.get_keyfile_contents()
if not key_file_contents or key_file_contents == current_key_file:
return

# put keyfile on the machine with appropriate permissions
Expand Down
18 changes: 18 additions & 0 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,24 @@ def _instatiate_keyfile(self, event: StartEvent) -> None:
file_contents=self.get_secret(APP_SCOPE, Config.Secrets.SECRET_KEYFILE_NAME),
)

def get_keyfile_contents(self) -> str:
"""Retrieves the contents of the keyfile on host machine."""
# wait for keyFile to be created by leader unit
if not self.get_secret(APP_SCOPE, Config.Secrets.SECRET_KEYFILE_NAME):
logger.debug("waiting for leader unit to generate keyfile contents")
return

key_file_path = f"{Config.MONGOD_CONF_DIR}/{KEY_FILE}"
key_file = Path(key_file_path)
if not key_file.is_file():
logger.info("no keyfile present")
return

with open(key_file_path, "r") as file:
key = file.read()

return key

def push_file_to_unit(self, parent_dir, file_name, file_contents) -> None:
"""K8s charms can push files to their containers easily, this is a vm charm workaround."""
Path(parent_dir).mkdir(parents=True, exist_ok=True)
Expand Down

0 comments on commit 6213835

Please sign in to comment.