Skip to content

Commit 83185db

Browse files
authored
Fix parsing of bookmark objects (#364)
* Fix bookmarks of real resources * Undo automated formatting * Check for metadata and resourceVersion before trying to extract * Added test for malformed bookmark * Fixed flake8 complaint
1 parent bfdc475 commit 83185db

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

kubernetes_asyncio/watch/watch.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,15 @@ def unmarshal_event(self, data: str, response_type):
102102
reason = "{}: {}".format(obj['reason'], obj['message'])
103103
raise client.exceptions.ApiException(status=obj['code'], reason=reason)
104104

105-
# If possible, compile the JSON response into a Python native response
106-
# type, eg `V1Namespace` or `V1Pod`,`ExtensionsV1beta1Deployment`, ...
107-
if response_type:
108-
js['object'] = self._api_client.deserialize(
109-
response=SimpleNamespace(data=json.dumps(js['raw_object'])),
110-
response_type=response_type
111-
)
112-
113105
if js['type'].lower() != 'bookmark':
106+
# If possible, compile the JSON response into a Python native response
107+
# type, eg `V1Namespace` or `V1Pod`,`ExtensionsV1beta1Deployment`, ...
108+
if response_type:
109+
js['object'] = self._api_client.deserialize(
110+
response=SimpleNamespace(data=json.dumps(js['raw_object'])),
111+
response_type=response_type
112+
)
113+
114114
# decode and save resource_version to continue watching
115115
if hasattr(js['object'], 'metadata'):
116116
self.resource_version = js['object'].metadata.resource_version
@@ -123,7 +123,14 @@ def unmarshal_event(self, data: str, response_type):
123123
self.resource_version = js['object']['metadata']['resourceVersion']
124124

125125
elif js['type'].lower() == 'bookmark':
126-
self.resource_version = js['object']['metadata']['resourceVersion']
126+
if (isinstance(js['raw_object'], dict)
127+
and 'metadata' in js['raw_object']
128+
and 'resourceVersion' in js['raw_object']['metadata']):
129+
self.resource_version = js['raw_object']['metadata']['resourceVersion']
130+
else:
131+
raise Exception(("Malformed JSON response for bookmark event, "
132+
"'metadata' or 'resourceVersion' field is missing. "
133+
"JSON: {}").format(js))
127134

128135
return js
129136

kubernetes_asyncio/watch/watch_test.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,37 @@ async def test_unmarshal_bookmark_succeeds_and_preserves_resource_version(self):
389389

390390
# make sure the resource version is preserved,
391391
# and the watcher's resource_version is updated
392-
self.assertTrue(isinstance(event['object'], dict))
393-
self.assertEqual("1", event['object']['metadata']['resourceVersion'])
392+
self.assertTrue(isinstance(event['raw_object'], dict))
393+
self.assertEqual("1", event['raw_object']['metadata']['resourceVersion'])
394+
self.assertEqual("1", w.resource_version)
395+
396+
async def test_unmarshal_job_bookmark_succeeds_and_preserves_resource_version(self):
397+
w = Watch()
398+
event = w.unmarshal_event('{"type": "BOOKMARK", "object": {"apiVersion":'
399+
'"batch/v1","kind":"Job","metadata":'
400+
'{"name": "bar", "resourceVersion": "1"},'
401+
'"spec": {"template": {"metadata": '
402+
'{"creationTimestamp":null}, "spec": '
403+
'{"containers":null}}}}}',
404+
'object')
405+
self.assertEqual("BOOKMARK", event['type'])
406+
407+
# make sure the resource version is preserved,
408+
# and the watcher's resource_version is updated
409+
self.assertTrue(isinstance(event['raw_object'], dict))
410+
self.assertEqual("1", event['raw_object']['metadata']['resourceVersion'])
394411
self.assertEqual("1", w.resource_version)
412+
413+
async def test_unmarshall_job_bookmark_malformed_object_fails(self):
414+
# An actual error response sent by K8s during testing.
415+
k8s_err = {
416+
'type': 'BOOKMARK',
417+
'object': {
418+
'kind': 'Job',
419+
'apiVersion': 'batch/v1',
420+
'metadata': {},
421+
}
422+
}
423+
424+
with self.assertRaises(Exception):
425+
Watch().unmarshal_event(json.dumps(k8s_err), None)

0 commit comments

Comments
 (0)