From 10ce8e0fbd0852660ecf093349af28262d857b06 Mon Sep 17 00:00:00 2001 From: arturo-seijas <102022572+arturo-seijas@users.noreply.github.com> Date: Fri, 17 Nov 2023 16:37:30 +0100 Subject: [PATCH] Support aliasing the redis relation (#75) * Support aliases for the redis relation --- lib/charms/redis_k8s/v0/redis.py | 49 ++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/lib/charms/redis_k8s/v0/redis.py b/lib/charms/redis_k8s/v0/redis.py index 1f96fbd..a7e5234 100644 --- a/lib/charms/redis_k8s/v0/redis.py +++ b/lib/charms/redis_k8s/v0/redis.py @@ -33,6 +33,7 @@ """ import logging import socket +from typing import Dict, Optional from ops.charm import CharmEvents from ops.framework import EventBase, EventSource, Object @@ -45,10 +46,11 @@ # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version. -LIBPATCH = 3 +LIBPATCH = 4 logger = logging.getLogger(__name__) +DEFAULT_REALTION_NAME = "redis" class RedisRelationUpdatedEvent(EventBase): """An event for the redis relation having been updated.""" @@ -60,14 +62,16 @@ class RedisRelationCharmEvents(CharmEvents): class RedisRequires(Object): - def __init__(self, charm, _stored): + + def __init__(self, charm, _stored, relation_name: str = DEFAULT_REALTION_NAME): """A class implementing the redis requires relation.""" - super().__init__(charm, "redis") - self.framework.observe(charm.on.redis_relation_joined, self._on_relation_changed) - self.framework.observe(charm.on.redis_relation_changed, self._on_relation_changed) - self.framework.observe(charm.on.redis_relation_broken, self._on_relation_broken) + super().__init__(charm, relation_name) + self.framework.observe(charm.on[relation_name].relation_joined, self._on_relation_changed) + self.framework.observe(charm.on[relation_name].relation_changed, self._on_relation_changed) + self.framework.observe(charm.on[relation_name].relation_broken, self._on_relation_broken) self._stored = _stored self.charm = charm + self.relation_name = relation_name def _on_relation_changed(self, event): """Handle the relation changed event.""" @@ -89,19 +93,46 @@ def _on_relation_broken(self, event): # Trigger an event that our charm can react to. self.charm.on.redis_relation_updated.emit() + @property + def relation_data(self) -> Optional[Dict[str, str]]: + """Retrieve the relation data. + + Returns: + Dict: dict containing the relation data. + """ + relation = self.model.get_relation(self.relation_name) + if not relation or not relation.units: + return None + unit = next(iter(relation.units)) + return relation.data[unit] + + @property + def url(self) -> Optional[str]: + """Retrieve the Redis URL. + + Returns: + str: the Redis URL. + """ + relation_data = self.relation_data + if not relation_data: + return None + redis_host = relation_data.get("hostname") + redis_port = relation_data.get("port") + return f"redis://{redis_host}:{redis_port}" + class RedisProvides(Object): def __init__(self, charm, port): """A class implementing the redis provides relation.""" - super().__init__(charm, "redis") + super().__init__(charm, DEFAULT_REALTION_NAME) self.framework.observe(charm.on.redis_relation_changed, self._on_relation_changed) self._port = port self._charm = charm def _on_relation_changed(self, event): """Handle the relation changed event.""" - event.relation.data[self.model.unit]['hostname'] = self._get_master_ip() - event.relation.data[self.model.unit]['port'] = str(self._port) + event.relation.data[self.model.unit]["hostname"] = self._get_master_ip() + event.relation.data[self.model.unit]["port"] = str(self._port) # The reactive Redis charm also exposes 'password'. When tackling # https://github.com/canonical/redis-k8s/issues/7 add 'password' # field so that it matches the exposed interface information from it.