Skip to content

Commit

Permalink
Merge pull request #5 from dmsimard/wip-1_4
Browse files Browse the repository at this point in the history
Implement missing GET calls, binary requests, body type validation
  • Loading branch information
dmsimard committed Jan 18, 2014
2 parents cb00d05 + 5448bff commit c6d8a9b
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 44 deletions.
54 changes: 39 additions & 15 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Client
--------------------------------------------------

The cephclient class takes care of sending calls to the API through HTTP and
handle the responses. It supports queries for JSON, XML or plain text.
handle the responses. It supports queries for JSON, XML, plain text or binary.

Wrapper
--------------------------------------------------
Expand Down Expand Up @@ -55,25 +55,16 @@ Instanciate CephWrapper::

Do your request and specify the reponse type you are expecting.

Either ``json``, ``xml`` or ``text`` (default) are available.

text::

response, body = wrapper.get_fsid(body = 'text')
print(response)

====

d5252e7d-75bc-4083-85ed-fe51fa83f62b

Either ``json``, ``xml``, ``text`` (default) or ``binary`` are available.

json::

response, body = wrapper.get_fsid(body = 'json')
print(json.dumps(body, indent=4, separators=(',', ': ')))
print('Response: {0}, Body:\n{1}'.format(response, json.dumps(body, indent=4, separators=(',', ': '))))

====

Response: <Response [200]>, Body:
{
"status": "OK",
"output": {
Expand All @@ -85,15 +76,48 @@ json::
xml::

response, body = wrapper.get_fsid(body = 'xml')
print(etree.tostring(body, pretty_print=True))
print('Response: {0}, Body:\n{1}'.format(reponse, etree.tostring(body, pretty_print=True)))

====

Response: <Response [200]>, Body:
<response>
<output>
<fsid><fsid>d5252e7d-75bc-4083-85ed-fe51fa83f62b</fsid></fsid>
</output>
<status>
OK
</status>
</response>
</response>



text::

response, body = wrapper.get_fsid(body = 'text')
print('Response: {0}, Body:\n{1}'.format(response, body))

====

Response: <Response [200]>, Body:
d5252e7d-75bc-4083-85ed-fe51fa83f62b

binary::

response, body = wrapper.mon_getmap(body = 'binary')
# < Do something binary with 'body' >


RELEASE NOTES
==================================================
**0.1.0.2**

- Implemented or fixed missing GET calls (All API GET calls that are not under the '/tell' namespace are now supported)
- Client can optionally raise an exception when requesting a unsupported body type for a provided API call (ex: requesting json through the wrapper for a call that is known to only return binary will raise an exception)
- Client now supports binary type responses (ex: crush map, mon map, etc)
- Improved the README (!)


**0.1.0.1**

- First public release of python-cephclient
18 changes: 15 additions & 3 deletions cephclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,27 @@ def _request(self, url, method, **kwargs):
elif kwargs['body'] is 'text':
kwargs['headers']['Accept'] = 'text/plain'
kwargs['headers']['Content-Type'] = 'text/plain'
elif kwargs['body'] is 'binary':
kwargs['headers']['Accept'] = 'application/octet-stream'
kwargs['headers']['Content-Type'] = 'application/octet-stream'
else:
raise exceptions.UnknownRequestType()

del kwargs['body']
raise exceptions.UnsupportedRequestType()
except KeyError:
# Default if body type is unspecified is text/plain
kwargs['headers']['Accept'] = 'text/plain'
kwargs['headers']['Content-Type'] = 'text/plain'

# Optionally verify if requested body type is supported
try:
if kwargs['body'] not in kwargs['supported_body_types']:
raise exceptions.UnsupportedBodyType()
else:
del kwargs['supported_body_types']
except KeyError:
pass

del kwargs['body']

self.log.debug("{0} URL: {1}{2} - {3}".format(method,
self.endpoint,
url,
Expand Down
9 changes: 8 additions & 1 deletion cephclient/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ def __str__(self):
return "This function is not yet available/completed."


class UnknownRequestType(Exception):
class UnsupportedRequestType(Exception):
"""
If a requested body type is not mapped
"""
def __str__(self):
return "Unknown request type. Requests available: 'json', 'xml', 'text'."

class UnsupportedBodyType(Exception):
"""
If a requested body type is not mapped
"""
def __str__(self):
return "This type of body is not supported for this API call."
74 changes: 49 additions & 25 deletions cephclient/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ def mds_dump(self, epoch = None, **kwargs):


def mds_getmap(self, epoch = None, **kwargs):
kwargs['supported_body_types'] = ['binary']

if epoch is not None:
return self.get('mds/getmap?epoch={0}'.format(epoch), **kwargs)
else:
Expand Down Expand Up @@ -153,14 +155,22 @@ def osd_find(self, id, **kwargs):
return self.get('osd/find?id={0}'.format(id), **kwargs)


def osd_getcrushmap(self, **kwargs):
# Could not get this to work yet
raise exceptions.FunctionNotImplemented()
def osd_getcrushmap(self, epoch = None, **kwargs):
kwargs['supported_body_types'] = ['binary']

if epoch is not None:
return self.get('osd/getcrushmap?epoch={0}'.format(epoch), **kwargs)
else:
return self.get('osd/getcrushmap', **kwargs)


def osd_getmap(self, epoch = None, **kwargs):
kwargs['supported_body_types'] = ['binary']

def osd_getmap(self, **kwargs):
# Could not get this to work yet
raise exceptions.FunctionNotImplemented()
if epoch is not None:
return self.get('osd/getmap?epoch={0}'.format(epoch), **kwargs)
else:
return self.get('osd/getmap', **kwargs)


def osd_getmaxosd(self, **kwargs):
Expand All @@ -181,8 +191,8 @@ def osd_lspools(self, auid = None, **kwargs):
return self.get('osd/lspools', **kwargs)


def osd_map(self, **kwargs):
raise exceptions.FunctionNotImplemented()
def osd_map(self, pool, object, **kwargs):
return self.get('osd/map?pool={0}&object={1}'.format(pool, object), **kwargs)


def osd_perf(self, **kwargs):
Expand Down Expand Up @@ -222,13 +232,17 @@ def mon_dump(self, epoch = None, **kwargs):
return self.get('mon/dump', **kwargs)


def mon_getmap(self, **kwargs):
# Could not get this to work yet
raise exceptions.FunctionNotImplemented()
def mon_getmap(self, epoch = None, **kwargs):
kwargs['supported_body_types'] = ['binary']

if epoch is not None:
return self.get('mon/getmap?epoch={0}'.format(epoch), **kwargs)
else:
return self.get('mon/getmap', **kwargs)

def mon_stat(self, **kwargs):
# TODO: Seems broken ? Returns null.
kwargs['supported_body_types'] = ['text', 'xml']

return self.get('mon/stat', **kwargs)


Expand All @@ -240,33 +254,43 @@ def mon_status(self, **kwargs):
# pg GET calls
###
def pg_debug(self, debugop, **kwargs):
return self.get('pg/debug?debugop={0}'.format(debugop), kwargs)
kwargs['supported_body_types'] = ['text', 'xml']

return self.get('pg/debug?debugop={0}'.format(debugop), kwargs)

def pg_dump(self, **kwargs):
raise exceptions.FunctionNotImplemented()

def pg_dump(self, dumpcontents = None, **kwargs):
if dumpcontents is not None:
return self.get('pg/dump?dumpcontents={0}'.format(dumpcontents), **kwargs)
else:
return self.get('pg/dump', **kwargs)

def pg_dump_json(self, **kwargs):
raise exceptions.FunctionNotImplemented()
def pg_dump_json(self, dumpcontents = None, **kwargs):
if dumpcontents is not None:
return self.get('pg/dump_json?dumpcontents={0}'.format(dumpcontents), **kwargs)
else:
return self.get('pg/dump_json', **kwargs)


def pg_dump_pools_json(self, **kwargs):
raise exceptions.FunctionNotImplemented()
return self.get('pg/dump_pools_json', **kwargs)


def pg_dump_stuck(self, **kwargs):
raise exceptions.FunctionNotImplemented()
def pg_dump_stuck(self, stuckops = None, **kwargs):
if stuckops is not None:
return self.get('pg/dump_stuck?stuckops={0}'.format(stuckops), **kwargs)
else:
return self.get('pg/dump_stuck', **kwargs)


def pg_getmap(self, **kwargs):
# Could not get this to work yet
raise exceptions.FunctionNotImplemented()
kwargs['supported_body_types'] = ['binary']

return self.get('pg/getmap', **kwargs)


def pg_map(self, **kwargs):
# Could not get this to work yet
raise exceptions.FunctionNotImplemented()
def pg_map(self, pgid, **kwargs):
return self.get('pg/map?pgid={0}'.format(pgid), **kwargs)


def pg_stat(self, **kwargs):
Expand Down

0 comments on commit c6d8a9b

Please sign in to comment.