Skip to content

Commit

Permalink
Add support for *List kinds (#213)
Browse files Browse the repository at this point in the history
* Add support for *List kinds
* Update  tests to support *List kinds
  • Loading branch information
fabianvf authored Oct 4, 2018
1 parent 44fdf7a commit 89b5e8e
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 214 deletions.
76 changes: 66 additions & 10 deletions openshift/dynamic/client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python

import sys
import copy
import json
from functools import partial

Expand All @@ -24,6 +25,7 @@
'DynamicClient',
'ResourceInstance',
'Resource',
'ResourceList',
'Subresource',
'ResourceContainer',
'ResourceField',
Expand Down Expand Up @@ -141,6 +143,7 @@ def get_resources_for_api_version(self, prefix, group, version, preferred):
subresources=subresources.get(resource['name']),
**resource
)
resources['{}List'.format(resource['kind'])] = ResourceList(resources[resource['kind']])
return resources

def ensure_namespace(self, resource, namespace, body):
Expand Down Expand Up @@ -329,7 +332,7 @@ def group_version(self):
return self.api_version

def __repr__(self):
return '<{}({}/{}>)'.format(self.__class__.__name__, self.group_version, self.name)
return '<{}({}/{})>'.format(self.__class__.__name__, self.group_version, self.name)

@property
def urls(self):
Expand Down Expand Up @@ -360,6 +363,54 @@ def __getattr__(self, name):
return partial(getattr(self.client, name), self)


class ResourceList(Resource):
""" Represents a list of API objects """

def __init__(self, resource):
self.resource = resource
self.kind = '{}List'.format(resource.kind)

def get(self, body=None, **kwargs):
if body is None:
return self.resource.get(**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)
for item in body['items']
]
return ResourceInstance(self, response)

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)
for item in body['items']
]
return ResourceInstance(self, response)

def verb_mapper(self, verb, body=None, **kwargs):
response = copy.deepcopy(body)
response['items'] = [
getattr(self.resource, verb)(body=item, **kwargs)
for item in body['items']
]
return ResourceInstance(self, response)

def create(self, *args, **kwargs):
return self.verb_mapper('create', *args, **kwargs)

def replace(self, *args, **kwargs):
return self.verb_mapper('replace', *args, **kwargs)

def patch(self, *args, **kwargs):
return self.verb_mapper('patch', *args, **kwargs)

def __getattr__(self, name):
return getattr(self.resource, name)


class Subresource(Resource):
""" Represents a subresource of an API resource. This generally includes operations
like scale, as well as status objects for an instantiated resource
Expand Down Expand Up @@ -544,6 +595,8 @@ def __serialize(self, field):
}
elif isinstance(field, (list, tuple)):
return [self.__serialize(item) for item in field]
elif isinstance(field, ResourceInstance):
return field.to_dict()
else:
return field

Expand Down Expand Up @@ -572,18 +625,21 @@ def __dir__(self):
def main():
config.load_kube_config()
client = DynamicClient(ApiClient())
ret = {}
ret = []
for resource in client.resources:
if resource.namespaced:
key = resource.urls['namespaced_full']
key = '{}.{}'.format(resource.group_version, resource.kind)
item = {}
item[key] = {k: v for k, v in resource.__dict__.items() if k not in ('client', 'subresources', 'resource')}
if isinstance(resource, ResourceList):
item[key]["resource"] = '{}.{}'.format(resource.resource.group_version, resource.resource.kind)
else:
key = resource.urls['full']
ret[key] = {k: v for k, v in resource.__dict__.items() if k not in ('client', 'subresources')}
ret[key]['subresources'] = {}
for name, value in resource.subresources.items():
ret[key]['subresources'][name] = {k: v for k, v in value.__dict__.items() if k != 'parent'}
item[key]['subresources'] = {}
for name, value in resource.subresources.items():
item[key]['subresources'][name] = {k: v for k, v in value.__dict__.items() if k != 'parent'}
item[key]['urls'] = resource.urls
ret.append(item)

print(yaml.safe_dump(ret))
print(yaml.safe_dump(sorted(ret, key=lambda x: x.keys()[0].replace('List', '1')), default_flow_style=False))
return 0


Expand Down
Loading

0 comments on commit 89b5e8e

Please sign in to comment.