libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rbogorods...@apache.org
Subject svn commit: r1095180 [1/2] - in /incubator/libcloud/trunk: ./ libcloud/common/ libcloud/compute/drivers/ libcloud/resource/ libcloud/resource/lb/ libcloud/resource/lb/drivers/ test/ test/compute/ test/resource/ test/resource/fixtures/ test/resource/fix...
Date Tue, 19 Apr 2011 19:49:29 GMT
Author: rbogorodskiy
Date: Tue Apr 19 19:49:28 2011
New Revision: 1095180

URL: http://svn.apache.org/viewvc?rev=1095180&view=rev
Log:
Import Load Balancers support.

At the moment drivers for two providers are available:
Rackspace and GoGrid. At the moment only basic features
provided by load balancing service are supported, but
they've been tested and should work without problems.

However, there are a lot of work to be done here still,
like adding locations support in a similar fashion as it's
done for compute part, adding blocking mode and refining
implementation in general.

Follow discussion on the maillist to be up-to-date with
these efforts:

http://mail-archives.apache.org/mod_mbox/incubator-libcloud/201104.mbox/<20110404221031.GA26577@reemsky>

Added:
    incubator/libcloud/trunk/example_lb.py
    incubator/libcloud/trunk/libcloud/common/gogrid.py
    incubator/libcloud/trunk/libcloud/resource/
    incubator/libcloud/trunk/libcloud/resource/lb/
    incubator/libcloud/trunk/libcloud/resource/lb/base.py
    incubator/libcloud/trunk/libcloud/resource/lb/drivers/
    incubator/libcloud/trunk/libcloud/resource/lb/drivers/gogrid.py
    incubator/libcloud/trunk/libcloud/resource/lb/drivers/rackspace.py
    incubator/libcloud/trunk/libcloud/resource/lb/providers.py
    incubator/libcloud/trunk/libcloud/resource/lb/types.py
    incubator/libcloud/trunk/test/resource/
    incubator/libcloud/trunk/test/resource/fixtures/
    incubator/libcloud/trunk/test/resource/fixtures/lb/
    incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/
    incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/ip_list.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_add.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_edit.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_get.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_list.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/
    incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes_post.json
    incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_post.json
    incubator/libcloud/trunk/test/resource/lb/
    incubator/libcloud/trunk/test/resource/lb/test_gogrid.py
    incubator/libcloud/trunk/test/resource/lb/test_rackspace.py
Modified:
    incubator/libcloud/trunk/libcloud/common/rackspace.py
    incubator/libcloud/trunk/libcloud/compute/drivers/gogrid.py
    incubator/libcloud/trunk/setup.py
    incubator/libcloud/trunk/test/compute/test_gogrid.py
    incubator/libcloud/trunk/test/file_fixtures.py

Added: incubator/libcloud/trunk/example_lb.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/example_lb.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/example_lb.py (added)
+++ incubator/libcloud/trunk/example_lb.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import os
+import time
+
+from libcloud.resource.lb.base import LB, LBNode
+from libcloud.resource.lb.types import Provider, LBState
+from libcloud.resource.lb.providers import get_driver
+
+def main():
+    Rackspace = get_driver(Provider.RACKSPACE)
+
+    driver = Rackspace('username', 'api key')
+
+    balancers = driver.list_balancers()
+
+    # creating a balancer which balances traffic across two
+    # nodes: 192.168.86.1:80 and 192.168.86.2:8080. Balancer
+    # itself listens on port 80/tcp
+    new_balancer_name = 'testlb' + os.urandom(4).encode('hex')
+    new_balancer = driver.create_balancer(name=new_balancer_name,
+            port=80,
+            nodes=(LBNode(None, '192.168.86.1', 80),
+                LBNode(None, '192.168.86.2', 8080))
+            )
+
+    print new_balancer
+
+    # wait for balancer to become ready
+    # NOTE: in real life code add timeout to not end up in
+    # endless loop when things go wrong on provider side
+    while True:
+        balancer = driver.balancer_detail(balancer=new_balancer)
+
+        if balancer.state == LBState.RUNNING:
+            break
+
+        time.sleep(30)
+
+    # fetch list of nodes
+    nodes = balancer.list_nodes()
+    print nodes
+
+    # remove first node
+    balancer.detach_node(nodes[0])
+
+    # and add another one: 10.0.0.10:1000
+    print balancer.attach_node(ip='10.0.0.10', port='1000')
+
+    # remove the balancer
+    driver.destroy_balancer(new_balancer)
+
+if __name__ == "__main__":
+    main()

Added: incubator/libcloud/trunk/libcloud/common/gogrid.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/common/gogrid.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/common/gogrid.py (added)
+++ incubator/libcloud/trunk/libcloud/common/gogrid.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,178 @@
+# 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 hashlib
+import time
+
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+from libcloud.common.types import InvalidCredsError, LibcloudError
+from libcloud.common.types import MalformedResponseError
+from libcloud.common.base import ConnectionUserAndKey, Response
+from libcloud.compute.base import NodeLocation
+
+HOST = 'api.gogrid.com'
+PORTS_BY_SECURITY = { True: 443, False: 80 }
+API_VERSION = '1.8'
+
+__all__ = ["GoGridResponse",
+        "GoGridConnection",
+        "GoGridIpAddress",
+        "BaseGoGridDriver",
+]
+
+class GoGridResponse(Response):
+
+    def __init__(self, *args, **kwargs):
+       self.driver = BaseGoGridDriver
+       super(GoGridResponse, self).__init__(*args, **kwargs)
+
+    def success(self):
+        if self.status == 403:
+            raise InvalidCredsError('Invalid credentials', self.driver)
+        if self.status == 401:
+            raise InvalidCredsError('API Key has insufficient rights', self.driver)
+        if not self.body:
+            return None
+        try:
+            return json.loads(self.body)['status'] == 'success'
+        except ValueError:
+            raise MalformedResponseError('Malformed reply',
+                    body=self.body, driver=self.driver)
+
+    def parse_body(self):
+        if not self.body:
+            return None
+        return json.loads(self.body)
+
+    def parse_error(self):
+        try:
+            return json.loads(self.body)["list"][0]['message']
+        except (ValueError, KeyError):
+            return None
+
+class GoGridConnection(ConnectionUserAndKey):
+    """
+    Connection class for the GoGrid driver
+    """
+
+    host = HOST
+    responseCls = GoGridResponse
+
+    def add_default_params(self, params):
+        params["api_key"] = self.user_id
+        params["v"] = API_VERSION
+        params["format"] = 'json'
+        params["sig"] = self.get_signature(self.user_id, self.key)
+
+        return params
+
+    def get_signature(self, key, secret):
+        """ create sig from md5 of key + secret + time """
+        m = hashlib.md5(key+secret+str(int(time.time())))
+        return m.hexdigest()
+
+class GoGridIpAddress(object):
+    """
+    IP Address
+    """
+
+    def __init__(self, id, ip, public, state, subnet):
+        self.id = id
+        self.ip = ip
+        self.public = public
+        self.state = state
+        self.subnet = subnet
+
+class BaseGoGridDriver(object):
+    """GoGrid has common object model for services they
+    provide, like locations and IP, so keep handling of
+    these things in a single place."""
+
+    name = "GoGrid"
+
+    def _get_ip(self, element):
+        return element.get('ip').get('ip')
+
+    def _to_ip(self, element):
+        ip = GoGridIpAddress(id=element['id'],
+                ip=element['ip'],
+                public=element['public'],
+                subnet=element['subnet'],
+                state=element["state"]["name"])
+        ip.location = self._to_location(element['datacenter'])
+        return ip
+
+    def _to_ips(self, object):
+        return [ self._to_ip(el)
+                for el in object['list'] ]
+
+    def _to_location(self, element):
+        location = NodeLocation(id=element['id'],
+                name=element['name'],
+                country="US",
+                driver=self.connection.driver)
+        return location
+
+    def _to_locations(self, object):
+        return [self._to_location(el)
+                for el in object['list']]
+
+
+    def ex_list_ips(self, **kwargs):
+        """Return list of IP addresses assigned to
+        the account.
+
+        @keyword    public: set to True to list only
+                    public IPs or False to list only
+                    private IPs. Set to None or not specify
+                    at all not to filter by type
+        @type       public: C{bool}
+        @keyword    assigned: set to True to list only addresses
+                    assigned to servers, False to list unassigned
+                    addresses and set to None or don't set at all
+                    not no filter by state
+        @type       assigned: C{bool}
+        @keyword    location: filter IP addresses by location
+        @type       location: L{NodeLocation}
+        @return:    C{list} of L{GoGridIpAddress}es
+        """
+
+        params = {}
+
+        if "public" in kwargs and kwargs["public"] is not None:
+            params["ip.type"] = {True: "Public",
+                    False: "Private"}[kwargs["public"]]
+        if "assigned" in kwargs and kwargs["assigned"] is not None:
+            params["ip.state"] = {True: "Assigned",
+                    False: "Unassigned"}[kwargs["assigned"]]
+        if "location" in kwargs and kwargs['location'] is not None:
+            params['datacenter'] = kwargs['location'].id
+
+        ips = self._to_ips(
+                self.connection.request('/api/grid/ip/list',
+                    params=params).object)
+        return ips
+
+    def _get_first_ip(self, location=None):
+        ips = self.ex_list_ips(public=True, assigned=False, location=location)
+        try:
+            return ips[0].ip
+        except IndexError:
+            raise LibcloudError('No public unassigned IPs left',
+                    self.driver)

Modified: incubator/libcloud/trunk/libcloud/common/rackspace.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/common/rackspace.py?rev=1095180&r1=1095179&r2=1095180&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/common/rackspace.py (original)
+++ incubator/libcloud/trunk/libcloud/common/rackspace.py Tue Apr 19 19:49:28 2011
@@ -76,6 +76,7 @@ class RackspaceBaseConnection(Connection
                 self.server_url = headers['x-server-management-url']
                 self.storage_url = headers['x-storage-url']
                 self.cdn_management_url = headers['x-cdn-management-url']
+                self.lb_url = self.server_url.replace("servers", "ord.loadbalancers")
                 self.auth_token = headers['x-auth-token']
             except KeyError:
                 raise InvalidCredsError()

Modified: incubator/libcloud/trunk/libcloud/compute/drivers/gogrid.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/compute/drivers/gogrid.py?rev=1095180&r1=1095179&r2=1095180&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/compute/drivers/gogrid.py (original)
+++ incubator/libcloud/trunk/libcloud/compute/drivers/gogrid.py Tue Apr 19 19:49:28 2011
@@ -24,18 +24,13 @@ try:
 except ImportError:
     import simplejson as json
 
-from libcloud.common.base import ConnectionUserAndKey, Response
 from libcloud.common.types import InvalidCredsError, LibcloudError
-from libcloud.common.types import MalformedResponseError
+from libcloud.common.gogrid import GoGridConnection, BaseGoGridDriver
 from libcloud.compute.providers import Provider
 from libcloud.compute.types import NodeState
 from libcloud.compute.base import Node, NodeDriver
 from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
 
-HOST = 'api.gogrid.com'
-PORTS_BY_SECURITY = { True: 443, False: 80 }
-API_VERSION = '1.8'
-
 STATE = {
     "Starting": NodeState.PENDING,
     "On": NodeState.RUNNING,
@@ -75,64 +70,6 @@ GOGRID_INSTANCE_TYPES = {
 }
 
 
-class GoGridResponse(Response):
-
-    def success(self):
-        if self.status == 403:
-            raise InvalidCredsError('Invalid credentials', GoGridNodeDriver)
-        if self.status == 401:
-            raise InvalidCredsError('API Key has insufficient rights', GoGridNodeDriver)
-        if not self.body:
-            return None
-        try:
-            return json.loads(self.body)['status'] == 'success'
-        except ValueError:
-            raise MalformedResponseError('Malformed reply', body=self.body, driver=GoGridNodeDriver)
-
-    def parse_body(self):
-        if not self.body:
-            return None
-        return json.loads(self.body)
-
-    def parse_error(self):
-        try:
-            return json.loads(self.body)["list"][0]['message']
-        except (ValueError, KeyError):
-            return None
-
-class GoGridConnection(ConnectionUserAndKey):
-    """
-    Connection class for the GoGrid driver
-    """
-
-    host = HOST
-    responseCls = GoGridResponse
-
-    def add_default_params(self, params):
-        params["api_key"] = self.user_id
-        params["v"] = API_VERSION
-        params["format"] = 'json'
-        params["sig"] = self.get_signature(self.user_id, self.key)
-
-        return params
-
-    def get_signature(self, key, secret):
-        """ create sig from md5 of key + secret + time """
-        m = hashlib.md5(key+secret+str(int(time.time())))
-        return m.hexdigest()
-
-class GoGridIpAddress(object):
-    """
-    IP Address
-    """
-
-    def __init__(self, id, ip, public, state, subnet):
-        self.id = id
-        self.ip = ip
-        self.public = public
-        self.state = state
-        self.subnet = subnet
-
 class GoGridNode(Node):
     # Generating uuid based on public ip to get around missing id on
     # create_node in gogrid api
@@ -144,7 +81,7 @@ class GoGridNode(Node):
             "%s:%d" % (self.public_ip,self.driver.type)
         ).hexdigest()
 
-class GoGridNodeDriver(NodeDriver):
+class GoGridNodeDriver(BaseGoGridDriver, NodeDriver):
     """
     GoGrid node driver
     """
@@ -203,19 +140,6 @@ class GoGridNodeDriver(NodeDriver):
                 driver=self.connection.driver)
         return location
 
-    def _to_ip(self, element):
-        ip = GoGridIpAddress(id=element['id'],
-                ip=element['ip'],
-                public=element['public'],
-                subnet=element['subnet'],
-                state=element["state"]["name"])
-        ip.location = self._to_location(element['datacenter'])
-        return ip
-
-    def _to_ips(self, object):
-        return [ self._to_ip(el)
-                for el in object['list'] ]
-
     def _to_locations(self, object):
         return [self._to_location(el)
                 for el in object['list']]

Added: incubator/libcloud/trunk/libcloud/resource/lb/base.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/resource/lb/base.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/resource/lb/base.py (added)
+++ incubator/libcloud/trunk/libcloud/resource/lb/base.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,175 @@
+# 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.common.base import ConnectionKey
+
+__all__ = [
+        "LBNode",
+        "LB",
+        "LBDriver",
+        ]
+
+class LBNode(object):
+
+    def __init__(self, id, ip, port):
+        self.id = str(id) if id else None
+        self.ip = ip
+        self.port = port
+
+    def __repr__(self):
+        return ('<LBNode: id=%s, address=%s:%s>' % (self.id,
+            self.ip, self.port))
+
+
+class LB(object):
+    """
+    Provide a common interface for handling Load Balancers.
+    """
+
+    def __init__(self, id, name, state, ip, port, driver):
+        self.id = str(id) if id else None
+        self.name = name
+        self.state = state
+        self.ip = ip
+        self.port = port
+        self.driver = driver
+
+    def attach_node(self, **kwargs):
+        return self.driver.balancer_attach_node(self, **kwargs)
+
+    def detach_node(self, node):
+        return self.driver.balancer_detach_node(self, node)
+
+    def list_nodes(self):
+        return self.driver.balancer_list_nodes(self)
+
+    def __repr__(self):
+        return ('<LB: id=%s, name=%s, state=%s>' % (self.id,
+                self.name, self.state))
+
+
+class LBDriver(object):
+    """
+    A base LBDriver class to derive from
+
+    This class is always subclassed by a specific driver.
+
+    """
+
+    connectionCls = ConnectionKey
+
+    def __init__(self, key, secret=None, secure=True):
+        self.key = key
+        self.secret = secret
+        args = [self.key]
+
+        if self.secret is not None:
+            args.append(self.secret)
+
+        args.append(secure)
+
+        self.connection = self.connectionCls(*args)
+        self.connection.driver = self
+        self.connection.connect()
+
+    def list_balancers(self):
+        """
+        List all loadbalancers
+
+        @return: C{list} of L{LB} objects
+
+        """
+
+        raise NotImplementedError, \
+                'list_balancers not implemented for this driver'
+
+    def create_balancer(self, **kwargs):
+        """
+        Create a new load balancer instance
+
+        @keyword name: Name of the new load balancer (required)
+        @type name: C{str}
+        @keyword port: Port the load balancer should listen on (required)
+        @type port: C{str}
+        @keyword nodes: C{list} of L{LBNode}s to attach to balancer
+        @type: C{list} of L{LBNode}s
+
+        """
+
+        raise NotImplementedError, \
+                'create_balancer not implemented for this driver'
+
+    def destroy_balancer(self, balancer):
+        """Destroy a load balancer
+
+        @return: C{bool} True if the destroy was successful, otherwise False
+
+        """
+
+        raise NotImplementedError, \
+                'destroy_balancer not implemented for this driver'
+
+    def balancer_detail(self, **kwargs):
+        """
+        Returns a detailed info about load balancer given by
+        existing L{LB} object or its id
+
+        @keyword balancer: L{LB} object you already fetched using list method for example
+        @type balancer: L{LB}
+        @keyword balancer_id: id of a load balancer you want to fetch
+        @type balancer_id: C{str}
+
+        @return: L{LB}
+
+        """
+
+        raise NotImplementedError, \
+                'balancer_detail not implemented for this driver'
+
+    def balancer_attach_node(self, balancer, **kwargs):
+        """
+        Attach a node to balancer
+
+        @keyword ip: IP address of a node
+        @type ip: C{str}
+        @keyword port: port that services we're balancing listens on on the node
+        @keyword port: C{str}
+
+        """
+
+        raise NotImplementedError, \
+                'balancer_attach_node not implemented for this driver'
+
+    def balancer_detach_node(self, balancer, node):
+        """
+        Detach node from balancer
+
+        @return: C{bool} True if node detach was successful, otherwise False
+
+        """
+
+        raise NotImplementedError, \
+                'balancer_detach_node not implemented for this driver'
+
+    def balancer_list_nodes(self, balancer):
+        """
+        Return list of nodes attached to balancer
+
+        @return: C{list} of L{LBNode}s
+
+        """
+
+        raise NotImplementedError, \
+                'balancer_list_nodes not implemented for this driver'

Added: incubator/libcloud/trunk/libcloud/resource/lb/drivers/gogrid.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/resource/lb/drivers/gogrid.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/resource/lb/drivers/gogrid.py (added)
+++ incubator/libcloud/trunk/libcloud/resource/lb/drivers/gogrid.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,191 @@
+# 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 os
+import time
+
+try:
+    import json
+except ImportError:
+    import simplejson
+
+from libcloud.resource.lb.base import LB, LBNode, LBDriver
+from libcloud.resource.lb.types import Provider, LBState, LibcloudLBImmutableError
+from libcloud.common.gogrid import GoGridConnection, BaseGoGridDriver
+
+class GoGridLBDriver(BaseGoGridDriver, LBDriver):
+    connectionCls = GoGridConnection
+    type = Provider.RACKSPACE
+    api_name = 'gogrid_lb'
+    name = 'GoGrid LB'
+
+    LB_STATE_MAP = { 'On': LBState.RUNNING,
+                     'Unknown': LBState.UNKNOWN }
+
+    def list_balancers(self):
+        return self._to_balancers(
+                self.connection.request('/api/grid/loadbalancer/list').object)
+
+    def ex_create_balancer_nowait(self, **kwargs):
+        name = kwargs['name']
+        port = kwargs['port']
+        nodes = kwargs['nodes']
+
+        params = {'name': name,
+                'virtualip.ip': self._get_first_ip(),
+                'virtualip.port': port}
+        params.update(self._nodes_to_params(nodes))
+
+        resp = self.connection.request('/api/grid/loadbalancer/add',
+                method='GET',
+                params=params)
+        return self._to_balancers(resp.object)[0]
+
+    def create_balancer(self, **kwargs):
+        balancer = self.ex_create_balancer_nowait(**kwargs)
+
+        timeout = 60 * 20
+        waittime = 0
+        interval = 2 * 15
+
+        if balancer.id is not None:
+            return balancer
+        else:
+            while waittime < timeout:
+                balancers = self.list_balancers()
+
+                for i in balancers:
+                    if i.name == balancer.name and i.id is not None:
+                        return i
+
+                waittime += interval
+                time.sleep(interval)
+
+        raise Exception('Failed to get id')
+
+    def destroy_balancer(self, balancer):
+        try:
+            resp = self.connection.request('/api/grid/loadbalancer/delete',
+                    method='POST', params={'id': balancer.id})
+        except Exception as err:
+            if "Update request for LoadBalancer" in str(err):
+                raise LibcloudLBImmutableError("Cannot delete immutable object",
+                        GoGridLBDriver)
+            else:
+                raise
+
+        return resp.status == 200
+
+    def balancer_detail(self, **kwargs):
+        params = {}
+
+        try:
+            params['name'] = kwargs['balancer_name']
+        except KeyError:
+            try:
+                balancer_id = kwargs['balancer_id']
+            except KeyError:
+                balancer_id = kwargs['balancer'].id
+
+            params['id'] = balancer_id
+
+        resp = self.connection.request('/api/grid/loadbalancer/get',
+                params=params)
+
+        return self._to_balancers(resp.object)[0]
+
+    def balancer_attach_node(self, balancer, **kwargs):
+        ip = kwargs['ip']
+        port = kwargs['port']
+
+        nodes = self.balancer_list_nodes(balancer)
+        nodes.append(LBNode(None, ip, port))
+
+        params = {"id": balancer.id}
+
+        params.update(self._nodes_to_params(nodes))
+
+        resp = self._update_node(params)
+
+        return [ node for node in
+                self._to_nodes(resp.object["list"][0]["realiplist"])
+                if node.ip == ip ][0]
+
+    def balancer_detach_node(self, balancer, node):
+        nodes = self.balancer_list_nodes(balancer)
+
+        remaining_nodes = [n for n in nodes if n.id != node.id]
+
+        params = {"id": balancer.id}
+        params.update(self._nodes_to_params(remaining_nodes))
+
+        resp = self._update_node(params)
+
+        return resp.status == 200
+
+    def balancer_list_nodes(self, balancer):
+        resp = self.connection.request('/api/grid/loadbalancer/get',
+                params={'id': balancer.id})
+        return self._to_nodes(resp.object["list"][0]["realiplist"])
+
+    def _update_node(self, params):
+        try:
+            return self.connection.request('/api/grid/loadbalancer/edit',
+                    method='POST',
+                    params=params)
+        except Exception as err:
+            if "Update already pending" in str(err):
+                raise LibcloudLBImmutableError("Balancer is immutable", GoGridLBDriver)
+
+        return None
+
+    def _nodes_to_params(self, nodes):
+        """
+        Helper method to convert list of L{LBNode} objects
+        to GET params.
+
+        """
+
+        params = {}
+
+        i = 0
+        for node in nodes:
+            params["realiplist.%s.ip" % i] = node.ip
+            params["realiplist.%s.port" % i] = node.port
+            i += 1
+
+        return params
+
+    def _to_balancers(self, object):
+        return [ self._to_balancer(el) for el in object["list"] ]
+
+    def _to_balancer(self, el):
+        lb = LB(id=el.get("id"),
+                name=el["name"],
+                state=self.LB_STATE_MAP.get(
+                    el["state"]["name"], LBState.UNKNOWN),
+                ip=el["virtualip"]["ip"]["ip"],
+                port=el["virtualip"]["port"],
+                driver=self.connection.driver)
+        return lb
+
+    def _to_nodes(self, object):
+        return [ self._to_node(el) for el in object ]
+
+    def _to_node(self, el):
+        lbnode = LBNode(id=el["ip"]["id"],
+                ip=el["ip"]["ip"],
+                port=el["port"])
+        return lbnode

Added: incubator/libcloud/trunk/libcloud/resource/lb/drivers/rackspace.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/resource/lb/drivers/rackspace.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/resource/lb/drivers/rackspace.py (added)
+++ incubator/libcloud/trunk/libcloud/resource/lb/drivers/rackspace.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,163 @@
+# 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 os
+
+try:
+    import json
+except ImportError:
+    import simplejson
+
+from libcloud.common.base import Response
+from libcloud.resource.lb.base import LB, LBNode, LBDriver
+from libcloud.resource.lb.types import Provider, LBState
+from libcloud.common.rackspace import (AUTH_HOST_US,
+        RackspaceBaseConnection)
+
+class RackspaceResponse(Response):
+
+    def success(self):
+        return 200 <= int(self.status) <= 299
+
+    def parse_body(self):
+        if not self.body:
+            return None
+        else:
+            return json.loads(self.body)
+
+class RackspaceConnection(RackspaceBaseConnection):
+    responseCls = RackspaceResponse
+    auth_host = AUTH_HOST_US
+    _url_key = "lb_url"
+
+    def __init__(self, user_id, key, secure=True):
+        super(RackspaceConnection, self).__init__(user_id, key, secure)
+        self.api_version = 'v1.0'
+        self.accept_format = 'application/json'
+
+    def request(self, action, params=None, data='', headers=None, method='GET'):
+        if not headers:
+            headers = {}
+        if not params:
+            params = {}
+        if self.lb_url:
+            action = self.lb_url + action
+        if method in ('POST', 'PUT'):
+            headers['Content-Type'] = 'application/json'
+        if method == 'GET':
+            params['cache-busing'] = os.urandom(8).encode('hex')
+
+        return super(RackspaceConnection, self).request(action=action,
+                params=params, data=data, method=method, headers=headers)
+
+
+class RackspaceLBDriver(LBDriver):
+    connectionCls = RackspaceConnection
+    type = Provider.RACKSPACE
+    api_name = 'rackspace_lb'
+    name = 'Rackspace LB'
+
+    LB_STATE_MAP = { 'ACTIVE': LBState.RUNNING,
+                     'BUILD': LBState.PENDING }
+
+    def list_balancers(self):
+        return self._to_balancers(
+                self.connection.request('/loadbalancers').object)
+
+    def create_balancer(self, **kwargs):
+        name = kwargs['name']
+        port = kwargs['port']
+        nodes = kwargs['nodes']
+
+        balancer_object = {"loadBalancer":
+                {"name": name,
+                    "port": port,
+                    "protocol": "HTTP",
+                    "virtualIps": [{"type": "PUBLIC"}],
+                    "nodes": [{"address": node.ip,
+                        "port": node.port,
+                        "condition": "ENABLED"} for node in nodes],
+                    }
+                }
+
+        resp = self.connection.request('/loadbalancers',
+                method='POST',
+                data=json.dumps(balancer_object))
+        return self._to_balancer(resp.object["loadBalancer"])
+
+    def destroy_balancer(self, balancer):
+        uri = '/loadbalancers/%s' % (balancer.id)
+        resp = self.connection.request(uri, method='DELETE')
+
+        return resp.status == 202
+
+    def balancer_detail(self, **kwargs):
+        try:
+            balancer_id = kwargs['balancer_id']
+        except KeyError:
+            balancer_id = kwargs['balancer'].id
+
+        uri = '/loadbalancers/%s' % (balancer_id)
+        resp = self.connection.request(uri)
+
+        return self._to_balancer(resp.object["loadBalancer"])
+
+    def balancer_attach_node(self, balancer, **kwargs):
+        ip = kwargs['ip']
+        port = kwargs['port']
+
+        node_object = {"nodes":
+                [{"port": port,
+                    "address": ip,
+                    "condition": "ENABLED"}]
+                }
+
+        uri = '/loadbalancers/%s/nodes' % (balancer.id)
+        resp = self.connection.request(uri, method='POST',
+                data=json.dumps(node_object))
+        return self._to_nodes(resp.object)[0]
+
+    def balancer_detach_node(self, balancer, node):
+        uri = '/loadbalancers/%s/nodes/%s' % (balancer.id, node.id)
+        resp = self.connection.request(uri, method='DELETE')
+
+        return resp.status == 202
+
+    def balancer_list_nodes(self, balancer):
+        uri = '/loadbalancers/%s/nodes' % (balancer.id)
+        return self._to_nodes(
+                self.connection.request(uri).object)
+
+    def _to_balancers(self, object):
+        return [ self._to_balancer(el) for el in object["loadBalancers"] ]
+
+    def _to_balancer(self, el):
+        lb = LB(id=el["id"],
+                name=el["name"],
+                state=self.LB_STATE_MAP.get(
+                    el["status"], LBState.UNKNOWN),
+                ip=el["virtualIps"][0]["address"],
+                port=el["port"],
+                driver=self.connection.driver)
+        return lb
+
+    def _to_nodes(self, object):
+        return [ self._to_node(el) for el in object["nodes"] ]
+
+    def _to_node(self, el):
+        lbnode = LBNode(id=el["id"],
+                ip=el["address"],
+                port=el["port"])
+        return lbnode

Added: incubator/libcloud/trunk/libcloud/resource/lb/providers.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/resource/lb/providers.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/resource/lb/providers.py (added)
+++ incubator/libcloud/trunk/libcloud/resource/lb/providers.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,33 @@
+# 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 import get_driver as get_provider_driver
+from libcloud.resource.lb.types import Provider
+
+__all__ = [
+        "Provider",
+        "DRIVERS",
+        "get_driver",
+        ]
+
+DRIVERS = {
+        Provider.RACKSPACE:
+            ('libcloud.resource.lb.drivers.rackspace', 'RackspaceLBDriver'),
+        Provider.GOGRID:
+            ('libcloud.resource.lb.drivers.gogrid', 'GoGridLBDriver'),
+}
+
+def get_driver(provider):
+    return get_provider_driver(DRIVERS, provider)

Added: incubator/libcloud/trunk/libcloud/resource/lb/types.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/resource/lb/types.py?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/resource/lb/types.py (added)
+++ incubator/libcloud/trunk/libcloud/resource/lb/types.py Tue Apr 19 19:49:28 2011
@@ -0,0 +1,43 @@
+# 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.
+
+__all__ = [
+        "Provider",
+        "LBState",
+        "LibcloudLBError",
+        "LibcloudLBImmutableError",
+        ]
+
+from libcloud.common.types import LibcloudError
+
+class LibcloudLBError(LibcloudError): pass
+
+class LibcloudLBImmutableError(LibcloudLBError): pass
+
+class Provider(object):
+    RACKSPACE = 0
+    GOGRID = 1
+
+class LBState(object):
+    """
+    Standart states for a loadbalancer
+
+    @cvar RUNNING: loadbalancer is running and ready to use
+    @cvar UNKNOWN: loabalancer state is unknown
+    """
+
+    RUNNING = 0
+    PENDING = 1
+    UNKNOWN = 2

Modified: incubator/libcloud/trunk/setup.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/setup.py?rev=1095180&r1=1095179&r2=1095180&view=diff
==============================================================================
--- incubator/libcloud/trunk/setup.py (original)
+++ incubator/libcloud/trunk/setup.py Tue Apr 19 19:49:28 2011
@@ -150,6 +150,9 @@ setup(
         'libcloud.compute',
         'libcloud.compute.drivers',
         'libcloud.drivers',
+        'libcloud.resource',
+        'libcloud.resource.lb',
+        'libcloud.resource.lb.drivers',
     ],
     package_dir={
         'libcloud': 'libcloud',

Modified: incubator/libcloud/trunk/test/compute/test_gogrid.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_gogrid.py?rev=1095180&r1=1095179&r2=1095180&view=diff
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_gogrid.py (original)
+++ incubator/libcloud/trunk/test/compute/test_gogrid.py Tue Apr 19 19:49:28 2011
@@ -19,7 +19,8 @@ import urlparse
 
 from libcloud.compute.base import NodeState, NodeLocation
 from libcloud.common.types import LibcloudError, InvalidCredsError
-from libcloud.compute.drivers.gogrid import GoGridNodeDriver, GoGridIpAddress
+from libcloud.common.gogrid import GoGridIpAddress
+from libcloud.compute.drivers.gogrid import GoGridNodeDriver
 from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
 
 from test import MockHttp               # pylint: disable-msg=E0611

Modified: incubator/libcloud/trunk/test/file_fixtures.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/file_fixtures.py?rev=1095180&r1=1095179&r2=1095180&view=diff
==============================================================================
--- incubator/libcloud/trunk/test/file_fixtures.py (original)
+++ incubator/libcloud/trunk/test/file_fixtures.py Tue Apr 19 19:49:28 2011
@@ -19,13 +19,14 @@ import os
 
 FIXTURES_ROOT = {
     'compute': 'compute/fixtures',
-    'storage': 'storage/fixtures'
+    'storage': 'storage/fixtures',
+    'resource': 'resource/fixtures',
 }
 
 class FileFixtures(object):
     def __init__(self, fixtures_type, sub_dir=''):
         script_dir = os.path.abspath(os.path.split(__file__)[0])
-        self.root = os.path.join(script_dir, FIXTURES_ROOT[fixtures_type], 
+        self.root = os.path.join(script_dir, FIXTURES_ROOT[fixtures_type],
                                  sub_dir)
 
     def load(self, file):
@@ -33,7 +34,7 @@ class FileFixtures(object):
         if os.path.exists(path):
             return open(path, 'r').read()
         else:
-            raise IOError
+            raise IOError(path)
 
 class ComputeFileFixtures(FileFixtures):
     def __init__(self, sub_dir=''):
@@ -44,3 +45,8 @@ class StorageFileFixtures(FileFixtures):
     def __init__(self, sub_dir=''):
         super(StorageFileFixtures, self).__init__(fixtures_type='storage',
                                                   sub_dir=sub_dir)
+
+class ResourceFileFixtures(FileFixtures):
+    def __init__(self, sub_dir=''):
+        super(ResourceFileFixtures, self).__init__(fixtures_type='resource',
+                                                  sub_dir=sub_dir)

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/ip_list.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/ip_list.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/ip_list.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/ip_list.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,316 @@
+{
+    "list": [
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868101, 
+            "ip": "10.0.0.68", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868102, 
+            "ip": "10.0.0.69", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868106, 
+            "ip": "10.0.0.73", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868107, 
+            "ip": "10.0.0.74", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868108, 
+            "ip": "10.0.0.75", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868109, 
+            "ip": "10.0.0.76", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868110, 
+            "ip": "10.0.0.77", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 1868111, 
+            "ip": "10.0.0.78", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.64/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277337, 
+            "ip": "10.0.0.244", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277338, 
+            "ip": "10.0.0.245", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277342, 
+            "ip": "10.0.0.249", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277343, 
+            "ip": "10.0.0.250", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277344, 
+            "ip": "10.0.0.251", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277345, 
+            "ip": "10.0.0.252", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277346, 
+            "ip": "10.0.0.253", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }, 
+        {
+            "datacenter": {
+                "description": "US East 1 Datacenter", 
+                "id": 2, 
+                "name": "US-East-1", 
+                "object": "option"
+            }, 
+            "id": 2277347, 
+            "ip": "10.0.0.254", 
+            "object": "ip", 
+            "public": true, 
+            "state": {
+                "description": "IP is available to use", 
+                "id": 1, 
+                "name": "Unassigned", 
+                "object": "option"
+            }, 
+            "subnet": "10.0.0.240/255.255.255.240"
+        }
+    ], 
+    "method": "/grid/ip/list", 
+    "status": "success", 
+    "summary": {
+        "numpages": 0, 
+        "returned": 16, 
+        "start": 0, 
+        "total": 16
+    }
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_add.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_add.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_add.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_add.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,141 @@
+{
+    "list": [
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "name": "test2", 
+            "id": 123,
+            "object": "loadbalancer", 
+            "os": {
+                "description": "The F5 Load Balancer.", 
+                "id": 1, 
+                "name": "F5", 
+                "object": "option"
+            }, 
+            "persistence": {
+                "description": "", 
+                "id": 1, 
+                "name": "None", 
+                "object": "option"
+            }, 
+            "realiplist": [
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868109, 
+                        "ip": "10.1.0.10", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.1.0.10/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868110, 
+                        "ip": "10.1.0.11", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.1.0.11/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868111, 
+                        "ip": "10.1.0.12", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.1.0.12/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }
+            ], 
+            "state": {
+                "description": "Loadbalancer is enabled and on.", 
+                "id": 1, 
+                "name": "On", 
+                "object": "option"
+            }, 
+            "type": {
+                "description": "", 
+                "id": 1, 
+                "name": "Round Robin", 
+                "object": "option"
+            }, 
+            "virtualip": {
+                "ip": {
+                    "datacenter": {
+                        "description": "US West 1 Datacenter", 
+                        "id": 1, 
+                        "name": "US-West-1", 
+                        "object": "option"
+                    }, 
+                    "id": 1868101, 
+                    "ip": "1.1.1.1", 
+                    "object": "ip", 
+                    "public": true, 
+                    "state": {
+                        "description": "IP is reserved or in use", 
+                        "id": 2, 
+                        "name": "Assigned", 
+                        "object": "option"
+                    }, 
+                    "subnet": "1.1.1.1/255.255.255.240"
+                }, 
+                "object": "ipportpair", 
+                "port": 80
+            }
+        }
+    ], 
+    "method": "/grid/loadbalancer/add", 
+    "status": "success", 
+    "summary": {
+        "numpages": 0, 
+        "returned": 1, 
+        "start": 0, 
+        "total": 1
+    }
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_edit.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_edit.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_edit.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_edit.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,164 @@
+{
+    "list": [
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 23530, 
+            "name": "test2", 
+            "object": "loadbalancer", 
+            "os": {
+                "description": "The F5 Load Balancer.", 
+                "id": 1, 
+                "name": "F5", 
+                "object": "option"
+            }, 
+            "persistence": {
+                "description": "", 
+                "id": 1, 
+                "name": "None", 
+                "object": "option"
+            }, 
+            "realiplist": [
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868108, 
+                        "ip": "10.0.0.75", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868109, 
+                        "ip": "10.0.0.76", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868110, 
+                        "ip": "10.0.0.77", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868111, 
+                        "ip": "10.0.0.78", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }
+            ], 
+            "state": {
+                "description": "Loadbalancer is enabled and on.", 
+                "id": 1, 
+                "name": "On", 
+                "object": "option"
+            }, 
+            "type": {
+                "description": "", 
+                "id": 1, 
+                "name": "Round Robin", 
+                "object": "option"
+            }, 
+            "virtualip": {
+                "ip": {
+                    "datacenter": {
+                        "description": "US West 1 Datacenter", 
+                        "id": 1, 
+                        "name": "US-West-1", 
+                        "object": "option"
+                    }, 
+                    "id": 1868101, 
+                    "ip": "10.0.0.68", 
+                    "object": "ip", 
+                    "public": true, 
+                    "state": {
+                        "description": "IP is reserved or in use", 
+                        "id": 2, 
+                        "name": "Assigned", 
+                        "object": "option"
+                    }, 
+                    "subnet": "10.0.0.64/255.255.255.240"
+                }, 
+                "object": "ipportpair", 
+                "port": 80
+            }
+        }
+    ], 
+    "method": "/grid/loadbalancer/edit", 
+    "status": "success", 
+    "summary": {
+        "numpages": 0, 
+        "returned": 1, 
+        "start": 0, 
+        "total": 1
+    }
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_get.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_get.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_get.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_get.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,141 @@
+{
+    "list": [
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 23530, 
+            "name": "test2", 
+            "object": "loadbalancer", 
+            "os": {
+                "description": "The F5 Load Balancer.", 
+                "id": 1, 
+                "name": "F5", 
+                "object": "option"
+            }, 
+            "persistence": {
+                "description": "", 
+                "id": 1, 
+                "name": "None", 
+                "object": "option"
+            }, 
+            "realiplist": [
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868109, 
+                        "ip": "10.0.0.76", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868110, 
+                        "ip": "10.0.0.77", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868111, 
+                        "ip": "10.0.0.78", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }
+            ], 
+            "state": {
+                "description": "Loadbalancer is enabled and on.", 
+                "id": 1, 
+                "name": "On", 
+                "object": "option"
+            }, 
+            "type": {
+                "description": "", 
+                "id": 1, 
+                "name": "Round Robin", 
+                "object": "option"
+            }, 
+            "virtualip": {
+                "ip": {
+                    "datacenter": {
+                        "description": "US West 1 Datacenter", 
+                        "id": 1, 
+                        "name": "US-West-1", 
+                        "object": "option"
+                    }, 
+                    "id": 1868101, 
+                    "ip": "10.0.0.68", 
+                    "object": "ip", 
+                    "public": true, 
+                    "state": {
+                        "description": "IP is reserved or in use", 
+                        "id": 2, 
+                        "name": "Assigned", 
+                        "object": "option"
+                    }, 
+                    "subnet": "10.0.0.64/255.255.255.240"
+                }, 
+                "object": "ipportpair", 
+                "port": 80
+            }
+        }
+    ], 
+    "method": "/grid/loadbalancer/get", 
+    "status": "success", 
+    "summary": {
+        "numpages": 0, 
+        "returned": 1, 
+        "start": 0, 
+        "total": 1
+    }
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_list.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_list.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_list.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/gogrid/loadbalancer_list.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,224 @@
+{
+    "list": [
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 23517, 
+            "name": "foo", 
+            "object": "loadbalancer", 
+            "os": {
+                "description": "The F5 Load Balancer.", 
+                "id": 1, 
+                "name": "F5", 
+                "object": "option"
+            }, 
+            "persistence": {
+                "description": "", 
+                "id": 1, 
+                "name": "None", 
+                "object": "option"
+            }, 
+            "realiplist": [
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868111, 
+                        "ip": "10.0.0.78", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }
+            ], 
+            "state": {
+                "description": "Loadbalancer is enabled and on.", 
+                "id": 1, 
+                "name": "On", 
+                "object": "option"
+            }, 
+            "type": {
+                "description": "", 
+                "id": 1, 
+                "name": "Round Robin", 
+                "object": "option"
+            }, 
+            "virtualip": {
+                "ip": {
+                    "datacenter": {
+                        "description": "US West 1 Datacenter", 
+                        "id": 1, 
+                        "name": "US-West-1", 
+                        "object": "option"
+                    }, 
+                    "id": 1868099, 
+                    "ip": "10.0.0.66", 
+                    "object": "ip", 
+                    "public": true, 
+                    "state": {
+                        "description": "IP is reserved or in use", 
+                        "id": 2, 
+                        "name": "Assigned", 
+                        "object": "option"
+                    }, 
+                    "subnet": "10.0.0.64/255.255.255.240"
+                }, 
+                "object": "ipportpair", 
+                "port": 80
+            }
+        }, 
+        {
+            "datacenter": {
+                "description": "US West 1 Datacenter", 
+                "id": 1, 
+                "name": "US-West-1", 
+                "object": "option"
+            }, 
+            "id": 23526, 
+            "name": "bar", 
+            "object": "loadbalancer", 
+            "os": {
+                "description": "The F5 Load Balancer.", 
+                "id": 1, 
+                "name": "F5", 
+                "object": "option"
+            }, 
+            "persistence": {
+                "description": "", 
+                "id": 1, 
+                "name": "None", 
+                "object": "option"
+            }, 
+            "realiplist": [
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868109, 
+                        "ip": "10.0.0.76", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868110, 
+                        "ip": "10.0.0.77", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }, 
+                {
+                    "ip": {
+                        "datacenter": {
+                            "description": "US West 1 Datacenter", 
+                            "id": 1, 
+                            "name": "US-West-1", 
+                            "object": "option"
+                        }, 
+                        "id": 1868111, 
+                        "ip": "10.0.0.78", 
+                        "object": "ip", 
+                        "public": true, 
+                        "state": {
+                            "description": "IP is available to use", 
+                            "id": 1, 
+                            "name": "Unassigned", 
+                            "object": "option"
+                        }, 
+                        "subnet": "10.0.0.64/255.255.255.240"
+                    }, 
+                    "object": "ipportpair", 
+                    "port": 80
+                }
+            ], 
+            "state": {
+                "description": "Loadbalancer is enabled and on.", 
+                "id": 1, 
+                "name": "On", 
+                "object": "option"
+            }, 
+            "type": {
+                "description": "", 
+                "id": 1, 
+                "name": "Round Robin", 
+                "object": "option"
+            }, 
+            "virtualip": {
+                "ip": {
+                    "datacenter": {
+                        "description": "US West 1 Datacenter", 
+                        "id": 1, 
+                        "name": "US-West-1", 
+                        "object": "option"
+                    }, 
+                    "id": 1868100, 
+                    "ip": "10.0.0.67", 
+                    "object": "ip", 
+                    "public": true, 
+                    "state": {
+                        "description": "IP is reserved or in use", 
+                        "id": 2, 
+                        "name": "Assigned", 
+                        "object": "option"
+                    }, 
+                    "subnet": "10.0.0.64/255.255.255.240"
+                }, 
+                "object": "ipportpair", 
+                "port": 80
+            }
+        }
+    ], 
+    "method": "/grid/loadbalancer/list", 
+    "status": "success", 
+    "summary": {
+        "numpages": 0, 
+        "returned": 2, 
+        "start": 0, 
+        "total": 2
+    }
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,48 @@
+{
+    "loadBalancers": [
+        {
+            "algorithm": "RANDOM", 
+            "created": {
+                "time": "2011-04-06T21:25:19+0000"
+            }, 
+            "id": 8155, 
+            "name": "test0", 
+            "port": 80, 
+            "protocol": "HTTP", 
+            "status": "ACTIVE", 
+            "updated": {
+                "time": "2011-04-06T21:25:31+0000"
+            }, 
+            "virtualIps": [
+                {
+                    "address": "1.1.1.25", 
+                    "id": 965, 
+                    "ipVersion": "IPV4", 
+                    "type": "PUBLIC"
+                }
+            ]
+        }, 
+        {
+            "algorithm": "RANDOM", 
+            "created": {
+                "time": "2011-04-06T21:26:22+0000"
+            }, 
+            "id": 8156, 
+            "name": "test1", 
+            "port": 80, 
+            "protocol": "HTTP", 
+            "status": "ACTIVE", 
+            "updated": {
+                "time": "2011-04-06T21:26:33+0000"
+            }, 
+            "virtualIps": [
+                {
+                    "address": "1.1.1.83", 
+                    "id": 1279, 
+                    "ipVersion": "IPV4", 
+                    "type": "PUBLIC"
+                }
+            ]
+        }
+    ]
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,46 @@
+{
+    "loadBalancer": {
+        "algorithm": "RANDOM", 
+        "cluster": {
+            "name": "ztm-n05.lbaas.ord1.rackspace.net"
+        }, 
+        "connectionLogging": {
+            "enabled": false
+        }, 
+        "created": {
+            "time": "2011-04-07T16:27:50Z"
+        }, 
+        "id": 8290, 
+        "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": 80, 
+        "protocol": "HTTP", 
+        "status": "ACTIVE", 
+        "updated": {
+            "time": "2011-04-07T16:28:12Z"
+        }, 
+        "virtualIps": [
+            {
+                "address": "1.1.1.1", 
+                "id": 1151, 
+                "ipVersion": "IPV4", 
+                "type": "PUBLIC"
+            }
+        ]
+    }
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,18 @@
+{
+    "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"
+        }
+    ]
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes_post.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes_post.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes_post.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_8290_nodes_post.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,12 @@
+{
+    "nodes": [
+        {
+            "address": "10.1.0.12", 
+            "condition": "ENABLED", 
+            "id": 30972, 
+            "port": 80, 
+            "status": "ONLINE", 
+            "weight": 1
+        }
+    ]
+}

Added: incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_post.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_post.json?rev=1095180&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_post.json (added)
+++ incubator/libcloud/trunk/test/resource/fixtures/lb/rackspace/v1_slug_loadbalancers_post.json Tue Apr 19 19:49:28 2011
@@ -0,0 +1,48 @@
+{
+    "loadBalancer": {
+        "algorithm": "RANDOM", 
+        "cluster": {
+            "name": "ztm-n05.lbaas.ord1.rackspace.net"
+        }, 
+        "connectionLogging": {
+            "enabled": false
+        }, 
+        "created": {
+            "time": "2011-04-07T16:27:50+0000"
+        }, 
+        "id": 8290, 
+        "name": "test2", 
+        "nodes": [
+            {
+                "address": "10.1.0.11", 
+                "condition": "ENABLED", 
+                "id": 30944, 
+                "port": 80, 
+                "status": "ONLINE", 
+                "weight": 1
+            }, 
+            {
+                "address": "10.1.0.10", 
+                "condition": "ENABLED", 
+                "id": 30945, 
+                "port": 80, 
+                "status": "ONLINE", 
+                "weight": 1
+            }
+        ], 
+        "port": 80, 
+        "protocol": "HTTP", 
+        "status": "BUILD", 
+        "updated": {
+            "time": "2011-04-07T16:27:50+0000"
+        }, 
+        "virtualIps": [
+            {
+                "address": "1.1.1.1", 
+                "id": 1151, 
+                "ipVersion": "IPV4", 
+                "type": "PUBLIC"
+            }
+        ]
+    }
+}



Mime
View raw message