You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2012/11/07 21:23:18 UTC

svn commit: r1406792 - in /libcloud/trunk: ./ libcloud/compute/ libcloud/compute/drivers/ libcloud/test/ libcloud/test/compute/ libcloud/test/compute/fixtures/hostvirtual/

Author: tomaz
Date: Wed Nov  7 20:23:17 2012
New Revision: 1406792

URL: http://svn.apache.org/viewvc?rev=1406792&view=rev
Log:
Add a new compute driver for HostVirtual (http://www.vr.org). Contributed by
Dinesh Bhoopathy, part of LIBCLOUD-249.

Added:
    libcloud/trunk/libcloud/compute/drivers/hostvirtual.py
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/create_node.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_images.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_locations.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_destroy.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_reboot.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_start.json
    libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_stop.json
    libcloud/trunk/libcloud/test/compute/test_hostvirtual.py
Modified:
    libcloud/trunk/CHANGES
    libcloud/trunk/libcloud/compute/drivers/__init__.py
    libcloud/trunk/libcloud/compute/providers.py
    libcloud/trunk/libcloud/compute/types.py
    libcloud/trunk/libcloud/test/secrets.py-dist

Modified: libcloud/trunk/CHANGES
URL: http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1406792&r1=1406791&r2=1406792&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Wed Nov  7 20:23:17 2012
@@ -40,6 +40,9 @@ Changes with Apache Libcloud in developm
      the code to make it easier to maintain.
      [Tomaz Muraus]
 
+   - Add a new driver for HostVirtual (http://www.vr.org) provider.
+     [Dinesh Bhoopathy]
+
   *) Storage
 
     - Add a new local storage driver.

Modified: libcloud/trunk/libcloud/compute/drivers/__init__.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/__init__.py?rev=1406792&r1=1406791&r2=1406792&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/__init__.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/__init__.py Wed Nov  7 20:23:17 2012
@@ -27,6 +27,7 @@ __all__ = [
     'elastichosts',
     'cloudsigma',
     'gogrid',
+    'hostvirtual',
     'ibm_sce',
     'linode',
     'opennebula',

Added: libcloud/trunk/libcloud/compute/drivers/hostvirtual.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/hostvirtual.py?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/hostvirtual.py (added)
+++ libcloud/trunk/libcloud/compute/drivers/hostvirtual.py Wed Nov  7 20:23:17 2012
@@ -0,0 +1,250 @@
+# 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.
+
+"""
+libcloud driver for the Host Virtual Inc. (VR) API
+Home page http://www.vr.org/
+"""
+
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+
+from libcloud.utils.py3 import httplib
+
+from libcloud.common.types import LibcloudError
+from libcloud.compute.providers import Provider
+from libcloud.common.base import ConnectionKey, JsonResponse
+from libcloud.compute.types import NodeState, InvalidCredsError
+from libcloud.compute.base import Node, NodeDriver
+from libcloud.compute.base import NodeImage, NodeSize, NodeLocation
+from libcloud.compute.base import NodeAuthSSHKey, NodeAuthPassword
+
+API_HOST = 'www.vr.org'
+API_ROOT = '/vapi'
+
+#API_VERSION = '0.1'
+NODE_STATE_MAP = {
+    'BUILDING': NodeState.PENDING,
+    'PENDING': NodeState.PENDING,
+    'RUNNING': NodeState.RUNNING,  # server is powered up
+    'STOPPING': NodeState.REBOOTING,
+    'REBOOTING': NodeState.REBOOTING,
+    'STARTING': NodeState.REBOOTING,
+    'TERMINATED': NodeState.TERMINATED  # server is powered down
+}
+
+
+class HostVirtualException(LibcloudError):
+    def __init__(self, code, message):
+        self.code = code
+        self.message = message
+        self.args = (code, message)
+
+    def __str__(self):
+        return self.__repr__()
+
+    def __repr__(self):
+        return "<HostVirtualException in %d : %s>" % (self.code, self.message)
+
+
+class HostVirtualResponse(JsonResponse):
+    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
+                            httplib.NO_CONTENT]
+
+    def parse_body(self):
+        if not self.body:
+            return None
+
+        data = json.loads(self.body)
+        return data
+
+    def parse_error(self):
+        if self.status == 401:
+            data = self.parse_body()
+            raise InvalidCredsError(
+                data['error']['code'] + ': ' + data['error']['message'])
+        elif self.status == 412:
+            data = self.parse_body()
+            raise HostVirtualException(
+                data['error']['code'], data['error']['message'])
+        elif self.status == 404:
+            data = self.parse_body()
+            raise HostVirtualException(
+                data['error']['code'], data['error']['message'])
+        else:
+            return self.body
+
+    def success(self):
+        return self.status in self.valid_response_codes
+
+
+class HostVirtualConnection(ConnectionKey):
+    host = API_HOST
+    responseCls = HostVirtualResponse
+
+    def add_default_params(self, params):
+        params["key"] = self.key
+        return params
+
+
+class HostVirtualNodeDriver(NodeDriver):
+    type = Provider.HOSTVIRTUAL
+    name = 'HostVirtual'
+    website = 'http://www.vr.org'
+    connectionCls = HostVirtualConnection
+
+    def __init__(self, key):
+        self.location = None
+        NodeDriver.__init__(self, key)
+
+    def _to_node(self, data):
+        state = NODE_STATE_MAP[data['status']]
+        public_ips = []
+        private_ips = []
+        extra = {}
+
+        public_ips.append(data['ip'])
+
+        node = Node(id=data['mbpkgid'], name=data['fqdn'], state=state,
+                    public_ips=public_ips, private_ips=private_ips,
+                    driver=self.connection.driver, extra=extra)
+        return node
+
+    def list_locations(self):
+        result = self.connection.request(API_ROOT + '/cloud/locations/').object
+        locations = []
+        for dc in result:
+            locations.append(NodeLocation(
+                dc["id"],
+                dc["name"],
+                dc["name"].split(',')[1].replace(" ", ""),  # country
+                self))
+        return locations
+
+    def list_sizes(self, location=None):
+        params = {}
+        if location:
+            params = {'location': location.id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/sizes/',
+            data=json.dumps(params)).object
+        sizes = []
+        for size in result:
+            n = NodeSize(id=size['plan'],
+                         name=size['plan'],
+                         ram=size['ram'],
+                         disk=size['disk'],
+                         bandwidth=size['transfer'],
+                         price=size['price'],
+                         driver=self.connection.driver)
+            sizes.append(n)
+        return sizes
+
+    def list_images(self):
+        result = self.connection.request(API_ROOT + '/cloud/images/').object
+        images = []
+        for image in result:
+            i = NodeImage(id=image["id"],
+                          name=image["os"],
+                          driver=self.connection.driver,
+                          extra={
+                              'hypervisor': image['tech'],
+                              'arch': image['bits']})
+            images.append(i)
+        return images
+
+    def list_nodes(self):
+        result = self.connection.request(API_ROOT + '/cloud/servers/').object
+        nodes = []
+        for value in result:
+            node = self._to_node(value)
+            nodes.append(node)
+        return nodes
+
+    def create_node(self, **kwargs):
+        name = kwargs['name']  # expects fqdn ex: test.com
+        size = kwargs['size']
+        image = kwargs['image']
+        auth = kwargs['auth']
+        dc = None
+
+        if "location" in kwargs:
+            dc = kwargs["location"].id
+        else:
+            dc = '3'
+
+        params = {'fqdn': name,
+                  'plan': size.id,
+                  'image': image.id,
+                  'location': dc
+                  }
+
+        ssh_key = None
+        password = None
+        if isinstance(auth, NodeAuthSSHKey):
+            ssh_key = auth.pubkey
+            params['ssh_key'] = ssh_key
+        elif isinstance(auth, NodeAuthPassword):
+            password = auth.password
+            params['password'] = password
+
+        if not ssh_key and not password:
+            raise HostVirtualException(500, "Need SSH key or root password")
+
+        if password is None:
+            raise HostVirtualException(500, "Root password cannot be empty")
+
+        result = self.connection.request(API_ROOT + '/cloud/buy_build',
+                                         data=json.dumps(params),
+                                         method='POST').object
+        return self._to_node(result)
+
+    def reboot_node(self, node):
+        params = {'force': 0, 'mbpkgid': node.id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/server/reboot',
+            data=json.dumps(params),
+            method='POST').object
+        if result:
+            return True
+
+    def destroy_node(self, node):
+        params = {'mbpkgid': node.id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/cancel', data=json.dumps(params),
+            method='POST').object
+        if result:
+            return True
+
+    def ex_stop_node(self, node):
+        params = {'force': 0, 'mbpkgid': node.id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/server/stop',
+            data=json.dumps(params),
+            method='POST').object
+        if result:
+            return True
+
+    def ex_start_node(self, node):
+        params = {'mbpkgid': node.id}
+        result = self.connection.request(
+            API_ROOT + '/cloud/server/start',
+            data=json.dumps(params),
+            method='POST').object
+        if result:
+            return True

Modified: libcloud/trunk/libcloud/compute/providers.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/providers.py?rev=1406792&r1=1406791&r2=1406792&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/providers.py (original)
+++ libcloud/trunk/libcloud/compute/providers.py Wed Nov  7 20:23:17 2012
@@ -115,7 +115,9 @@ DRIVERS = {
     Provider.VCL:
         ('libcloud.compute.drivers.vcl', 'VCLNodeDriver'),
     Provider.KTUCLOUD:
-        ('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver')
+        ('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver'),
+    Provider.HOSTVIRTUAL:
+	('libcloud.compute.drivers.hostvirtual', 'HostVirtualNodeDriver')
 }
 
 

Modified: libcloud/trunk/libcloud/compute/types.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/types.py?rev=1406792&r1=1406791&r2=1406792&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/types.py (original)
+++ libcloud/trunk/libcloud/compute/types.py Wed Nov  7 20:23:17 2012
@@ -119,6 +119,7 @@ class Provider(object):
     KTUCLOUD = 47
     GRIDSPOT = 49
     RACKSPACE_FIRST_GEN = 51
+    HOSTVIRTUAL = 52
 
     # Deprecated constants
     RACKSPACE_UK = 23

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/create_node.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/create_node.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/create_node.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/create_node.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,17 @@
+{
+  "mbpkgid": "76070",
+  "package_status": "Active",
+  "domu_package": null,
+  "rescue": null,
+  "locked": null,
+  "state": null,
+  "installed": null,
+  "package": null,
+  "ipv6": "",
+  "city": null,
+  "fqdn": "test.com",
+  "uptime": false,
+  "ip": null,
+  "name": "VR512",
+  "status": "BUILDING"
+}

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_images.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_images.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_images.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_images.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,98 @@
+[
+  {
+    "id": "1739",
+    "os": "Gentoo 2012 (0619) i386",
+    "description": "Gentoo 2012 0619 i386",
+    "type": "gentoo",
+    "subtype": "pv",
+    "size": "840mb",
+    "created": "2012-06-27 13:21:03",
+    "updated": "2012-06-27 13:28:50",
+    "bits": "32",
+    "tech": "pv"
+  },
+  {
+    "id": "1613",
+    "os": "CentOS 5.8 x64",
+    "description": "CentOS 5.8 x64",
+    "type": "centos",
+    "subtype": "pv",
+    "size": "1.2gb",
+    "created": "2012-03-31 01:34:54",
+    "updated": "2012-05-23 16:15:29",
+    "bits": "32",
+    "tech": "pv"
+  },
+  {
+    "id": "1676",
+    "os": "Ubuntu Server 12.04 LTS 64 bit",
+    "description": "Ubuntu 12.04 LTS x64",
+    "type": "ubuntu",
+    "subtype": "pv",
+    "size": "800mb",
+    "created": "2012-05-04 06:20:59",
+    "updated": "2012-05-04 06:31:09",
+    "bits": "64",
+    "tech": "pv"
+  },
+  {
+    "id": "1667",
+    "os": "Ubuntu Server 12.04 LTS 32 bit",
+    "description": "Ubuntu 12.04 i386",
+    "type": "ubuntu",
+    "subtype": "pv",
+    "size": "700mb",
+    "created": "2012-05-04 06:18:10",
+    "updated": "2012-05-04 06:31:08",
+    "bits": "32",
+    "tech": "pv"
+  },
+  {
+    "id": "1640",
+    "os": "CentOS 6.2 x64",
+    "description": "CentOS 6.2 x64",
+    "type": "centos",
+    "subtype": "pv",
+    "size": "1.2gb",
+    "created": "2012-03-31 01:36:44",
+    "updated": "2012-03-31 01:39:25",
+    "bits": "64",
+    "tech": "pv"
+  },
+  {
+    "id": "1631",
+    "os": "CentOS 6.2 i386",
+    "description": "CentOS 6.2 i386",
+    "type": "centos",
+    "subtype": "pv",
+    "size": "1.1gb",
+    "created": "2012-03-31 01:36:15",
+    "updated": "2012-03-31 01:38:50",
+    "bits": "32",
+    "tech": "pv"
+  },
+  {
+    "id": "1622",
+    "os": "CentOS 5.8 i386",
+    "description": "CentOS 5.8 i386",
+    "type": "centos",
+    "subtype": "pv",
+    "size": "1.1gb",
+    "created": "2012-03-31 01:35:30",
+    "updated": "2012-03-31 01:38:49",
+    "bits": "32",
+    "tech": "pv"
+  },
+  {
+    "id": "721",
+    "os": "Ubuntu 11.04 Server x64 PV",
+    "description": "<p>Ubuntu 11.04 base server installation.<\/p>",
+    "type": "ubuntu",
+    "subtype": "pv",
+    "size": "600mb",
+    "created": "2011-05-01 06:21:08",
+    "updated": "2011-05-01 13:21:08",
+    "bits": "64",
+    "tech": "pv"
+  }
+]

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_locations.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_locations.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_locations.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_locations.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,46 @@
+[
+  {
+    "id": "3",
+    "name": "SJC - San Jose, CA"
+  },
+  {
+    "id": "13",
+    "name": "IAD2- Reston, VA"
+  },
+  {
+    "id": "21",
+    "name": "LAX3 - Los Angeles, CA"
+  },
+  {
+    "id": "31",
+    "name": "CHI - Chicago, IL"
+  },
+  {
+    "id": "41",
+    "name": "NYC - New York, NY"
+  },
+  {
+    "id": "61",
+    "name": "MAA - Chennai (Madras), India"
+  },
+  {
+    "id": "71",
+    "name": "LON - London, United Kingdom"
+  },
+  {
+    "id": "72",
+    "name": "AMS2 - Amsterdam, NL"
+  },
+  {
+    "id": "82",
+    "name": "FRA - Paris, France"
+  },
+  {
+    "id": "83",
+    "name": "HK - Hong Kong, HK"
+  },
+  {
+    "id": "101",
+    "name": "DFW - Dallas, TX"
+  }
+]

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_nodes.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,62 @@
+[
+  {
+    "host": "659",
+    "rescue": "0",
+    "fqdn": "server1.vr-cluster.org",
+    "mbpkgid": "62291",
+    "locked": "0",
+    "os": "Debian 6 i386 PV",
+    "ip": "208.111.45.250",
+    "installed": "0",
+    "state": "DOWN",
+    "package": "VR512",
+    "ipv6": "2607:f740:10::f98",
+    "city": "MAA - Chennai (Madras), India",
+    "status": "TERMINATED"
+  },
+  {
+    "host": "902",
+    "rescue": "0",
+    "fqdn": "newbuild.vr.com",
+    "mbpkgid": "62327",
+    "locked": "0",
+    "os": "CentOS 5.8 x64",
+    "ip": "208.111.39.118",
+    "installed": "0",
+    "state": "DOWN",
+    "package": "VR512",
+    "ipv6": "2607:f740:0:3f::f0d",
+    "city": "SJC - San Jose, CA",
+    "status": "TERMINATED"
+  },
+  {
+    "host": "1010",
+    "rescue": "0",
+    "fqdn": "3test.build.com",
+    "mbpkgid": "62300",
+    "locked": "0",
+    "os": "CentOS 6.2 x64",
+    "ip": "208.111.40.179",
+    "installed": "0",
+    "state": "DOWN",
+    "package": "VR512",
+    "ipv6": "2607:f740:c::f4f",
+    "city": "LAX3 - Los Angeles, CA",
+    "status": "TERMINATED"
+  },
+  {
+    "host": "1028",
+    "rescue": "0",
+    "fqdn": "libcloud2.node.com",
+    "mbpkgid": "74567",
+    "locked": "0",
+    "os": "CentOS 5.8 x64",
+    "ip": "209.177.157.99",
+    "installed": "1",
+    "state": "UP",
+    "package": "VR512",
+    "ipv6": "2607:f740:b::eff",
+    "city": "IAD2- Reston, VA",
+    "status": "RUNNING"
+  }
+]

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/list_sizes.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,82 @@
+[
+  {
+    "plan": "VR256",
+    "ram": "256MB",
+    "disk": "10GB",
+    "transfer": "200GB",
+    "price": "10.00",
+    "available": "1421"
+  },
+  {
+    "plan": "VR384",
+    "ram": "384MB",
+    "disk": "15GB",
+    "transfer": "300GB",
+    "price": "15.00",
+    "available": "939"
+  },
+  {
+    "plan": "VR512",
+    "ram": "512MB",
+    "disk": "20GB",
+    "transfer": "400GB",
+    "price": "20.00",
+    "available": "713"
+  },
+  {
+    "plan": "VR768",
+    "ram": "768MB",
+    "disk": "30GB",
+    "transfer": "600GB",
+    "price": "30.00",
+    "available": "476"
+  },
+  {
+    "plan": "VR1024",
+    "ram": "1024MB",
+    "disk": "40GB",
+    "transfer": "800GB",
+    "price": "40.00",
+    "available": "350"
+  },
+  {
+    "plan": "VR1280",
+    "ram": "1280MB",
+    "disk": "50GB",
+    "transfer": "1000GB",
+    "price": "50.00",
+    "available": "276"
+  },
+  {
+    "plan": "VR1536",
+    "ram": "1536MB",
+    "disk": "60GB",
+    "transfer": "1200GB",
+    "price": "60.00",
+    "available": "226"
+  },
+  {
+    "plan": "VR2048",
+    "ram": "2048MB",
+    "disk": "80GB",
+    "transfer": "1600GB",
+    "price": "80.00",
+    "available": "160"
+  },
+  {
+    "plan": "VR4048",
+    "ram": "4048MB",
+    "disk": "160GB",
+    "transfer": "3200GB",
+    "price": "160.00",
+    "available": "69"
+  },
+  {
+    "plan": "VR8096",
+    "ram": "8096MB",
+    "disk": "320GB",
+    "transfer": "6400GB",
+    "price": "320.00",
+    "available": "9"
+  }
+]

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_destroy.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_destroy.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_destroy.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_destroy.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,3 @@
+{
+	"status" : "success"
+}

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_reboot.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_reboot.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_reboot.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_reboot.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,3 @@
+{
+	"status" : "success"
+}

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_start.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_start.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_start.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_start.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,3 @@
+{
+	"status" : "success"
+}

Added: libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_stop.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_stop.json?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_stop.json (added)
+++ libcloud/trunk/libcloud/test/compute/fixtures/hostvirtual/node_stop.json Wed Nov  7 20:23:17 2012
@@ -0,0 +1,3 @@
+{
+	"status" : "success"
+}

Added: libcloud/trunk/libcloud/test/compute/test_hostvirtual.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/test_hostvirtual.py?rev=1406792&view=auto
==============================================================================
--- libcloud/trunk/libcloud/test/compute/test_hostvirtual.py (added)
+++ libcloud/trunk/libcloud/test/compute/test_hostvirtual.py Wed Nov  7 20:23:17 2012
@@ -0,0 +1,161 @@
+# 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
+
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+from libcloud.utils.py3 import httplib
+
+from libcloud.compute.drivers.hostvirtual import HostVirtualNodeDriver
+from libcloud.compute.types import NodeState
+from libcloud.compute.base import NodeAuthPassword
+from libcloud.test import MockHttp
+from libcloud.test.file_fixtures import ComputeFileFixtures
+from libcloud.test.secrets import HOSTVIRTUAL_PARAMS
+
+
+class HostVirtualTest(unittest.TestCase):
+    def setUp(self):
+        HostVirtualNodeDriver.connectionCls.conn_classes = (
+            None, HostVirtualMockHttp)
+        self.driver = HostVirtualNodeDriver(*HOSTVIRTUAL_PARAMS)
+
+    def test_list_nodes(self):
+        nodes = self.driver.list_nodes()
+        self.assertEqual(len(nodes), 4)
+        self.assertEqual(len(nodes[0].public_ips), 1)
+        self.assertEqual(len(nodes[1].public_ips), 1)
+        self.assertEqual(len(nodes[0].private_ips), 0)
+        self.assertEqual(len(nodes[1].private_ips), 0)
+        self.assertTrue('208.111.39.118' in nodes[1].public_ips)
+        self.assertTrue('208.111.45.250' in nodes[0].public_ips)
+        self.assertEqual(nodes[3].state, NodeState.RUNNING)
+        self.assertEqual(nodes[1].state, NodeState.TERMINATED)
+
+    def test_list_sizes(self):
+        sizes = self.driver.list_sizes()
+        self.assertEqual(len(sizes), 10)
+        self.assertEqual(sizes[0].id, 'VR256')
+        self.assertEqual(sizes[4].id, 'VR1024')
+        self.assertEqual(sizes[2].ram, '512MB')
+        self.assertEqual(sizes[2].disk, '20GB')
+        self.assertEqual(sizes[3].bandwidth, '600GB')
+        self.assertEqual(sizes[1].price, '15.00')
+
+    def test_list_images(self):
+        images = self.driver.list_images()
+        self.assertEqual(len(images), 8)
+        self.assertEqual(images[0].id, '1739')
+        self.assertEqual(images[0].name, 'Gentoo 2012 (0619) i386')
+
+    def test_list_locations(self):
+        locations = self.driver.list_locations()
+        self.assertEqual(locations[0].id, '3')
+        self.assertEqual(locations[0].name, 'SJC - San Jose, CA')
+        self.assertEqual(locations[1].id, '13')
+        self.assertEqual(locations[1].name, 'IAD2- Reston, VA')
+
+    def test_reboot_node(self):
+        node = self.driver.list_nodes()[0]
+        self.assertTrue(self.driver.reboot_node(node))
+
+    def test_stop_node(self):
+        node = self.driver.list_nodes()[0]
+        self.assertTrue(self.driver.ex_stop_node(node))
+
+    def test_start_node_response(self):
+        node = self.driver.list_nodes()[0]
+        self.assertTrue(self.driver.ex_start_node(node))
+
+    def test_destroy_node(self):
+        node = self.driver.list_nodes()[0]
+        self.assertTrue(self.driver.destroy_node(node))
+
+    def test_create_node(self):
+        auth = NodeAuthPassword('vr!@#hosted#@!')
+        size = self.driver.list_sizes()[0]
+        image = self.driver.list_images()[0]
+        node = self.driver.create_node(
+            name='test.com',
+            image=image,
+            size=size,
+            auth=auth
+        )
+        self.assertEqual('76070', node.id)
+        self.assertEqual('test.com', node.name)
+
+    def test_create_node_in_location(self):
+        auth = NodeAuthPassword('vr!@#hosted#@!')
+        size = self.driver.list_sizes()[0]
+        image = self.driver.list_images()[0]
+        location = self.driver.list_locations()[1]
+        node = self.driver.create_node(
+            name='test.com',
+            image=image,
+            size=size,
+            auth=auth,
+            location=location
+        )
+        self.assertEqual('76070', node.id)
+        self.assertEqual('test.com', node.name)
+
+
+class HostVirtualMockHttp(MockHttp):
+    fixtures = ComputeFileFixtures('hostvirtual')
+
+    def _vapi_cloud_servers(self, method, url, body, headers):
+        body = self.fixtures.load('list_nodes.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_sizes(self, method, url, body, headers):
+        body = self.fixtures.load('list_sizes.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_images(self, method, url, body, headers):
+        body = self.fixtures.load('list_images.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_locations(self, method, url, body, headers):
+        body = self.fixtures.load('list_locations.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_cancel(self, method, url, body, headers):
+        body = self.fixtures.load('node_destroy.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_server_reboot(self, method, url, body, headers):
+        body = self.fixtures.load('node_reboot.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_server_stop(self, method, url, body, headers):
+        body = self.fixtures.load('node_stop.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_server_start(self, method, url, body, headers):
+        body = self.fixtures.load('node_start.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _vapi_cloud_buy_build(self, method, url, body, headers):
+        body = self.fixtures.load('create_node.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())
+
+# vim:autoindent tabstop=4 shiftwidth=4 expandtab softtabstop=4 filetype=python

Modified: libcloud/trunk/libcloud/test/secrets.py-dist
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/secrets.py-dist?rev=1406792&r1=1406791&r2=1406792&view=diff
==============================================================================
--- libcloud/trunk/libcloud/test/secrets.py-dist (original)
+++ libcloud/trunk/libcloud/test/secrets.py-dist Wed Nov  7 20:23:17 2012
@@ -38,6 +38,7 @@ VPSNET_PARAMS = ('user', 'key')
 JOYENT_PARAMS = ('user', 'key')
 VCL_PARAMS = ('user', 'pass', True, 'foo.bar.com')
 GRIDSPOT_PARAMS = ('key',)
+HOSTVIRTUAL_PARAMS = ('key',)
 
 # Storage
 STORAGE_S3_PARAMS = ('key', 'secret')