Skip to content

Commit

Permalink
[DPE-5215] Upgrade libraries to fix secret disclosure issue (#328)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gu1nness authored Sep 11, 2024
1 parent 7911c38 commit 675e66e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
38 changes: 29 additions & 9 deletions lib/charms/mongodb/v0/config_server_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

from charms.data_platform_libs.v0.data_interfaces import (
DatabaseProvides,
DatabaseRequestedEvent,
DatabaseRequires,
)
from charms.mongodb.v1.mongos import MongosConnection
from ops.charm import CharmBase, EventBase, RelationBrokenEvent
from ops.charm import CharmBase, EventBase, RelationBrokenEvent, RelationChangedEvent
from ops.framework import Object
from ops.model import (
ActiveStatus,
Expand Down Expand Up @@ -42,7 +43,7 @@

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 9
LIBPATCH = 12


class ClusterProvider(Object):
Expand All @@ -57,6 +58,9 @@ def __init__(
self.database_provides = DatabaseProvides(self.charm, relation_name=self.relation_name)

super().__init__(charm, self.relation_name)
self.framework.observe(
self.database_provides.on.database_requested, self._on_database_requested
)
self.framework.observe(
charm.on[self.relation_name].relation_changed, self._on_relation_changed
)
Expand Down Expand Up @@ -105,8 +109,14 @@ def is_valid_mongos_integration(self) -> bool:

return True

def _on_relation_changed(self, event) -> None:
"""Handles providing mongos with KeyFile and hosts."""
def _on_database_requested(self, event: DatabaseRequestedEvent | RelationChangedEvent) -> None:
"""Handles the database requested event.
The first time secrets are written to relations should be on this event.
Note: If secrets are written for the first time on other events we risk
the chance of writing secrets in plain sight.
"""
if not self.pass_hook_checks(event):
if not self.is_valid_mongos_integration():
self.charm.status.set_and_share_status(
Expand All @@ -116,12 +126,9 @@ def _on_relation_changed(self, event) -> None:
)
logger.info("Skipping relation joined event: hook checks did not pass")
return

config_server_db = self.generate_config_server_db()

# create user and set secrets for mongos relation
self.charm.client_relations.oversee_users(None, None)

relation_data = {
KEYFILE_KEY: self.charm.get_secret(
Config.Relations.APP_SCOPE, Config.Secrets.SECRET_KEYFILE_NAME
Expand All @@ -135,9 +142,20 @@ def _on_relation_changed(self, event) -> None:
)
if int_tls_ca:
relation_data[INT_TLS_CA_KEY] = int_tls_ca

self.database_provides.update_relation_data(event.relation.id, relation_data)

def _on_relation_changed(self, event: RelationChangedEvent) -> None:
"""Handles providing mongos with KeyFile and hosts."""
# First we need to ensure that the database requested event has run
# otherwise we risk the chance of writing secrets in plain sight.
if not self.database_provides.fetch_relation_field(event.relation.id, "database"):
logger.info("Database Requested has not run yet, skipping.")
event.defer()
return

# TODO : This workflow is a fix until we have time for a better and complete fix (DPE-5513)
self._on_database_requested(event)

def _on_relation_broken(self, event) -> None:
if self.charm.upgrade_in_progress:
logger.warning(
Expand Down Expand Up @@ -328,6 +346,8 @@ def _on_relation_broken(self, event: RelationBrokenEvent) -> None:
# K8s charm have a 1:Many client scheme and share connection info in a different manner.
if self.substrate == Config.Substrate.VM:
self.charm.remove_connection_info()
else:
self.db_initialised = False

# BEGIN: helper functions
def pass_hook_checks(self, event):
Expand Down Expand Up @@ -371,7 +391,7 @@ def is_mongos_running(self) -> bool:
connection_uri = f"mongodb://{self.charm.get_mongos_host()}"

# use the mongos port for k8s charms and external connections on VM
if self.charm.is_external_client or self.substrate == Config.K8S_SUBSTRATE:
if self.substrate == Config.Substrate.K8S or self.charm.is_external_client:
connection_uri = connection_uri + f":{Config.MONGOS_PORT}"

with MongosConnection(None, connection_uri) as mongo:
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/sharding_tests/test_mongos.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ async def test_connect_to_cluster_creates_user(ops_test: OpsTest) -> None:
lambda: is_relation_joined(
ops_test,
CLUSTER_REL_NAME,
CONFIG_SERVER_REL_NAME,
CLUSTER_REL_NAME,
)
is True,
timeout=600,
Expand Down

0 comments on commit 675e66e

Please sign in to comment.