Handle JSON data from dashboard plugins

The dashboard-plugin interface sends relation data json encoded but
the charm does not decode the local-settings key. This change decodes
the data. I have not been able to find any classic plugins that
rely on sending raw data but to maintain backwards compatability
just incase the charm will fallback to the old behaviour if the
relation data is not json encoded.

Change-Id: I3f956ae811cb6c46b5e2ab31f1353678a35e623a
Closes-Bug: #1986538
This commit is contained in:
Liam Young 2022-08-15 14:08:01 +00:00
parent af7a57d539
commit 123b8447ed
2 changed files with 37 additions and 1 deletions

View File

@ -341,6 +341,13 @@ class LocalSettingsContext(OSContextGenerator):
relations = []
# Juju 'internal' data like egress-address is not json encoded. So only
# try and decode the keys we know to expect.
json_keys = [
'local-settings',
'priority',
'conflicting-packages',
'install-packages']
for rid in relation_ids("dashboard-plugin"):
try:
unit = related_units(rid)[0]
@ -349,7 +356,20 @@ class LocalSettingsContext(OSContextGenerator):
else:
rdata = relation_get(unit=unit, rid=rid)
if set(('local-settings', 'priority')) <= set(rdata.keys()):
relations.append((unit, rdata))
# Classic dashboard plugins may send non-json data but
# reactive charms send json. Attempt to json decode the
# data but fallback if that fails.
decoded_data = {}
try:
for key in rdata.keys():
if key in json_keys:
decoded_data[key] = json.loads(rdata[key])
else:
decoded_data[key] = rdata[key]
except (json.decoder.JSONDecodeError, TypeError):
relations.append((unit, rdata))
else:
relations.append((unit, decoded_data))
ctxt = {
'settings': [

View File

@ -1324,6 +1324,22 @@ class TestHorizonContexts(CharmTestCase):
'# horizon-plugin/0\n'
'FOO = True']})
def test_LocalSettingsContextJSON(self):
self.relation_ids.return_value = ['plugin:0', 'plugin-too:0']
self.related_units.side_effect = [['horizon-plugin/0'],
['horizon-plugin-too/0']]
# One JSON and one raw relation
self.relation_get.side_effect = [{'priority': "99",
'local-settings': '"FOO = True"'},
{'priority': 60,
'local-settings': 'BAR = False'}]
self.assertEqual(horizon_contexts.LocalSettingsContext()(),
{'settings': ['# horizon-plugin-too/0\n'
'BAR = False',
'# horizon-plugin/0\n'
'FOO = True']})
def test_WebSSOFIDServiceProviderContext(self):
def relation_ids_side_effect(rname):
return {