Fix k8s client for handling empty list in response.
Implements: blueprint selflink Change-Id: I0db851889017cfe19cc84acab36bdc67b04a9145
This commit is contained in:
parent
e69989c6e4
commit
9bc33d9b78
kuryr_kubernetes
@ -133,12 +133,20 @@ class K8sClient(object):
|
|||||||
# for custom resources there are both kind and apiVersion..
|
# for custom resources there are both kind and apiVersion..
|
||||||
if kind.endswith('List'):
|
if kind.endswith('List'):
|
||||||
kind = kind[:-4]
|
kind = kind[:-4]
|
||||||
|
|
||||||
|
# NOTE(gryf): In case we get null/None for items from the API,
|
||||||
|
# we need to convert it to the empty list, otherwise it might
|
||||||
|
# be propagated to the consumers of this method and sent back
|
||||||
|
# to the Kubernetes as is, and fail as a result.
|
||||||
|
if result['items'] is None:
|
||||||
|
result['items'] = []
|
||||||
|
|
||||||
for item in result['items']:
|
for item in result['items']:
|
||||||
if not item.get('kind'):
|
if not item.get('kind'):
|
||||||
item['kind'] = kind
|
item['kind'] = kind
|
||||||
if not item.get('apiVersion'):
|
if not item.get('apiVersion'):
|
||||||
item['apiVersion'] = api_version
|
item['apiVersion'] = api_version
|
||||||
else:
|
|
||||||
if not result.get('apiVersion'):
|
if not result.get('apiVersion'):
|
||||||
result['apiVersion'] = api_version
|
result['apiVersion'] = api_version
|
||||||
else:
|
else:
|
||||||
|
@ -155,6 +155,27 @@ class TestK8sClient(test_base.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(exc.K8sClientException, self.client.get, path)
|
self.assertRaises(exc.K8sClientException, self.client.get, path)
|
||||||
|
|
||||||
|
@mock.patch('requests.sessions.Session.get')
|
||||||
|
def test_get_null_on_items_list(self, m_get):
|
||||||
|
path = '/test'
|
||||||
|
|
||||||
|
req = {'kind': 'PodList',
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'metadata': {},
|
||||||
|
'items': None}
|
||||||
|
|
||||||
|
ret = {'kind': 'PodList',
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'metadata': {},
|
||||||
|
'items': []}
|
||||||
|
|
||||||
|
m_resp = mock.MagicMock()
|
||||||
|
m_resp.ok = True
|
||||||
|
m_resp.json.return_value = req
|
||||||
|
m_get.return_value = m_resp
|
||||||
|
|
||||||
|
self.assertEqual(self.client.get(path), ret)
|
||||||
|
|
||||||
@mock.patch('itertools.count')
|
@mock.patch('itertools.count')
|
||||||
@mock.patch('requests.sessions.Session.patch')
|
@mock.patch('requests.sessions.Session.patch')
|
||||||
def test_annotate(self, m_patch, m_count):
|
def test_annotate(self, m_patch, m_count):
|
||||||
|
@ -143,6 +143,12 @@ class Watcher(health.HealthHandler):
|
|||||||
LOG.exception(f'Error getting path when reconciling.')
|
LOG.exception(f'Error getting path when reconciling.')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# NOTE(gryf): For some resources (like pods) we could observe that
|
||||||
|
# 'items' is set to None. I'm not sure if that's a K8s issue, since
|
||||||
|
# accroding to the documentation is should be list.
|
||||||
|
if not resources:
|
||||||
|
return
|
||||||
|
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
event = {
|
event = {
|
||||||
'type': 'MODIFIED',
|
'type': 'MODIFIED',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user