Author: tomaz
Date: Wed Dec 14 06:14:01 2011
New Revision: 1214063

URL: http://svn.apache.org/viewvc?rev=1214063&view=rev
Log:
Add Brightbox.net LoadBalancer driver. This patch has been contributed by Tim
Fletcher <mail at tfletcher dot com> and is part of LIBCLOUD-136.

Added:
    libcloud/trunk/libcloud/common/brightbox.py
    libcloud/trunk/libcloud/loadbalancer/drivers/brightbox.py
    libcloud/trunk/test/loadbalancer/fixtures/brightbox/
    libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers.json
    
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_lba_1235f.json
    libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_post.json
    libcloud/trunk/test/loadbalancer/fixtures/brightbox/token.json
    libcloud/trunk/test/loadbalancer/test_brightbox.py
Modified:
    libcloud/trunk/libcloud/compute/drivers/brightbox.py
    libcloud/trunk/libcloud/loadbalancer/providers.py
    libcloud/trunk/libcloud/loadbalancer/types.py
    libcloud/trunk/test/secrets.py-dist

Added: libcloud/trunk/libcloud/common/brightbox.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/common/brightbox.py?rev=1214063&view=auto
==============================================================================
--- libcloud/trunk/libcloud/common/brightbox.py (added)
+++ libcloud/trunk/libcloud/common/brightbox.py Wed Dec 14 06:14:01 2011
@@ -0,0 +1,91 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import base64
+
+from libcloud.common.base import ConnectionUserAndKey, JsonResponse
+from libcloud.compute.types import InvalidCredsError
+
+from libcloud.utils.py3 import b
+
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+
+class BrightboxResponse(JsonResponse):
+    def success(self):
+        return self.status >= 200 and self.status < 400
+
+    def parse_body(self):
+        if self.headers['content-type'].split('; ')[0] == 'application/json':
+            return super(BrightboxResponse, self).parse_body()
+        else:
+            return self.body
+
+    def parse_error(self):
+        response = super(BrightboxResponse, self).parse_body()
+
+        return '%s: %s' % (response['error_name'], response['errors'][0])
+
+
+class BrightboxConnection(ConnectionUserAndKey):
+    """
+    Connection class for the Brightbox driver
+    """
+
+    host = 'api.gb1.brightbox.com'
+    responseCls = BrightboxResponse
+
+    def _fetch_oauth_token(self):
+        body = json.dumps({'client_id': self.user_id, 'grant_type': 'none'})
+
+        authorization = 'Basic ' + str(base64.encodestring(b('%s:%s' %
+                                        (self.user_id, self.key)))).rstrip()
+
+        self.connect()
+
+        response = self.connection.request(method='POST', url='/token',
+                                           body=body, headers={
+            'Host': self.host,
+            'User-Agent': self._user_agent(),
+            'Authorization': authorization,
+            'Content-Type': 'application/json',
+            'Content-Length': str(len(body))
+        })
+
+        response = self.connection.getresponse()
+
+        if response.status == 200:
+            return json.loads(response.read())['access_token']
+        else:
+            message = '%s (%s)' % (json.loads(response.read())['error'],
+                                   response.status)
+
+            raise InvalidCredsError(message)
+
+    def add_default_headers(self, headers):
+        try:
+            headers['Authorization'] = 'OAuth ' + self.token
+        except AttributeError:
+            self.token = self._fetch_oauth_token()
+
+            headers['Authorization'] = 'OAuth ' + self.token
+
+        return headers
+
+    def encode_data(self, data):
+        return json.dumps(data)

Modified: libcloud/trunk/libcloud/compute/drivers/brightbox.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/brightbox.py?rev=1214063&r1=1214062&r2=1214063&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/brightbox.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/brightbox.py Wed Dec 14 06:14:01 
2011
@@ -16,84 +16,16 @@
 Brightbox Driver
 """
 from libcloud.utils.py3 import httplib
-import base64
 
-from libcloud.utils.py3 import b
-
-from libcloud.common.base import ConnectionUserAndKey, JsonResponse
-from libcloud.compute.types import Provider, NodeState, InvalidCredsError
+from libcloud.common.brightbox import BrightboxConnection
+from libcloud.compute.types import Provider, NodeState
 from libcloud.compute.base import NodeDriver
 from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
 
-try:
-    import simplejson as json
-except ImportError:
-    import json
 
 API_VERSION = '1.0'
 
 
-class BrightboxResponse(JsonResponse):
-    def success(self):
-        return self.status >= 200 and self.status < 400
-
-    def parse_body(self):
-        if self.headers['content-type'].split('; ')[0] == 'application/json':
-            return super(BrightboxResponse, self).parse_body()
-        else:
-            return self.body
-
-    def parse_error(self):
-        return super(BrightboxResponse, self).parse_body()['error']
-
-
-class BrightboxConnection(ConnectionUserAndKey):
-    """
-    Connection class for the Brightbox driver
-    """
-
-    host = 'api.gb1.brightbox.com'
-    responseCls = BrightboxResponse
-
-    def _fetch_oauth_token(self):
-        body = json.dumps({'client_id': self.user_id, 'grant_type': 'none'})
-
-        authorization = 'Basic ' + str(base64.encodestring(b('%s:%s' %
-                                        (self.user_id, self.key)))).rstrip()
-
-        self.connect()
-
-        response = self.connection.request(method='POST', url='/token', 
body=body, headers={
-            'Host': self.host,
-            'User-Agent': self._user_agent(),
-            'Authorization': authorization,
-            'Content-Type': 'application/json',
-            'Content-Length': str(len(body))
-        })
-
-        response = self.connection.getresponse()
-
-        if response.status == 200:
-            return json.loads(response.read())['access_token']
-        else:
-            message = '%s (%s)' % (json.loads(response.read())['error'], 
response.status)
-
-            raise InvalidCredsError(message)
-
-    def add_default_headers(self, headers):
-        try:
-            headers['Authorization'] = 'OAuth ' + self.token
-        except AttributeError:
-            self.token = self._fetch_oauth_token()
-
-            headers['Authorization'] = 'OAuth ' + self.token
-
-        return headers
-
-    def encode_data(self, data):
-        return json.dumps(data)
-
-
 class BrightboxNodeDriver(NodeDriver):
     """
     Brightbox node driver

Added: libcloud/trunk/libcloud/loadbalancer/drivers/brightbox.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/loadbalancer/drivers/brightbox.py?rev=1214063&view=auto
==============================================================================
--- libcloud/trunk/libcloud/loadbalancer/drivers/brightbox.py (added)
+++ libcloud/trunk/libcloud/loadbalancer/drivers/brightbox.py Wed Dec 14 
06:14:01 2011
@@ -0,0 +1,132 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from libcloud.utils.py3 import httplib
+from libcloud.common.brightbox import BrightboxConnection
+from libcloud.loadbalancer.base import Driver, Algorithm, Member
+from libcloud.loadbalancer.base import LoadBalancer
+from libcloud.loadbalancer.types import State
+from libcloud.utils.misc import reverse_dict
+
+API_VERSION = '1.0'
+
+
+class BrightboxLBDriver(Driver):
+    connectionCls = BrightboxConnection
+
+    name = 'Brightbox'
+
+    LB_STATE_MAP = {
+        'creating': State.PENDING,
+        'active': State.RUNNING,
+        'deleting': State.UNKNOWN,
+        'deleted': State.UNKNOWN,
+        'failing': State.UNKNOWN,
+        'failed': State.UNKNOWN,
+    }
+
+    _VALUE_TO_ALGORITHM_MAP = {
+        'round-robin': Algorithm.ROUND_ROBIN,
+        'least-connections': Algorithm.LEAST_CONNECTIONS
+    }
+
+    _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
+
+    def list_protocols(self):
+        return ['tcp', 'http']
+
+    def list_balancers(self):
+        data = self.connection.request('/%s/load_balancers' % API_VERSION) \
+                   .object
+
+        return list(map(self._to_balancer, data))
+
+    def create_balancer(self, name, port, protocol, algorithm, members):
+        response = self._post('/%s/load_balancers' % API_VERSION, {
+          'name': name,
+          'nodes': list(map(self._member_to_node, members)),
+          'policy': self._algorithm_to_value(algorithm),
+          'listeners': [{'in': port, 'out': port, 'protocol': protocol}],
+          'healthcheck': {'type': protocol, 'port': port}
+        })
+
+        return self._to_balancer(response.object)
+
+    def destroy_balancer(self, balancer):
+        response = self.connection.request('/%s/load_balancers/%s' %
+                                           (API_VERSION, balancer.id),
+                                           method='DELETE')
+
+        return response.status == httplib.ACCEPTED
+
+    def get_balancer(self, balancer_id):
+        data = self.connection.request('/%s/load_balancers/%s' % (API_VERSION,
+                                                         balancer_id)).object
+
+        return self._to_balancer(data)
+
+    def balancer_attach_compute_node(self, balancer, node):
+        return self.balancer_attach_member(balancer, node)
+
+    def balancer_attach_member(self, balancer, member):
+        path = '/%s/load_balancers/%s/add_nodes' % (API_VERSION, balancer.id)
+
+        response = self._post(path, {'nodes': [self._member_to_node(member)]})
+
+        return member
+
+    def balancer_detach_member(self, balancer, member):
+        path = '/%s/load_balancers/%s/remove_nodes' % (API_VERSION,
+                                                       balancer.id)
+
+        response = self._post(path, {'nodes': [self._member_to_node(member)]})
+
+        return response.status == httplib.ACCEPTED
+
+    def balancer_list_members(self, balancer):
+        path = '/%s/load_balancers/%s' % (API_VERSION, balancer.id)
+
+        data = self.connection.request(path).object
+
+        return list(map(self._node_to_member, data['nodes']))
+
+    def _post(self, path, data={}):
+        headers = {'Content-Type': 'application/json'}
+
+        return self.connection.request(path, data=data, headers=headers,
+                                       method='POST')
+
+    def _to_balancer(self, data):
+        return LoadBalancer(
+            id=data['id'],
+            name=data['name'],
+            state=self.LB_STATE_MAP.get(data['status'], State.UNKNOWN),
+            ip=self._public_ip(data),
+            port=data['listeners'][0]['in'],
+            driver=self.connection.driver
+        )
+
+    def _member_to_node(self, member):
+        return {'node': member.id}
+
+    def _node_to_member(self, data):
+        return Member(data['id'], None, None)
+
+    def _public_ip(self, data):
+        if len(data['cloud_ips']) > 0:
+            ip = data['cloud_ips'][0]['public_ip']
+        else:
+            ip = None

Modified: libcloud/trunk/libcloud/loadbalancer/providers.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/loadbalancer/providers.py?rev=1214063&r1=1214062&r2=1214063&view=diff
==============================================================================
--- libcloud/trunk/libcloud/loadbalancer/providers.py (original)
+++ libcloud/trunk/libcloud/loadbalancer/providers.py Wed Dec 14 06:14:01 2011
@@ -31,7 +31,10 @@ DRIVERS = {
             ('libcloud.loadbalancer.drivers.gogrid', 'GoGridLBDriver'),
         Provider.NINEFOLD:
             ('libcloud.loadbalancer.drivers.ninefold', 'NinefoldLBDriver'),
+        Provider.BRIGHTBOX:
+            ('libcloud.loadbalancer.drivers.brightbox', 'BrightboxLBDriver')
 }
 
+
 def get_driver(provider):
     return get_provider_driver(DRIVERS, provider)

Modified: libcloud/trunk/libcloud/loadbalancer/types.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/loadbalancer/types.py?rev=1214063&r1=1214062&r2=1214063&view=diff
==============================================================================
--- libcloud/trunk/libcloud/loadbalancer/types.py (original)
+++ libcloud/trunk/libcloud/loadbalancer/types.py Wed Dec 14 06:14:01 2011
@@ -36,6 +36,7 @@ class Provider(object):
     GOGRID = 1
     NINEFOLD = 2
     RACKSPACE_UK = 3
+    BRIGHTBOX = 4
 
 
 class State(object):

Added: libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers.json
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers.json?rev=1214063&view=auto
==============================================================================
--- libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers.json 
(added)
+++ libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers.json Wed 
Dec 14 06:14:01 2011
@@ -0,0 +1,22 @@
+[{"id": "lba-1235f",
+  "resource_type": "load_balancer",
+  "url": "https://api.gb1.brightbox.com/1.0/load_balancers/lba-1235f";,
+  "name": "lb1",
+  "created_at": "2011-10-06T14:50:28Z",
+  "deleted_at": null,
+  "status": "active",
+  "listeners": [{"out": 80, "protocol": "http", "in": 80}],
+  "cloud_ips":
+   [{"id": "cip-c2v98",
+     "public_ip": "109.107.37.179",
+     "resource_type": "cloud_ip",
+     "reverse_dns": "cip-109-107-37-179.gb1.brightbox.com",
+     "status": "mapped",
+     "url": "https://api.gb1.brightbox.com/1.0/cloud_ips/cip-c2v98"}],
+  "account":
+   {"id": "acc-43ks4",
+    "resource_type": "account",
+    "url": "https://api.gb1.brightbox.com/1.0/account";,
+    "name": "Brightbox",
+    "status": "active"},
+  "nodes": []}]

Added: 
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_lba_1235f.json
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_lba_1235f.json?rev=1214063&view=auto
==============================================================================
--- 
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_lba_1235f.json
 (added)
+++ 
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_lba_1235f.json
 Wed Dec 14 06:14:01 2011
@@ -0,0 +1,38 @@
+{"id": "lba-1235f",
+ "resource_type": "load_balancer",
+ "url": "https://api.gb1.brightbox.com/1.0/load_balancers/lba-1235f";,
+ "policy": "least-connections",
+ "name": "lb1",
+ "created_at": "2011-10-01T01:00:00Z",
+ "deleted_at": null,
+ "healthcheck":
+  {"threshold_down": 3,
+   "timeout": 5000,
+   "port": 80,
+   "request": "/",
+   "type": "http",
+   "interval": 5000,
+   "threshold_up": 3},
+ "listeners":
+  [{"out": 80,
+    "protocol": "http",
+    "in": 80}],
+ "status": "active",
+ "cloud_ips":
+  [],
+ "account":
+  {"id": "acc-43ks4",
+   "resource_type": "account",
+   "url": "https://api.gb1.brightbox.com/1.0/account";,
+   "name": "Brightbox",
+   "status": "active"},
+ "nodes":
+  [{"id": "srv-lv426",
+    "resource_type": "server",
+    "url": "https://api.gb1.brightbox.com/1.0/servers/srv-lv426";,
+    "name": "web1",
+    "created_at": "2011-10-01T01:00:00Z",
+    "deleted_at": null,
+    "hostname": "srv-lv426",
+    "started_at": "2011-10-01T01:01:00Z",
+    "status": "active"}]}
\ No newline at end of file

Added: 
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_post.json
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_post.json?rev=1214063&view=auto
==============================================================================
--- 
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_post.json 
(added)
+++ 
libcloud/trunk/test/loadbalancer/fixtures/brightbox/load_balancers_post.json 
Wed Dec 14 06:14:01 2011
@@ -0,0 +1,38 @@
+{"id": "lba-o466u",
+ "resource_type": "load_balancer",
+ "url": "https://api.gb1.brightbox.com/1.0/load_balancers/lba-o466u";,
+ "policy": "least-connections",
+ "name": "lb2",
+ "created_at": "2011-10-01T01:00:00Z",
+ "deleted_at": null,
+ "healthcheck":
+  {"threshold_down": 3,
+   "timeout": 5000,
+   "port": 80,
+   "request": "/",
+   "type": "http",
+   "interval": 5000,
+   "threshold_up": 3},
+ "listeners":
+  [{"out": 80,
+    "protocol": "http",
+    "in": 80}],
+ "status": "creating",
+ "cloud_ips":
+  [],
+ "account":
+  {"id": "acc-43ks4",
+   "resource_type": "account",
+   "url": "https://api.gb1.brightbox.com/1.0/account";,
+   "name": "Brightbox",
+   "status": "active"},
+ "nodes":
+  [{"id": "srv-lv426",
+    "resource_type": "server",
+    "url": "https://api.gb1.brightbox.com/1.0/servers/srv-lv426";,
+    "name": "web1",
+    "created_at": "2011-10-01T01:00:00Z",
+    "deleted_at": null,
+    "hostname": "srv-lv426",
+    "started_at": "2011-10-01T01:01:00Z",
+    "status": "active"}]}
\ No newline at end of file

Added: libcloud/trunk/test/loadbalancer/fixtures/brightbox/token.json
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/fixtures/brightbox/token.json?rev=1214063&view=auto
==============================================================================
--- libcloud/trunk/test/loadbalancer/fixtures/brightbox/token.json (added)
+++ libcloud/trunk/test/loadbalancer/fixtures/brightbox/token.json Wed Dec 14 
06:14:01 2011
@@ -0,0 +1 @@
+{"access_token": "k1bjflpsaj8wnrbrwzad0eqo36nxiha", "expires_in": 3600}

Added: libcloud/trunk/test/loadbalancer/test_brightbox.py
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/loadbalancer/test_brightbox.py?rev=1214063&view=auto
==============================================================================
--- libcloud/trunk/test/loadbalancer/test_brightbox.py (added)
+++ libcloud/trunk/test/loadbalancer/test_brightbox.py Wed Dec 14 06:14:01 2011
@@ -0,0 +1,131 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import unittest
+
+from libcloud.utils.py3 import httplib
+from libcloud.loadbalancer.base import Member, Algorithm
+from libcloud.loadbalancer.drivers.brightbox import BrightboxLBDriver
+from libcloud.loadbalancer.types import State
+
+from test import MockHttpTestCase
+from test.secrets import LB_BRIGHTBOX_PARAMS
+from test.file_fixtures import LoadBalancerFileFixtures
+
+
+class BrightboxLBTests(unittest.TestCase):
+    def setUp(self):
+        BrightboxLBDriver.connectionCls.conn_classes = (None,
+                                                        BrightboxLBMockHttp)
+        BrightboxLBMockHttp.type = None
+        self.driver = BrightboxLBDriver(*LB_BRIGHTBOX_PARAMS)
+
+    def test_list_protocols(self):
+        protocols = self.driver.list_protocols()
+
+        self.assertEqual(len(protocols), 2)
+        self.assertTrue('tcp' in protocols)
+        self.assertTrue('http' in protocols)
+
+    def test_list_balancers(self):
+        balancers = self.driver.list_balancers()
+
+        self.assertEquals(len(balancers), 1)
+        self.assertEquals(balancers[0].id, 'lba-1235f')
+        self.assertEquals(balancers[0].name, 'lb1')
+
+    def test_get_balancer(self):
+        balancer = self.driver.get_balancer(balancer_id='lba-1235f')
+
+        self.assertEquals(balancer.id, 'lba-1235f')
+        self.assertEquals(balancer.name, 'lb1')
+        self.assertEquals(balancer.state, State.RUNNING)
+
+    def test_destroy_balancer(self):
+        balancer = self.driver.get_balancer(balancer_id='lba-1235f')
+
+        self.assertTrue(self.driver.destroy_balancer(balancer))
+
+    def test_create_balancer(self):
+        members = [Member('srv-lv426', None, None)]
+
+        balancer = self.driver.create_balancer(name='lb2', port=80,
+            protocol='http', algorithm=Algorithm.ROUND_ROBIN, members=members)
+
+        self.assertEquals(balancer.name, 'lb2')
+        self.assertEquals(balancer.port, 80)
+        self.assertEquals(balancer.state, State.PENDING)
+
+    def test_balancer_list_members(self):
+        balancer = self.driver.get_balancer(balancer_id='lba-1235f')
+        members = balancer.list_members()
+
+        self.assertEquals(len(members), 1)
+        self.assertEquals('srv-lv426', members[0].id)
+
+    def test_balancer_attach_member(self):
+        balancer = self.driver.get_balancer(balancer_id='lba-1235f')
+        member = balancer.attach_member(Member('srv-kg983', ip=None,
+                                               port=None))
+
+        self.assertEquals(member.id, 'srv-kg983')
+
+    def test_balancer_detach_member(self):
+        balancer = self.driver.get_balancer(balancer_id='lba-1235f')
+        member = Member('srv-lv426', None, None)
+
+        self.assertTrue(balancer.detach_member(member))
+
+
+class BrightboxLBMockHttp(MockHttpTestCase):
+    fixtures = LoadBalancerFileFixtures('brightbox')
+
+    def _token(self, method, url, body, headers):
+        if method == 'POST':
+            return self.response(httplib.OK, self.fixtures.load('token.json'))
+
+    def _1_0_load_balancers(self, method, url, body, headers):
+        if method == 'GET':
+            return self.response(httplib.OK,
+                                 self.fixtures.load('load_balancers.json'))
+        elif method == 'POST':
+            body = self.fixtures.load('load_balancers_post.json')
+            return self.response(httplib.ACCEPTED, body)
+
+    def _1_0_load_balancers_lba_1235f(self, method, url, body, headers):
+        if method == 'GET':
+            body = self.fixtures.load('load_balancers_lba_1235f.json')
+            return self.response(httplib.OK, body)
+        elif method == 'DELETE':
+            return self.response(httplib.ACCEPTED, '')
+
+    def _1_0_load_balancers_lba_1235f_add_nodes(self, method, url, body,
+                                                headers):
+        if method == 'POST':
+            return self.response(httplib.ACCEPTED, '')
+
+    def _1_0_load_balancers_lba_1235f_remove_nodes(self, method, url, body,
+                                                   headers):
+        if method == 'POST':
+            return self.response(httplib.ACCEPTED, '')
+
+    def response(self, status, body):
+        return (status, body, {'content-type': 'application/json'},
+                httplib.responses[status])
+
+
+if __name__ == "__main__":
+    sys.exit(unittest.main())

Modified: libcloud/trunk/test/secrets.py-dist
URL: 
http://svn.apache.org/viewvc/libcloud/trunk/test/secrets.py-dist?rev=1214063&r1=1214062&r2=1214063&view=diff
==============================================================================
--- libcloud/trunk/test/secrets.py-dist (original)
+++ libcloud/trunk/test/secrets.py-dist Wed Dec 14 06:14:01 2011
@@ -39,6 +39,9 @@ VPSNET_PARAMS = ('user', 'key')
 STORAGE_S3_PARAMS = ('key', 'secret')
 STORAGE_GOOGLE_STORAGE_PARAMS = ('key', 'secret')
 
+# Loadbalancer
+LB_BRIGHTBOX_PARAMS = ('user', 'key')
+
 # DNS
 DNS_PARAMS_LINODE = ('user', 'key')
 DNS_PARAMS_ZERIGO = ('email', 'api token')


Reply via email to