Updated Branches: refs/heads/refactor_cloudstack_connection_class [created] c97410d14
Modify CloudStack Connection class so it looks more like other connection classes and user can more easily specify which attributes to send as part of the query string and as part of the request body. Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c97410d1 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c97410d1 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c97410d1 Branch: refs/heads/refactor_cloudstack_connection_class Commit: c97410d14510346b297187e4aef179e4980d88f8 Parents: 5fc5073 Author: Tomaz Muraus <[email protected]> Authored: Wed Nov 20 14:20:15 2013 +0100 Committer: Tomaz Muraus <[email protected]> Committed: Wed Nov 20 14:21:13 2013 +0100 ---------------------------------------------------------------------- libcloud/common/cloudstack.py | 82 ++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/c97410d1/libcloud/common/cloudstack.py ---------------------------------------------------------------------- diff --git a/libcloud/common/cloudstack.py b/libcloud/common/cloudstack.py index a34f3df..5f139e2 100644 --- a/libcloud/common/cloudstack.py +++ b/libcloud/common/cloudstack.py @@ -15,6 +15,7 @@ import base64 import hashlib +import copy import hmac from libcloud.utils.py3 import urlencode @@ -39,6 +40,17 @@ class CloudStackConnection(ConnectionUserAndKey, PollingConnection): ASYNC_SUCCESS = 1 ASYNC_FAILURE = 2 + def encode_data(self, data): + """ + Must of the data is sent as part of query params (eeww), + but in newer versions, userdata argument can be sent as a + urlencoded data in the request body. + """ + if data: + data = urlencode(data) + + return data + def _make_signature(self, params): signature = [(k.lower(), v) for k, v in list(params.items())] signature.sort(key=lambda x: x[0]) @@ -59,25 +71,37 @@ class CloudStackConnection(ConnectionUserAndKey, PollingConnection): return params, headers - def _async_request(self, command, **kwargs): - context = {'command': command} - context.update(kwargs) - result = super(CloudStackConnection, self).async_request(action=None, - params=None, - data=None, - headers=None, - method=None, + def _async_request(self, command, action=None, params=None, data=None, + headers=None, method='GET', context=None): + if params: + context = copy.deepcopy(params) + else: + context = {} + + # Command is specified as part of GET call + context['command'] = command + result = super(CloudStackConnection, self).async_request(action=action, + params=params, + data=data, + headers= + headers, + method=method, context= context) return result['jobresult'] def get_request_kwargs(self, action, params=None, data='', headers=None, method='GET', context=None): - return context + command = context['command'] + request_kwargs = {'command': command, 'action': action, + 'params': params, 'data': data, + 'headers': headers, 'method': method} + return request_kwargs def get_poll_request_kwargs(self, response, context, request_kwargs): job_id = response['jobid'] - kwargs = {'command': 'queryAsyncJobResult', 'jobid': job_id} + params = {'jobid': job_id} + kwargs = {'command': 'queryAsyncJobResult', 'params': params} return kwargs def has_completed(self, response): @@ -89,13 +113,24 @@ class CloudStackConnection(ConnectionUserAndKey, PollingConnection): return status == self.ASYNC_SUCCESS - def _sync_request(self, command, **kwargs): - """This method handles synchronous calls which are generally fast - information retrieval requests and thus return 'quickly'.""" + def _sync_request(self, command, action=None, params=None, data=None, + headers=None, method='GET'): + """ + This method handles synchronous calls which are generally fast + information retrieval requests and thus return 'quickly'. + """ + # command is always sent as part of "command" query parameter + if params: + params = copy.deepcopy(params) + else: + params = {} + + params['command'] = command + result = self.request(action=self.driver.path, params=params, + data=data, headers=headers, method=method) - kwargs['command'] = command - result = self.request(self.driver.path, params=kwargs) command = command.lower() + 'response' + if command not in result.object: raise MalformedResponseError( "Unknown response format", @@ -116,8 +151,15 @@ class CloudStackDriverMixIn(object): super(CloudStackDriverMixIn, self).__init__(key, secret, secure, host, port) - def _sync_request(self, command, **kwargs): - return self.connection._sync_request(command, **kwargs) - - def _async_request(self, command, **kwargs): - return self.connection._async_request(command, **kwargs) + def _sync_request(self, command, action=None, params=None, data=None, + headers=None, method='GET'): + return self.connection._sync_request(command=command, action=action, + params=params, data=data, + headers=headers, method=method) + + def _async_request(self, command, action=None, params=None, data=None, + headers=None, method='GET', context=None): + return self.connection._async_request(command=command, action=action, + params=params, data=data, + headers=headers, method=method, + context=context)
