From 9d8dbf2e269b43e03877a57f094e33aaecccc061 Mon Sep 17 00:00:00 2001 From: Adam Dyess Date: Fri, 1 Mar 2024 15:29:52 -0600 Subject: [PATCH] calculate expected hash by first unrolling json data, sorting by relation data keys, then sha --- ops/ops/interface_gcp/requires.py | 30 ++++++++++++++++++++++++----- ops/tests/unit/test_ops_requires.py | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ops/ops/interface_gcp/requires.py b/ops/ops/interface_gcp/requires.py index 0a9922b..976e7b2 100644 --- a/ops/ops/interface_gcp/requires.py +++ b/ops/ops/interface_gcp/requires.py @@ -116,9 +116,15 @@ def send_instance_info(self, _): info = { "charm": self.charm.meta.name, "instance": self.instance_id, - "zone": self.zone, "model-uuid": os.environ["JUJU_MODEL_UUID"], + "zone": self.zone, } + log.info( + "%s is instance=%s in zone=%s", + self.charm.unit.name, + self.instance_id, + self.zone, + ) self._request(info) @cached_property @@ -145,7 +151,16 @@ def is_ready(self): completed = json.loads(self._received.get("completed", "{}")).get( self.instance_id ) - return bool(requested and requested == completed) + ready = bool(requested and requested == completed) + if not requested: + log.warning("Local end has yet to request integration") + if not completed: + log.warning("Remote end has yet to calculate a response") + elif not ready: + log.warning( + "Waiting for completed=%s to be requested=%s", completed, requested + ) + return ready @property def credentials(self): @@ -165,9 +180,14 @@ def evaluate_relation(self, event) -> Optional[str]: @property def _expected_hash(self): - return sha256( - json.dumps(dict(self._to_publish), sort_keys=True).encode("utf8") - ).hexdigest() + def from_json(s: str): + try: + return json.loads(s) + except json.decoder.JSONDecodeError: + return s + + to_sha = {key: from_json(val) for key, val in self._to_publish.items()} + return sha256(json.dumps(to_sha, sort_keys=True).encode()).hexdigest() def _request(self, keyvals): kwds = {key: json.dumps(val) for key, val in keyvals.items()} diff --git a/ops/tests/unit/test_ops_requires.py b/ops/tests/unit/test_ops_requires.py index c8dd916..f0fd87b 100644 --- a/ops/tests/unit/test_ops_requires.py +++ b/ops/tests/unit/test_ops_requires.py @@ -89,7 +89,7 @@ def test_is_ready_no_relation(harness, event_type): def test_is_ready_success(harness): - chksum = "e595c1619f2c63d4d237b20af77b1451b2912e878ce3dff666e49de2794df745" + chksum = "72bd9ed0dbf680ea356bca7d78f1cda9e6484227f0d270b0602128ecb622686f" completed = '{"i-abcdefghijklmnopq": "%s"}' % chksum harness.add_relation("gcp", "remote", unit_data={"completed": completed}) assert harness.charm.gcp.is_ready is True