Disable cache busting stuff in the OpenStack driver and only enable it with Rackspace first-gen driver.
Also move base cache busting functionality on a base Connection class so it can be more easily re-used with other drivers. Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/16f2fd6d Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/16f2fd6d Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/16f2fd6d Branch: refs/heads/trunk Commit: 16f2fd6d188693064ff81766edd160f751cc61e9 Parents: cf951ff Author: Tomaz Muraus <[email protected]> Authored: Wed Oct 30 19:33:12 2013 +0100 Committer: Tomaz Muraus <[email protected]> Committed: Wed Oct 30 19:33:12 2013 +0100 ---------------------------------------------------------------------- libcloud/common/base.py | 26 +++++++++++++++++++++ libcloud/common/openstack.py | 10 -------- libcloud/compute/drivers/openstack.py | 3 --- libcloud/compute/drivers/rackspace.py | 1 + libcloud/loadbalancer/drivers/rackspace.py | 3 +-- libcloud/test/compute/test_openstack.py | 31 ------------------------- libcloud/test/test_connection.py | 29 +++++++++++++++++++++++ 7 files changed, 57 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/common/base.py ---------------------------------------------------------------------- diff --git a/libcloud/common/base.py b/libcloud/common/base.py index 9a90dec..9dc778f 100644 --- a/libcloud/common/base.py +++ b/libcloud/common/base.py @@ -13,9 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import sys import ssl import copy +import binascii import time from xml.etree import ElementTree as ET @@ -387,6 +389,7 @@ class Connection(object): secure = 1 driver = None action = None + cache_busting = False def __init__(self, secure=True, host=None, port=None, url=None, timeout=None): @@ -562,6 +565,10 @@ class Connection(object): # Extend default parameters params = self.add_default_params(params) + # Add cache busting parameters (if enabled) + if self.cache_busting and method == 'GET': + params = self._add_cache_busting_to_params(params=params) + # Extend default headers headers = self.add_default_headers(headers) @@ -671,6 +678,25 @@ class Connection(object): """ return data + def _add_cache_busting_to_params(self, params): + """ + Add cache busting parameter to the query parameters of a GET request. + + Parameters are only added if "cache_busting" class attribute is set to + True. + + Note: This should only be used with *naughty* providers which use + excessive caching of responses. + """ + cache_busting_value = binascii.hexlify(os.urandom(8)).decode('ascii') + + if isinstance(params, dict): + params['cache-busting'] = cache_busting_value + else: + params.append(('cache-busting', cache_busting_value)) + + return params + class PollingConnection(Connection): """ http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/common/openstack.py ---------------------------------------------------------------------- diff --git a/libcloud/common/openstack.py b/libcloud/common/openstack.py index 7eb1ee0..b9a6f2e 100644 --- a/libcloud/common/openstack.py +++ b/libcloud/common/openstack.py @@ -17,8 +17,6 @@ Common utilities for OpenStack """ import sys -import binascii -import os import datetime from libcloud.utils.py3 import httplib @@ -585,14 +583,6 @@ class OpenStackBaseConnection(ConnectionUserAndKey): (self.host, self.port, self.secure, self.request_path) = \ self._tuple_from_url(url) - def _add_cache_busting_to_params(self, params): - cache_busting_number = binascii.hexlify(os.urandom(8)).decode('ascii') - - if isinstance(params, dict): - params['cache-busting'] = cache_busting_number - else: - params.append(('cache-busting', cache_busting_number)) - class OpenStackDriverMixin(object): http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/compute/drivers/openstack.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py index f337391..d9da773 100644 --- a/libcloud/compute/drivers/openstack.py +++ b/libcloud/compute/drivers/openstack.py @@ -145,9 +145,6 @@ class OpenStackComputeConnection(OpenStackBaseConnection): if method in ("POST", "PUT"): headers = {'Content-Type': self.default_content_type} - if method == "GET": - self._add_cache_busting_to_params(params) - return super(OpenStackComputeConnection, self).request( action=action, params=params, data=data, http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/compute/drivers/rackspace.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/rackspace.py b/libcloud/compute/drivers/rackspace.py index a96f9d6..1aed2ef 100644 --- a/libcloud/compute/drivers/rackspace.py +++ b/libcloud/compute/drivers/rackspace.py @@ -55,6 +55,7 @@ class RackspaceFirstGenConnection(OpenStack_1_0_Connection): XML_NAMESPACE = 'http://docs.rackspacecloud.com/servers/api/v1.0' auth_url = AUTH_URL _auth_version = '2.0' + cache_busting = True def __init__(self, *args, **kwargs): self.region = kwargs.pop('region', None) http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/loadbalancer/drivers/rackspace.py ---------------------------------------------------------------------- diff --git a/libcloud/loadbalancer/drivers/rackspace.py b/libcloud/loadbalancer/drivers/rackspace.py index dc9eb05..13be22c 100644 --- a/libcloud/loadbalancer/drivers/rackspace.py +++ b/libcloud/loadbalancer/drivers/rackspace.py @@ -249,6 +249,7 @@ class RackspaceConnection(RackspaceConnection, PollingConnection): auth_url = AUTH_URL poll_interval = 2 timeout = 80 + cache_busting = True def request(self, action, params=None, data='', headers=None, method='GET'): @@ -259,8 +260,6 @@ class RackspaceConnection(RackspaceConnection, PollingConnection): if method in ('POST', 'PUT'): headers['Content-Type'] = 'application/json' - if method == 'GET': - self._add_cache_busting_to_params(params) return super(RackspaceConnection, self).request( action=action, params=params, http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/test/compute/test_openstack.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py index 44085d9..b73ccb4 100644 --- a/libcloud/test/compute/test_openstack.py +++ b/libcloud/test/compute/test_openstack.py @@ -1119,14 +1119,6 @@ class OpenStack_1_1_Tests(unittest.TestCase, TestCaseMixin): self.assertEqual(image_id, '1d4a8ea9-aae7-4242-a42d-5ff4702f2f14') self.assertEqual(image_id_two, '13') - def test_cache_busts(self): - self.driver.connection.request( - "/servers/12066", params={"key": "value"}) - - def test_cache_busts_with_list_of_tuples(self): - params = [("key", "value1"), ("key", "value2")] - self.driver.connection.request("/servers/12067", params=params) - def test_ex_rescue_with_password(self): node = Node(id=12064, name=None, state=None, public_ips=None, private_ips=None, driver=self.driver) @@ -1457,29 +1449,6 @@ class OpenStack_1_1_MockHttp(MockHttpTestCase): else: raise NotImplementedError() - # Cache Busting Test -- parameters as a dictionary - def _v1_1_slug_servers_12066(self, method, url, body, headers): - if method == "GET": - self.assertTrue( - "cache-busting=" in url, msg="Did not add cache-busting query string") - self.assertTrue("key=value" in url, msg="Did not add parameters") - body = self.fixtures.load('_servers_12064.json') - return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK]) - - raise NotImplementedError() - - # Cache Busting Test -- parameters as a list of tuples - def _v1_1_slug_servers_12067(self, method, url, body, headers): - if method == "GET": - self.assertTrue( - "cache-busting=" in url, msg="Did not add cache-busting query string") - self.assertTrue("key=value1" in url, msg="Did not add parameters") - self.assertTrue("key=value2" in url, msg="Did not add parameters") - body = self.fixtures.load('_servers_12064.json') - return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK]) - - raise NotImplementedError() - def _v1_1_slug_servers_12064(self, method, url, body, headers): if method == "GET": body = self.fixtures.load('_servers_12064.json') http://git-wip-us.apache.org/repos/asf/libcloud/blob/16f2fd6d/libcloud/test/test_connection.py ---------------------------------------------------------------------- diff --git a/libcloud/test/test_connection.py b/libcloud/test/test_connection.py index 892ec6e..1418c3c 100644 --- a/libcloud/test/test_connection.py +++ b/libcloud/test/test_connection.py @@ -88,6 +88,35 @@ class ConnectionClassTestCase(unittest.TestCase): call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1') + def test_cache_busting(self): + params1 = {'foo1': 'bar1', 'foo2': 'bar2'} + params2 = [('foo1', 'bar1'), ('foo2', 'bar2')] + + con = Connection() + con.connection = Mock() + con.pre_connect_hook = Mock() + con.pre_connect_hook.return_value = {}, {} + con.cache_busting = False + + con.request(action='/path', params=params1) + args, kwargs = con.pre_connect_hook.call_args + self.assertFalse('cache-busting' in args[0]) + self.assertEqual(args[0], params1) + + con.request(action='/path', params=params2) + args, kwargs = con.pre_connect_hook.call_args + self.assertFalse('cache-busting' in args[0]) + self.assertEqual(args[0], params2) + + con.cache_busting = True + + con.request(action='/path', params=params1) + args, kwargs = con.pre_connect_hook.call_args + self.assertTrue('cache-busting' in args[0]) + + con.request(action='/path', params=params2) + args, kwargs = con.pre_connect_hook.call_args + self.assertTrue('cache-busting' in args[0][len(params2)]) if __name__ == '__main__': sys.exit(unittest.main())
