diff --git a/lib/charms/opensearch/v0/opensearch_backups.py b/lib/charms/opensearch/v0/opensearch_backups.py index 521b65fcb..ee7510f56 100644 --- a/lib/charms/opensearch/v0/opensearch_backups.py +++ b/lib/charms/opensearch/v0/opensearch_backups.py @@ -1074,24 +1074,38 @@ def get_service_status( # noqa: C901 class OpenSearchBackupFactory(OpenSearchPluginRelationsHandler): """Creates the correct backup class and populates the appropriate relation details.""" - _singleton = None _backup_obj = None - def __new__(cls, *args): - """Sets singleton class to be reused during this hook.""" - if cls._singleton is None: - cls._singleton = super(OpenSearchBackupFactory, cls).__new__(cls) - return cls._singleton - def __init__(self, charm: CharmBase): super().__init__() self._charm = charm + @property + def _get_peer_rel_data(self) -> Dict[str, Any]: + if ( + not (relation := self._charm.model.get_relation(PeerClusterRelationName)) + or not (data := relation.data.get(relation.app)) + or not data.get("data") + ): + return {} + data = PeerClusterRelData.from_str(data["data"]) + return data.credentials.s3 + @override def is_relation_set(self) -> bool: """Checks if the relation is set for the plugin handler.""" relation = self._charm.model.get_relation(self._relation_name) - return relation is not None and relation.units + if isinstance(self.backup(), OpenSearchBackup): + return relation is not None and relation.units + + # We are not not the MAIN_ORCHESTRATOR + # The peer-cluster relation will always exist, so we must check if + # the relation has the information we need or not. + return ( + self._get_peer_rel_data + and self._get_peer_rel_data.access_key + and self._get_peer_rel_data.secret_key + ) @property def _relation_name(self) -> str: @@ -1106,7 +1120,9 @@ def get_relation_data(self) -> Dict[str, Any]: relation = self._charm.model.get_relation(self._relation_name) if not self.is_relation_set(): return {} - return relation.data.get(relation.app) + elif isinstance(self.backup(), OpenSearchBackup): + return relation.data.get(relation.app) + return self._get_peer_rel_data def backup(self) -> OpenSearchBackupBase: """Implements the logic that returns the correct class according to the cluster type.""" diff --git a/lib/charms/opensearch/v0/opensearch_base_charm.py b/lib/charms/opensearch/v0/opensearch_base_charm.py index bb466e192..9aac3fc6a 100644 --- a/lib/charms/opensearch/v0/opensearch_base_charm.py +++ b/lib/charms/opensearch/v0/opensearch_base_charm.py @@ -644,6 +644,7 @@ def _on_config_changed(self, event: ConfigChangedEvent): # noqa C901 self._restart_opensearch_event.emit() except (OpenSearchPluginError, OpenSearchKeystoreNotReadyYetError) as e: + logger.warning(f"{PluginConfigChangeError}: {str(e)}") if self.unit.is_leader() and isinstance(e, OpenSearchPluginError): self.status.set(BlockedStatus(PluginConfigChangeError), app=True) event.defer() diff --git a/lib/charms/opensearch/v0/opensearch_plugins.py b/lib/charms/opensearch/v0/opensearch_plugins.py index c4994e217..1111eb0ab 100644 --- a/lib/charms/opensearch/v0/opensearch_plugins.py +++ b/lib/charms/opensearch/v0/opensearch_plugins.py @@ -340,12 +340,30 @@ class OpenSearchPluginRelationsHandler(ABC): relations should plugin manager listen to. """ + _singleton = None + + def __new__(cls, *args): + """Sets singleton class in this hook, as relation objects can only be created once.""" + if cls._singleton is None: + cls._singleton = super(OpenSearchPluginRelationsHandler, cls).__new__(cls) + return cls._singleton + def is_relation_set(self) -> bool: - """Returns True if the relation is set, False otherwise.""" - return False + """Returns True if the relation is set, False otherwise. + + It can mean the relation exists or not, simply put; or it can also mean a subset of data + exists within a bigger relation. One good example, peer-cluster is a single relation that + contains a lot of different data. In this case, we'd be interested in a subset of + its entire databag. + """ + return NotImplementedError() def get_relation_data(self) -> Dict[str, Any]: - """Returns the relation that the plugin manager should listen to.""" + """Returns the relation that the plugin manager should listen to. + + Simplest case, just returns the relation data. In more complex cases, it may return + a subset of the relation data, e.g. a single key-value pair. + """ raise NotImplementedError()