diff --git a/lib/charms/grafana_k8s/v0/grafana_source.py b/lib/charms/grafana_k8s/v0/grafana_source.py index e545dfb8..6e09c508 100644 --- a/lib/charms/grafana_k8s/v0/grafana_source.py +++ b/lib/charms/grafana_k8s/v0/grafana_source.py @@ -162,7 +162,7 @@ def __init__(self, *args): # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 23 +LIBPATCH = 24 logger = logging.getLogger(__name__) @@ -432,13 +432,22 @@ def update_source(self, source_url: Optional[str] = ""): def get_source_uids(self) -> Dict[str, Dict[str, str]]: """Get the datasource UID(s) assigned by the remote end(s) to this datasource. - Returns a mapping from remote application names to unit names to datasource uids. + Returns a mapping from remote application UIDs to unit names to datasource uids. """ uids = {} for rel in self._charm.model.relations.get(self._relation_name, []): if not rel: continue - uids[rel.app.name] = json.loads(rel.data[rel.app].get("datasource_uids", "{}")) + app_databag = rel.data[rel.app] + grafana_uid = app_databag.get("grafana_uid") + if not grafana_uid: + logger.warning( + "remote end is using an old grafana_datasource interface: " + "`grafana_uid` field not found." + ) + continue + + uids[grafana_uid] = json.loads(app_databag.get("datasource_uids", "{}")) return uids def _set_sources_from_event(self, event: RelationJoinedEvent) -> None: @@ -568,6 +577,14 @@ def _publish_source_uids(self, rel: Relation, uids: Dict[str, str]): Assumes only leader unit will call this method """ + unique_grafana_name = "juju_{}_{}_{}_{}".format( + self._charm.model.name, + self._charm.model.uuid, + self._charm.model.app.name, + self._charm.model.unit.name.split("/")[1], # type: ignore + ) + + rel.data[self._charm.app]["grafana_uid"] = unique_grafana_name rel.data[self._charm.app]["datasource_uids"] = json.dumps(uids) def _get_source_config(self, rel: Relation): diff --git a/tests/scenario/test_datasources.py b/tests/scenario/test_datasources.py index 2f8df2eb..d3f7a1e0 100644 --- a/tests/scenario/test_datasources.py +++ b/tests/scenario/test_datasources.py @@ -42,6 +42,7 @@ def test_datasource_sharing(ctx): "remote_host/0": "juju_foo_bar_baz_0", "remote_host/1": "juju_foo_bar_baz_1", } + assert local_app_data["grafana_uid"] def test_datasource_get(): @@ -59,7 +60,10 @@ def test_datasource_get(): {"model": "foo", "model_uuid": "bar", "application": "baz", "type": "tempo"} ) }, - remote_app_data={"datasource_uids": json.dumps(local_ds_uids)}, + remote_app_data={ + "grafana_uid": "foo-grafana-1", + "datasource_uids": json.dumps(local_ds_uids), + }, ) state = State(leader=True, relations={datasource}) @@ -85,6 +89,7 @@ def __init__(self, framework: Framework): def test_datasource_get_nodata(): # GIVEN a datasource relation with two remote units, but which hasn't shared any datasource uids + # for example because the remote end is using an older charm lib datasource = Relation( "grafana-source", remote_app_name="remote_host", @@ -115,5 +120,5 @@ def __init__(self, framework: Framework): ctx = Context(MyProviderCharm, MyProviderCharm.META) with ctx(ctx.on.relation_changed(datasource), state) as mgr: charm = mgr.charm - # THEN we can see our datasource uids via the provider - assert list(charm.source_provider.get_source_uids().values())[0] == {} + # THEN we can see no datasource uids via the provider + assert not charm.source_provider.get_source_uids()