diff --git a/README.rst b/README.rst index 749fd08..0974449 100644 --- a/README.rst +++ b/README.rst @@ -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 -------------------------------------------------- @@ -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: , Body: { "status": "OK", "output": { @@ -85,10 +76,11 @@ 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: , Body: d5252e7d-75bc-4083-85ed-fe51fa83f62b @@ -96,4 +88,36 @@ xml:: OK - \ No newline at end of file + + + + +text:: + + response, body = wrapper.get_fsid(body = 'text') + print('Response: {0}, Body:\n{1}'.format(response, body)) + + ==== + + Response: , 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 \ No newline at end of file diff --git a/cephclient/client.py b/cephclient/client.py index c3cbcbe..00aa0ca 100644 --- a/cephclient/client.py +++ b/cephclient/client.py @@ -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, diff --git a/cephclient/exceptions.py b/cephclient/exceptions.py index 2e6b2e2..40533e8 100644 --- a/cephclient/exceptions.py +++ b/cephclient/exceptions.py @@ -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." \ No newline at end of file diff --git a/cephclient/wrapper.py b/cephclient/wrapper.py index c3875bc..cc0db8b 100644 --- a/cephclient/wrapper.py +++ b/cephclient/wrapper.py @@ -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: @@ -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): @@ -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): @@ -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) @@ -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):