From 6b04701a51fd8110f4779a729e303c6823c2eca4 Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Tue, 28 May 2019 10:18:47 -0700 Subject: [PATCH] Always set apiVersion and kind for resources within a resource list (#298) * Always set apiVersion and kind for resources within a resource list When the Kubernetes REST API returns a list of objects, it returns a resource list object with an apiVersion and kind set to "KindList" where "Kind" is the Kind of object queried, rather than an simple array of objects. The `items` property contains the array of resources returned. Each resource in this list does not contain the GVK information, only the resource list has an apiVersion or kind property set. This ensures when a resource list is returned, each resource within the list has it's apiVersion and kind set, to make it similar to other Kubernetes clients, and easier to work with the returned resources. * Just do one big serialization at the end of a ResourceList operation (cherry picked from commit 68cc0e3a73c16928ea9e4b7fc2fff828beab47e3) --- openshift/dynamic/client.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openshift/dynamic/client.py b/openshift/dynamic/client.py index 9657a399..6abd163b 100755 --- a/openshift/dynamic/client.py +++ b/openshift/dynamic/client.py @@ -510,7 +510,7 @@ def get(self, body=None, **kwargs): response = copy.deepcopy(body) namespace = kwargs.pop('namespace', None) response['items'] = [ - self.resource.get(name=item['metadata']['name'], namespace=item['metadata'].get('namespace', namespace), **kwargs) + self.resource.get(name=item['metadata']['name'], namespace=item['metadata'].get('namespace', namespace), **kwargs).to_dict() for item in body['items'] ] return ResourceInstance(self, response) @@ -519,7 +519,7 @@ def delete(self, body=None, *args, **kwargs): response = copy.deepcopy(body) namespace = kwargs.pop('namespace', None) response['items'] = [ - self.resource.delete(name=item['metadata']['name'], namespace=item['metadata'].get('namespace', namespace), **kwargs) + self.resource.delete(name=item['metadata']['name'], namespace=item['metadata'].get('namespace', namespace), **kwargs).to_dict() for item in body['items'] ] return ResourceInstance(self, response) @@ -527,7 +527,7 @@ def delete(self, body=None, *args, **kwargs): def verb_mapper(self, verb, body=None, **kwargs): response = copy.deepcopy(body) response['items'] = [ - getattr(self.resource, verb)(body=item, **kwargs) + getattr(self.resource, verb)(body=item, **kwargs).to_dict() for item in body['items'] ] return ResourceInstance(self, response) @@ -738,6 +738,17 @@ class ResourceInstance(object): def __init__(self, resource, instance): self.resource_type = resource + # If we have a list of resources, then set the apiVersion and kind of + # each resource in 'items' + kind = instance['kind'] + if kind.endswith('List') and 'items' in instance: + kind = instance['kind'][:-4] + for item in instance['items']: + if 'apiVersion' not in item: + item['apiVersion'] = instance['apiVersion'] + if 'kind' not in item: + item['kind'] = kind + self.attributes = self.__deserialize(instance) def __deserialize(self, field):