Skip to content

Commit

Permalink
Fix _on_secret_update
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Ratushnyy committed Sep 12, 2023
1 parent e4200f1 commit 688f0e5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
45 changes: 34 additions & 11 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# See LICENSE file for licensing details.
import json
import logging
import re
import subprocess
import time
from typing import Dict, List, Optional, Set
Expand Down Expand Up @@ -585,19 +586,21 @@ def _on_secret_remove(self, event: SecretRemoveEvent):
)

def _on_secret_changed(self, event: SecretChangedEvent):
secret = event.secret

if secret.id == self.app_peer_data.get(Config.Secrets.SECRET_INTERNAL_LABEL, None):
if self._compare_secret_ids(
event.secret.id, self.app_peer_data.get(Config.Secrets.SECRET_INTERNAL_LABEL)
):
scope = APP_SCOPE
elif secret.id == self.unit_peer_data.get(Config.Secrets.SECRET_INTERNAL_LABEL, None):
elif self._compare_secret_ids(
event.secret.id, self.unit_peer_data.get(Config.Secrets.SECRET_INTERNAL_LABEL)
):
scope = UNIT_SCOPE
else:
logging.debug(
f"Secret {event._id}:{event.secret.id} changed, but it's irrelevant for us"
)
logging.debug("Secret %s changed, but it's unknown", event.secret.id)
return
logging.debug("Secret %s for scope %s changed, refreshing", event.secret.id, scope)
self._update_juju_secrets_cache(scope)
self._connect_mongodb_exporter()
self._connect_pbm_agent()

# END: charm event handlers

Expand Down Expand Up @@ -631,7 +634,7 @@ def _init_operator_user(self) -> None:
raise AdminUserCreationError

logger.debug(f"{OperatorUser.get_username()} user created")
self._user_created(OperatorUser)
self._set_user_created(OperatorUser)

@retry(
stop=stop_after_attempt(3),
Expand All @@ -651,7 +654,7 @@ def _init_monitor_user(self):
)
logger.debug("creating the monitor user...")
mongo.create_user(self.monitor_config)
self._user_created(MonitorUser)
self._set_user_created(MonitorUser)

# leader should reconnect to exporter after creating the monitor user - since the snap
# will have an authorisation error until the the user has been created and the daemon
Expand All @@ -677,15 +680,15 @@ def _init_backup_user(self):
)
logger.debug("creating the backup user...")
mongo.create_user(self.backup_config)
self._user_created(BackupUser)
self._set_user_created(BackupUser)

# END: users management

# BEGIN: helper functions
def _is_user_created(self, user: MongoDBUser) -> bool:
return f"{user.get_username()}-user-created" in self.app_peer_data

def _user_created(self, user: MongoDBUser) -> None:
def _set_user_created(self, user: MongoDBUser) -> None:
self.app_peer_data[f"{user.get_username()}-user-created"] = "True"

def _get_mongodb_config_for_user(
Expand Down Expand Up @@ -1120,6 +1123,26 @@ def _peer_data(self, scope: Scopes):
scope_obj = self._scope_obj(scope)
return self._peers.data[scope_obj]

@staticmethod
def _compare_secret_ids(secret_id1: str, secret_id2: str) -> bool:
"""Reliable comparison on secret equality.
NOTE: Secret IDs may be of any of these forms:
- secret://9663a790-7828-4186-8b21-2624c58b6cfe/citb87nubg2s766pab40
- secret:citb87nubg2s766pab40
"""
if not secret_id1 or not secret_id2:
return False

regex = re.compile(".*[^/][/:]")

pure_id1 = regex.sub("", secret_id1)
pure_id2 = regex.sub("", secret_id2)

if pure_id1 and pure_id2:
return pure_id1 == pure_id2
return False

def _juju_secret_set(self, scope: Scopes, key: str, value: str) -> str:
"""Helper function setting Juju secret in Juju versions >3.0."""
peer_data = self._peer_data(scope)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/metrics_tests/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async def test_endpoints_new_password(ops_test: OpsTest):
action = await action.wait()
# wait for non-leader units to receive relation changed event.
time.sleep(3)
await ops_test.model.wait_for_idle()
await ops_test.model.wait_for_idle(apps=[app], status="active", idle_period=15)
for unit in application.units:
await verify_endpoints(ops_test, unit)

Expand Down

0 comments on commit 688f0e5

Please sign in to comment.