Author: tomaz
Date: Thu Dec 22 20:52:15 2011
New Revision: 1222444

URL: http://svn.apache.org/viewvc?rev=1222444&view=rev
Log:
1. Add 'request_kwargs' kwarg to the 'get_poll_request_kwargs' method.
This argument contains kwargs which were previously used to initiate the poll
request.

2. Add update_balancer method to the base LoadBalancer class.

3. Add update_balancer and ex_update_balancer_no_poll method to the Rackspace
LoadBalancer driver.

This patch has been contributed by Mark Everett <[email protected]> and
is part of GH-47.

Added:
    
libcloud/trunk/test/loadbalancer/fixtures/rackspace/v1_slug_loadbalancers_3xxx.json
Modified:
    libcloud/trunk/CHANGES
    libcloud/trunk/libcloud/common/base.py
    libcloud/trunk/libcloud/common/cloudstack.py
    libcloud/trunk/libcloud/dns/drivers/rackspace.py
    libcloud/trunk/libcloud/loadbalancer/base.py
    libcloud/trunk/libcloud/loadbalancer/drivers/rackspace.py
    libcloud/trunk/test/loadbalancer/test_rackspace.py

Modified: libcloud/trunk/CHANGES
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Thu Dec 22 20:52:15 2011
@@ -2,6 +2,13 @@
 
 Changes with Apache Libcloud in development:
 
+  *) General:
+
+    - Add 'request_kwargs' argument to the get_poll_request_kwargs method.
+      This argument contains kwargs which were previously used to initiate the
+      poll request.
+      [Mark Everett]
+
   *) Compute:
 
      - Added support for retrieving OpenNebula v3.2 instance types, OpenNebula
@@ -63,6 +70,12 @@ Changes with Apache Libcloud in developm
       (Rackspace driver).
       [Mark Everett]
 
+    - Add update_balancer method to the base LoadBalancer class.
+      [Mark Everett]
+
+    - Add update_balancer method to the Rackspace driver.
+      [Mark Everett]
+
 Changes with Apache Libcloud 0.7.1:
 
   *) General:

Modified: libcloud/trunk/libcloud/common/base.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/common/base.py?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/libcloud/common/base.py (original)
+++ libcloud/trunk/libcloud/common/base.py Thu Dec 22 20:52:15 2011
@@ -618,14 +618,16 @@ class PollingConnection(Connection):
                                          context=context)
         response = request(**kwargs)
         kwargs = self.get_poll_request_kwargs(response=response,
-                                              context=context)
+                                              context=context,
+                                              request_kwargs=kwargs)
 
         end = time.time() + self.timeout
         completed = False
         while time.time() < end and not completed:
             response = request(**kwargs)
             completed = self.has_completed(response=response)
-            time.sleep(self.poll_interval)
+            if not completed:
+                time.sleep(self.poll_interval)
 
         if not completed:
             raise LibcloudError('Job did not complete in %s seconds' %
@@ -643,7 +645,7 @@ class PollingConnection(Connection):
                   'headers': headers, 'method': method}
         return kwargs
 
-    def get_poll_request_kwargs(self, response, context):
+    def get_poll_request_kwargs(self, response, context, request_kwargs):
         """
         Return keyword arguments which are passed to the request() method when
         polling for the job status.
@@ -651,6 +653,10 @@ class PollingConnection(Connection):
         @param response: Response object returned by poll request.
         @type response: C{HTTPResponse}
 
+        @param request_kwargs: Kwargs previously used to initiate the
+                                  poll request.
+        @type response: C{dict}
+
         @return C{dict} Keyword arguments
         """
         raise NotImplementedError('get_poll_request_kwargs not implemented')

Modified: libcloud/trunk/libcloud/common/cloudstack.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/common/cloudstack.py?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/libcloud/common/cloudstack.py (original)
+++ libcloud/trunk/libcloud/common/cloudstack.py Thu Dec 22 20:52:15 2011
@@ -73,7 +73,7 @@ class CloudStackConnection(ConnectionUse
                            method='GET', context=None):
         return context
 
-    def get_poll_request_kwargs(self, response, context):
+    def get_poll_request_kwargs(self, response, context, request_kwargs):
         job_id = response['jobid']
         kwargs = {'command': 'queryAsyncJobResult', 'jobid': job_id}
         return kwargs

Modified: libcloud/trunk/libcloud/dns/drivers/rackspace.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/dns/drivers/rackspace.py?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/libcloud/dns/drivers/rackspace.py (original)
+++ libcloud/trunk/libcloud/dns/drivers/rackspace.py Thu Dec 22 20:52:15 2011
@@ -87,7 +87,7 @@ class RackspaceDNSConnection(OpenStack_1
     poll_interval = 2.5
     timeout = 30
 
-    def get_poll_request_kwargs(self, response, context):
+    def get_poll_request_kwargs(self, response, context, request_kwargs):
         job_id = response.object['jobId']
         kwargs = {'action': '/status/%s' % (job_id),
                 'params': {'showDetails': True}}

Modified: libcloud/trunk/libcloud/loadbalancer/base.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/loadbalancer/base.py?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/libcloud/loadbalancer/base.py (original)
+++ libcloud/trunk/libcloud/loadbalancer/base.py Thu Dec 22 20:52:15 2011
@@ -163,6 +163,25 @@ class Driver(BaseDriver):
         raise NotImplementedError(
                 'get_balancer not implemented for this driver')
 
+    def update_balancer(self, balancer, **kwargs):
+        """
+        Sets the name, algorithm, protocol, or port on a load balancer.
+
+        @keyword    name: New load balancer name
+        @type       metadata: C{str}
+
+        @keyword    algorithm: New load balancer algorithm
+        @type       metadata: C{libcloud.loadbalancer.base.Algorithm}
+
+        @keyword    protocol: New load balancer protocol
+        @type       metadata: C{str}
+
+        @keyword    port: New load balancer port
+        @type       metadata: C{int}
+        """
+        raise NotImplementedError(
+                'update_balancer not implemented for this driver')
+
     def balancer_attach_compute_node(self, balancer, node):
         """
         Attach a compute node as a member to the load balancer.

Modified: libcloud/trunk/libcloud/loadbalancer/drivers/rackspace.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/loadbalancer/drivers/rackspace.py?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/libcloud/loadbalancer/drivers/rackspace.py (original)
+++ libcloud/trunk/libcloud/loadbalancer/drivers/rackspace.py Thu Dec 22 
20:52:15 2011
@@ -21,10 +21,12 @@ try:
 except ImportError:
     import json
 
+from libcloud.utils.py3 import httplib
 from libcloud.utils.misc import reverse_dict
-from libcloud.common.base import JsonResponse
 from libcloud.loadbalancer.base import LoadBalancer, Member, Driver, Algorithm
 from libcloud.loadbalancer.base import DEFAULT_ALGORITHM
+from libcloud.common.types import LibcloudError
+from libcloud.common.base import JsonResponse, PollingConnection
 from libcloud.loadbalancer.types import State, MemberCondition
 from libcloud.common.openstack import OpenStackBaseConnection
 from libcloud.common.rackspace import (
@@ -105,7 +107,7 @@ class RackspaceConnectionThrottle(object
 
     @param max_connections: Maximum number of of connections per IP address.
                             (Must be between 0 and 100000, 0 allows an
-                            unlimited number of connections.
+                            unlimited number of connections.)
     @type max_connections: C{int}
 
     @param max_connection_rate: Maximum number of connections allowed
@@ -155,10 +157,12 @@ class RackspaceAccessRule(object):
         self.address = address
 
 
-class RackspaceConnection(OpenStackBaseConnection):
+class RackspaceConnection(OpenStackBaseConnection, PollingConnection):
     responseCls = RackspaceResponse
     auth_url = AUTH_URL_US
     _url_key = "lb_url"
+    poll_interval = 2
+    timeout = 80
 
     def __init__(self, user_id, key, secure=True, **kwargs):
         super(RackspaceConnection, self).__init__(user_id, key, secure,
@@ -181,6 +185,17 @@ class RackspaceConnection(OpenStackBaseC
         return super(RackspaceConnection, self).request(action=action,
                 params=params, data=data, method=method, headers=headers)
 
+    def get_poll_request_kwargs(self, response, context, request_kwargs):
+        return {'action': request_kwargs['action'],
+                'method': 'GET'}
+
+    def has_completed(self, response):
+        state = response.object['loadBalancer']['status']
+        if state == 'ERROR':
+            raise LibcloudError("Load balancer entered an ERROR state.",
+                                driver=self.driver)
+
+        return state == 'ACTIVE'
 
 class RackspaceUKConnection(RackspaceConnection):
     auth_url = AUTH_URL_UK
@@ -238,19 +253,19 @@ class RackspaceLBDriver(Driver):
 
     def create_balancer(self, name, members, protocol='http',
                         port=80, algorithm=DEFAULT_ALGORITHM):
-        algorithm = self._algorithm_to_value(algorithm)
-
-        balancer_object = {"loadBalancer":
-                {"name": name,
-                    "port": port,
-                    "algorithm": algorithm,
-                    "protocol": protocol.upper(),
-                    "virtualIps": [{"type": "PUBLIC"}],
-                    "nodes": [{"address": member.ip,
-                        "port": member.port,
-                        "condition": "ENABLED"} for member in members],
-                    }
-                }
+        balancer_attrs = self._kwargs_to_mutable_attrs(
+                                name=name,
+                                protocol=protocol,
+                                port=port,
+                                algorithm=algorithm)
+
+        balancer_attrs.update({
+            "virtualIps": [{"type": "PUBLIC"}],
+            "nodes": [{"address": member.ip,
+                "port": member.port,
+                "condition": "ENABLED"} for member in members],
+            })
+        balancer_object = {"loadBalancer": balancer_attrs}
 
         resp = self.connection.request('/loadbalancers',
                 method='POST',
@@ -261,7 +276,7 @@ class RackspaceLBDriver(Driver):
         uri = '/loadbalancers/%s' % (balancer.id)
         resp = self.connection.request(uri, method='DELETE')
 
-        return resp.status == 202
+        return resp.status == httplib.ACCEPTED
 
     def get_balancer(self, balancer_id):
         uri = '/loadbalancers/%s' % (balancer_id)
@@ -291,13 +306,29 @@ class RackspaceLBDriver(Driver):
         uri = '/loadbalancers/%s/nodes/%s' % (balancer.id, member.id)
         resp = self.connection.request(uri, method='DELETE')
 
-        return resp.status == 202
+        return resp.status == httplib.ACCEPTED
 
     def balancer_list_members(self, balancer):
         uri = '/loadbalancers/%s/nodes' % (balancer.id)
         return self._to_members(
                 self.connection.request(uri).object)
 
+    def update_balancer(self, balancer, **kwargs):
+        attrs = self._kwargs_to_mutable_attrs(**kwargs)
+        resp = self.connection.async_request(
+                    action='/loadbalancers/%s' % balancer.id,
+                    method='PUT',
+                    data=json.dumps(attrs))
+        return self._to_balancer(resp.object["loadBalancer"])
+
+    def ex_update_balancer_no_poll(self, balancer, **kwargs):
+        attrs = self._kwargs_to_mutable_attrs(**kwargs)
+        resp = self.connection.request(
+                    action='/loadbalancers/%s' % balancer.id,
+                    method='PUT',
+                    data=json.dumps(attrs))
+        return resp.status == httplib.ACCEPTED
+
     def ex_list_algorithm_names(self):
         """
         Lists algorithms supported by the API.  Returned as strings because
@@ -407,6 +438,23 @@ class RackspaceLBDriver(Driver):
                 extra=extra)
         return lbmember
 
+    def _kwargs_to_mutable_attrs(self, **attrs):
+        update_attrs = {}
+        if "name" in attrs:
+            update_attrs['name'] = attrs['name']
+
+        if "algorithm" in attrs:
+            algorithm_value = self._algorithm_to_value(attrs['algorithm'])
+            update_attrs['algorithm'] = algorithm_value
+
+        if "protocol" in attrs:
+            update_attrs['protocol'] = attrs['protocol'].upper()
+
+        if "port" in attrs:
+            update_attrs['port'] = int(attrs['port'])
+
+        return update_attrs
+
     def _ex_private_virtual_ips(self, el):
         if not 'virtualIps' in el:
             return None

Added: 
libcloud/trunk/test/loadbalancer/fixtures/rackspace/v1_slug_loadbalancers_3xxx.json
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/fixtures/rackspace/v1_slug_loadbalancers_3xxx.json?rev=1222444&view=auto
==============================================================================
--- 
libcloud/trunk/test/loadbalancer/fixtures/rackspace/v1_slug_loadbalancers_3xxx.json
 (added)
+++ 
libcloud/trunk/test/loadbalancer/fixtures/rackspace/v1_slug_loadbalancers_3xxx.json
 Thu Dec 22 20:52:15 2011
@@ -0,0 +1,46 @@
+{
+    "loadBalancer": {
+        "algorithm": "UUUUUUUUUU", 
+        "cluster": {
+            "name": "ztm-n05.lbaas.ord1.rackspace.net"
+        }, 
+        "connectionLogging": {
+            "enabled": false
+        }, 
+        "created": {
+            "time": "2011-04-07T16:27:50Z"
+        }, 
+        "id": 9999999, 
+        "name": "test2", 
+        "nodes": [
+            {
+                "address": "10.1.0.11", 
+                "condition": "ENABLED", 
+                "id": 30944, 
+                "port": 80, 
+                "status": "ONLINE"
+            }, 
+            {
+                "address": "10.1.0.10", 
+                "condition": "ENABLED", 
+                "id": 30945, 
+                "port": 80, 
+                "status": "ONLINE"
+            }
+        ], 
+        "port": 88888, 
+        "protocol": "XXXXX", 
+        "status": "ACTIVE", 
+        "updated": {
+            "time": "2011-04-07T16:28:12Z"
+        }, 
+        "virtualIps": [
+            {
+                "address": "1.1.1.1", 
+                "id": 1151, 
+                "ipVersion": "IPV4", 
+                "type": "PUBLIC"
+            }
+        ]
+    }
+}

Modified: libcloud/trunk/test/loadbalancer/test_rackspace.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/test_rackspace.py?rev=1222444&r1=1222443&r2=1222444&view=diff
==============================================================================
--- libcloud/trunk/test/loadbalancer/test_rackspace.py (original)
+++ libcloud/trunk/test/loadbalancer/test_rackspace.py Thu Dec 22 20:52:15 2011
@@ -23,11 +23,12 @@ except ImportError:
 
 from libcloud.utils.py3 import httplib
 
-from libcloud.loadbalancer.base import Member, Algorithm
+from libcloud.loadbalancer.base import LoadBalancer, Member, Algorithm
 from libcloud.loadbalancer.types import MemberCondition
 from libcloud.loadbalancer.drivers.rackspace import RackspaceLBDriver
 from libcloud.loadbalancer.drivers.rackspace import RackspaceUKLBDriver
 from libcloud.loadbalancer.drivers.rackspace import RackspaceAccessRuleType
+from libcloud.common.types import LibcloudError
 
 from test import MockHttpTestCase
 from test.file_fixtures import LoadBalancerFileFixtures, OpenStackFixtures
@@ -40,6 +41,7 @@ class RackspaceLBTests(unittest.TestCase
                 RackspaceLBMockHttp)
         RackspaceLBMockHttp.type = None
         self.driver = RackspaceLBDriver('user', 'key')
+        self.driver.connection.poll_interval = 0.0
 
     def test_list_protocols(self):
         protocols = self.driver.list_protocols()
@@ -293,6 +295,94 @@ class RackspaceLBTests(unittest.TestCase
         ret = balancer.detach_member(member)
         self.assertTrue(ret)
 
+    def test_update_balancer_protocol(self):
+        balancer = LoadBalancer(id='3130', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        updated_balancer = self.driver.update_balancer(balancer, 
protocol='HTTPS')
+        self.assertEqual('HTTPS', updated_balancer.extra['protocol'])
+
+    def test_update_balancer_port(self):
+        balancer = LoadBalancer(id='3131', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        updated_balancer = self.driver.update_balancer(balancer, port=1337)
+        self.assertEqual(1337, updated_balancer.port)
+
+    def test_update_balancer_name(self):
+        balancer = LoadBalancer(id='3132', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        updated_balancer = self.driver.update_balancer(balancer, 
name='new_lb_name')
+        self.assertEqual('new_lb_name', updated_balancer.name)
+
+    def test_update_balancer_algorithm(self):
+        balancer = LoadBalancer(id='3133', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        updated_balancer = self.driver.update_balancer(balancer,
+                                                       
algorithm=Algorithm.ROUND_ROBIN)
+        self.assertEqual(Algorithm.ROUND_ROBIN, 
updated_balancer.extra['algorithm'])
+
+    def test_update_balancer_bad_algorithm_exception(self):
+        balancer = LoadBalancer(id='3134', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        try:
+            self.driver.update_balancer(balancer,
+                                        algorithm='HAVE_MERCY_ON_OUR_SERVERS')
+        except LibcloudError:
+            pass
+        else:
+            self.fail('Should have thrown an exception with bad algorithm 
value')
+
+    def test_ex_update_balancer_no_poll_protocol(self):
+        balancer = LoadBalancer(id='3130', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        action_succeeded = self.driver.ex_update_balancer_no_poll(
+                                                              balancer,
+                                                              protocol='HTTPS')
+        self.assertTrue(action_succeeded)
+
+    def test_ex_update_balancer_no_poll_port(self):
+        balancer = LoadBalancer(id='3131', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        action_succeeded = self.driver.ex_update_balancer_no_poll(
+                                                            balancer,
+                                                            port=1337)
+        self.assertTrue(action_succeeded)
+
+    def test_ex_update_balancer_no_poll_name(self):
+        balancer = LoadBalancer(id='3132', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+
+        action_succeeded = self.driver.ex_update_balancer_no_poll(
+                                                          balancer,
+                                                          name='new_lb_name')
+        self.assertTrue(action_succeeded)
+
+    def test_ex_update_balancer_no_poll_algorithm(self):
+        balancer = LoadBalancer(id='3133', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        action_succeeded = self.driver.ex_update_balancer_no_poll(balancer,
+                                               algorithm=Algorithm.ROUND_ROBIN)
+        self.assertTrue(action_succeeded)
+
+    def test_ex_update_balancer_no_poll_bad_algorithm_exception(self):
+        balancer = LoadBalancer(id='3134', name='LB_update',
+                                         state='PENDING_UPDATE', 
ip='10.34.4.3',
+                                         port=80, driver=self.driver)
+        try:
+            self.driver.update_balancer(balancer,
+                                        algorithm='HAVE_MERCY_ON_OUR_SERVERS')
+        except LibcloudError:
+            pass
+        else:
+            self.fail('Should have thrown exception with bad algorithm value')
 
 class RackspaceUKLBTests(RackspaceLBTests):
 
@@ -302,7 +392,6 @@ class RackspaceUKLBTests(RackspaceLBTest
         RackspaceLBMockHttp.type = None
         self.driver = RackspaceUKLBDriver('user', 'key')
 
-
 class RackspaceLBMockHttp(MockHttpTestCase):
     fixtures = LoadBalancerFileFixtures('rackspace')
     auth_fixtures = OpenStackFixtures()
@@ -451,6 +540,60 @@ class RackspaceLBMockHttp(MockHttpTestCa
 
         raise NotImplementedError
 
+    def _v1_0_slug_loadbalancers_3130(self, method, url, body, headers):
+        """ update_balancer(b, protocol='HTTPS'), then get_balancer('3130') """
+        if method == "PUT":
+            self.assertEqual(json.loads(body), {'protocol': 'HTTPS'})
+            return (httplib.ACCEPTED, "", {}, 
httplib.responses[httplib.ACCEPTED])
+        elif method == "GET":
+            response_body = 
json.loads(self.fixtures.load("v1_slug_loadbalancers_3xxx.json"))
+            response_body['loadBalancer']['id'] = 3130
+            response_body['loadBalancer']['protocol'] = 'HTTPS'
+            return (httplib.OK, json.dumps(response_body), {}, 
httplib.responses[httplib.OK])
+        raise NotImplementedError
+
+    def _v1_0_slug_loadbalancers_3131(self, method, url, body, headers):
+        """ update_balancer(b, port=443), then get_balancer('3131') """
+        if method == "PUT":
+            self.assertEqual(json.loads(body), {'port': 1337})
+            return (httplib.ACCEPTED, "", {}, 
httplib.responses[httplib.ACCEPTED])
+        elif method == "GET":
+            response_body = 
json.loads(self.fixtures.load("v1_slug_loadbalancers_3xxx.json"))
+            response_body['loadBalancer']['id'] = 3131
+            response_body['loadBalancer']['port'] = 1337
+            return (httplib.OK, json.dumps(response_body), {}, 
httplib.responses[httplib.OK])
+        raise NotImplementedError
+
+    def _v1_0_slug_loadbalancers_3132(self, method, url, body, headers):
+        """ update_balancer(b, name='new_lb_name'), then get_balancer('3132') 
"""
+        if method == "PUT":
+            self.assertEqual(json.loads(body), {'name': 'new_lb_name'})
+            return (httplib.ACCEPTED, "", {}, 
httplib.responses[httplib.ACCEPTED])
+        elif method == "GET":
+            response_body = 
json.loads(self.fixtures.load("v1_slug_loadbalancers_3xxx.json"))
+            response_body['loadBalancer']['id'] = 3132
+            response_body['loadBalancer']['name'] = 'new_lb_name'
+            return (httplib.OK, json.dumps(response_body), {}, 
httplib.responses[httplib.OK])
+        raise NotImplementedError
+
+    def _v1_0_slug_loadbalancers_3133(self, method, url, body, headers):
+        """ update_balancer(b, algorithm='ROUND_ROBIN'), then 
get_balancer('3133') """
+        if method == "PUT":
+            self.assertEqual(json.loads(body), {'algorithm': 'ROUND_ROBIN'})
+            return (httplib.ACCEPTED, "", {}, 
httplib.responses[httplib.ACCEPTED])
+        elif method == "GET":
+            response_body = 
json.loads(self.fixtures.load("v1_slug_loadbalancers_3xxx.json"))
+            response_body['loadBalancer']['id'] = 3133
+            response_body['loadBalancer']['algorithm'] = 'ROUND_ROBIN'
+            return (httplib.OK, json.dumps(response_body), {}, 
httplib.responses[httplib.OK])
+        raise NotImplementedError
+
+    def _v1_0_slug_loadbalancers_3134(self, method, url, body, headers):
+        """ update.balancer(b, algorithm='HAVE_MERCY_ON_OUR_SERVERS') """
+        if method == "PUT":
+            return (httplib.BAD_REQUEST, "", {}, 
httplib.responses[httplib.BAD_REQUEST])
+        raise NotImplementedError
+
     def _v1_1_auth(self, method, url, body, headers):
         headers = {'content-type': 'application/json; charset=UTF-8'}
         body = self.auth_fixtures.load('_v1_1__auth.json')


Reply via email to