summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDolph Mathews <dolph.mathews@gmail.com>2012-09-11 11:12:37 -0500
committerDolph Mathews <dolph.mathews@gmail.com>2012-10-04 09:25:56 +0000
commit315285e76ad520e89b5616503bdce8e061c77141 (patch)
treedeb3fcdc1eff761e007d441d3dc89bc7f94fd6a2
parente25959724508b3ea74ed3f456e4eaae4f72609dd (diff)
downloadpython-keystoneclient-315285e76ad520e89b5616503bdce8e061c77141.tar.gz
Manager for generic CRUD on v3
Change-Id: I15944f2e171e26b5209b55356edd1110b301310c
-rw-r--r--keystoneclient/base.py111
1 files changed, 111 insertions, 0 deletions
diff --git a/keystoneclient/base.py b/keystoneclient/base.py
index 8be4227..eadc127 100644
--- a/keystoneclient/base.py
+++ b/keystoneclient/base.py
@@ -18,6 +18,8 @@
Base utilities to build API operation managers and objects on top of.
"""
+import urllib
+
from keystoneclient import exceptions
@@ -144,6 +146,115 @@ class ManagerWithFind(Manager):
return found
+class CrudManager(Manager):
+ """Base manager class for manipulating Keystone entities.
+
+ Children of this class are expected to define a `collection_key` and `key`.
+
+ - `collection_key`: Usually a plural noun by convention (e.g. `entities`);
+ used to refer collections in both URL's (e.g. `/v3/entities`) and JSON
+ objects containing a list of member resources (e.g. `{'entities': [{},
+ {}, {}]}`).
+ - `key`: Usually a singular noun by convention (e.g. `entity`); used to
+ refer to an individual member of the collection.
+
+ """
+ collection_key = None
+ key = None
+
+ def build_url(self, base_url=None, **kwargs):
+ """Builds a resource URL for the given kwargs.
+
+ Given an example collection where `collection_key = 'entities'` and
+ `key = 'entity'`, the following URL's could be generated.
+
+ By default, the URL will represent a collection of entities, e.g.::
+
+ /entities
+
+ If kwargs contains an `entity_id`, then the URL will represent a
+ specific member, e.g.::
+
+ /entities/{entity_id}
+
+ If a `base_url` is provided, the generated URL will be appended to it.
+
+ """
+ url = base_url if base_url is not None else ''
+
+ url += '/%s' % self.collection_key
+
+ # do we have a specific entity?
+ entity_id = kwargs.get('%s_id' % self.key)
+ if entity_id is not None:
+ url += '/%s' % entity_id
+
+ return url
+
+ def _filter_kwargs(self, kwargs):
+ # drop null values
+ for key, ref in kwargs.copy().iteritems():
+ if ref is None:
+ kwargs.pop(key)
+ else:
+ id_value = getid(ref)
+ if id_value != ref:
+ kwargs.pop(key)
+ kwargs['%s_id' % key] = id_value
+ return kwargs
+
+ def create(self, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+ return self._create(
+ self.build_url(**kwargs),
+ {self.key: kwargs},
+ self.key)
+
+ def get(self, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+ return self._get(
+ self.build_url(**kwargs),
+ self.key)
+
+ def head(self, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+ return self._head(self.build_url(**kwargs))
+
+ def list(self, base_url=None, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+
+ return self._list(
+ '%(base_url)s%(query)s' % {
+ 'base_url': self.build_url(base_url=base_url, **kwargs),
+ 'query': '?%s' % urllib.urlencode(kwargs) if kwargs else '',
+ },
+ self.collection_key)
+
+ def put(self, base_url=None, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+
+ return self._update(
+ self.build_url(base_url=base_url, **kwargs),
+ method='PUT')
+
+ def update(self, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+ params = kwargs.copy()
+ params.pop('%s_id' % self.key)
+
+ return self._update(
+ self.build_url(**kwargs),
+ {self.key: params},
+ self.key,
+ method='PATCH')
+
+ def delete(self, **kwargs):
+ kwargs = self._filter_kwargs(kwargs)
+
+ return self._delete(
+ self.build_url(**kwargs))
+
+
class Resource(object):
"""
A resource represents a particular instance of an object (tenant, user,