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 2013/10/07 13:15:57 UTC
[1/5] git commit: [LIBCLOUD-404]: Add Nephoscale driver.
Updated Branches:
refs/heads/trunk bf681d8d1 -> 34ec154b1
[LIBCLOUD-404]: Add Nephoscale driver.
Signed-off-by: Tomaz Muraus <to...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/da2fd8d8
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/da2fd8d8
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/da2fd8d8
Branch: refs/heads/trunk
Commit: da2fd8d859b7998bbfd99e4c61de1e62f8dea0e4
Parents: bf681d8
Author: Markos Gogoulos <mg...@unweb.me>
Authored: Mon Sep 30 14:00:58 2013 +0300
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Oct 7 12:55:06 2013 +0200
----------------------------------------------------------------------
libcloud/compute/drivers/nephoscale.py | 459 +++++++++++++++++++
libcloud/compute/providers.py | 4 +-
libcloud/compute/types.py | 2 +
libcloud/data/pricing.json | 16 +
.../fixtures/nephoscale/list_images.json | 243 ++++++++++
.../compute/fixtures/nephoscale/list_keys.json | 25 +
.../fixtures/nephoscale/list_locations.json | 31 ++
.../compute/fixtures/nephoscale/list_nodes.json | 161 +++++++
.../fixtures/nephoscale/list_password_keys.json | 18 +
.../compute/fixtures/nephoscale/list_sizes.json | 178 +++++++
.../fixtures/nephoscale/list_ssh_keys.json | 18 +
.../fixtures/nephoscale/success_action.json | 11 +
libcloud/test/compute/test_nephoscale.py | 189 ++++++++
13 files changed, 1354 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/compute/drivers/nephoscale.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/nephoscale.py b/libcloud/compute/drivers/nephoscale.py
new file mode 100644
index 0000000..80dba81
--- /dev/null
+++ b/libcloud/compute/drivers/nephoscale.py
@@ -0,0 +1,459 @@
+# 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.
+
+"""
+NephoScale Cloud driver (http://www.nephoscale.com)
+API documentation: http://docs.nephoscale.com
+Created by Markos Gogoulos (https://mist.io)
+"""
+
+import base64
+import sys
+import string
+import random
+import time
+import os
+import binascii
+
+try:
+ import simplejson as json
+except:
+ import json
+
+from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import b
+from libcloud.utils.py3 import urlencode
+
+from libcloud.compute.providers import Provider
+from libcloud.compute.base import is_private_subnet
+from libcloud.common.base import JsonResponse, ConnectionUserAndKey
+from libcloud.compute.types import (NodeState, InvalidCredsError,
+ LibcloudError)
+from libcloud.compute.base import (Node, NodeDriver, NodeImage, NodeSize,
+ NodeLocation)
+
+API_HOST = 'api.nephoscale.com'
+
+NODE_STATE_MAP = {
+ 'on': NodeState.RUNNING,
+ 'off': NodeState.UNKNOWN,
+ 'unknown': NodeState.UNKNOWN,
+}
+
+VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
+ httplib.NO_CONTENT]
+
+#used in create_node and specifies how many times to get the list of nodes and
+#check if the newly created node is there. This is because when a request is
+#sent to create a node, NephoScale replies with the job id, and not the node
+#itself thus we don't have the ip addresses, that are required in deploy_node
+CONNECT_ATTEMPTS = 10
+
+
+class NodeKey(object):
+ def __init__(self, id, name, public_key=None, key_group=None,
+ password=None):
+ self.id = id
+ self.name = name
+ self.key_group = key_group
+ self.password = password
+ self.public_key = public_key
+
+ def __repr__(self):
+ return (('<NodeKey: id=%s, name=%s>') %
+ (self.id, self.name))
+
+
+class NephoscaleResponse(JsonResponse):
+ """
+ Nephoscale API Response
+ """
+
+ def parse_error(self):
+ if self.status == httplib.UNAUTHORIZED:
+ raise InvalidCredsError('Authorization Failed')
+ if self.status == httplib.NOT_FOUND:
+ raise Exception("The resource you are looking for is not found.")
+
+ return self.body
+
+ def success(self):
+ return self.status in VALID_RESPONSE_CODES
+
+
+class NephoscaleConnection(ConnectionUserAndKey):
+ """
+ Nephoscale connection class.
+ Authenticates to the API through Basic Authentication
+ with username/password
+ """
+ host = API_HOST
+ responseCls = NephoscaleResponse
+
+ def add_default_headers(self, headers):
+ """
+ Add parameters that are necessary for every request
+ """
+ user_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key)))
+ headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
+ return headers
+
+
+class NephoscaleNodeDriver(NodeDriver):
+ """
+ Nephoscale node driver class.
+
+ >>> from libcloud.compute.types import Provider
+ >>> from libcloud.compute.providers import get_driver
+ >>> driver = get_driver('nephoscale')
+ >>> conn = driver('nepho_user','nepho_password')
+ >>> conn.list_nodes()
+ """
+
+ type = Provider.NEPHOSCALE
+ api_name = 'nephoscale'
+ name = 'NephoScale'
+ website = 'http://www.nephoscale.com'
+ connectionCls = NephoscaleConnection
+ features = {'create_node': ['ssh_key']}
+
+ def list_locations(self):
+ """
+ List available zones for deployment
+
+ :rtype: ``list`` of :class:`NodeLocation`
+ """
+ result = self.connection.request('/datacenter/zone/').object
+ locations = []
+ for value in result.get('data', []):
+ location = NodeLocation(id=value.get('id'),
+ name=value.get('name'),
+ country='US',
+ driver=self)
+ locations.append(location)
+ return locations
+
+ def list_images(self):
+ """
+ List available images for deployment
+
+ :rtype: ``list`` of :class:`NodeImage`
+ """
+ result = self.connection.request('/image/server/').object
+ images = []
+ for value in result.get('data', []):
+ extra = {'architecture': value.get('architecture'),
+ 'disks': value.get('disks'),
+ 'billable_type': value.get('billable_type'),
+ 'pcpus': value.get('pcpus'),
+ 'cores': value.get('cores'),
+ 'uri': value.get('uri'),
+ 'storage': value.get('storage'),
+ }
+ image = NodeImage(id=value.get('id'),
+ name=value.get('friendly_name'),
+ driver=self,
+ extra=extra)
+ images.append(image)
+ return images
+
+ def list_sizes(self):
+ """
+ List available sizes containing prices
+
+ :rtype: ``list`` of :class:`NodeSize`
+ """
+ result = self.connection.request('/server/type/cloud/').object
+ sizes = []
+ for value in result.get('data', []):
+ value_id = value.get('id')
+ size = NodeSize(id=value_id,
+ name=value.get('friendly_name'),
+ ram=value.get('ram'),
+ disk=value.get('storage'),
+ bandwidth=None,
+ price=self._get_size_price(size_id=str(value_id)),
+ driver=self)
+ sizes.append(size)
+
+ return sorted(sizes, key=lambda k: k.price)
+
+ def list_nodes(self):
+ """
+ List available nodes
+
+ :rtype: ``list`` of :class:`Node`
+ """
+ result = self.connection.request('/server/cloud/').object
+ nodes = [self._to_node(value) for value in result.get('data', [])]
+ return nodes
+
+ def rename_node(self, node, name, hostname=None):
+ """rename a cloud server, optionally specify hostname too"""
+ data = {'name': name}
+ if hostname:
+ data['hostname'] = hostname
+ params = urlencode(data)
+ result = self.connection.request('/server/cloud/%s/' % node.id,
+ data=params, method='PUT').object
+ return result.get('response') in VALID_RESPONSE_CODES
+
+ def reboot_node(self, node):
+ """reboot a running node"""
+ result = self.connection.request('/server/cloud/%s/initiator/restart/'
+ % node.id, method='POST').object
+ return result.get('response') in VALID_RESPONSE_CODES
+
+ def ex_start_node(self, node):
+ """start a stopped node"""
+ result = self.connection.request('/server/cloud/%s/initiator/start/'
+ % node.id, method='POST').object
+ return result.get('response') in VALID_RESPONSE_CODES
+
+ def ex_stop_node(self, node):
+ """stop a running node"""
+ result = self.connection.request('/server/cloud/%s/initiator/stop/'
+ % node.id, method='POST').object
+ return result.get('response') in VALID_RESPONSE_CODES
+
+ def destroy_node(self, node):
+ """destroy a node"""
+ result = self.connection.request('/server/cloud/%s/' % node.id,
+ method='DELETE').object
+ return result.get('response') in VALID_RESPONSE_CODES
+
+ def ex_list_keypairs(self, ssh=False, password=False, key_group=None):
+ """
+ List available console and server keys
+ There are two types of keys for NephoScale, ssh and password keys.
+ If run without arguments, lists all keys. Otherwise list only
+ ssh keys, or only password keys.
+ Password keys with key_group 4 are console keys. When a server
+ is created, it has two keys, one password or ssh key, and
+ one password console key.
+
+ :keyword ssh: if specified, show ssh keys only (optional)
+ :type ssh: ``bool``
+
+ :keyword password: if specified, show password keys only (optional)
+ :type password: ``bool``
+
+ :keyword key_group: if specified, show keys with this key_group only
+ eg key_group=4 for console password keys (optional)
+ :type key_group: ``int``
+
+ :rtype: ``list`` of :class:`NodeKey`
+ """
+ if (ssh and password):
+ raise LibcloudError('You can only supply ssh or password. To \
+get all keys call with no arguments')
+ if ssh:
+ result = self.connection.request('/key/sshrsa/').object
+ elif password:
+ result = self.connection.request('/key/password/').object
+ else:
+ result = self.connection.request('/key/').object
+ keys = [self._to_key(value) for value in result.get('data', [])]
+
+ if key_group:
+ keys = [key for key in keys if
+ key.key_group == key_group]
+ return keys
+
+ def ex_create_keypair(self, name, public_key=None, password=None,
+ key_group=None):
+ """Creates a key, ssh or password, for server or console
+ The group for the key (key_group) is 1 for Server and 4 for Console
+ Returns the id of the created key
+ """
+ if public_key:
+ if not key_group:
+ key_group = 1
+ data = {
+ 'name': name,
+ 'public_key': public_key,
+ 'key_group': key_group
+
+ }
+ params = urlencode(data)
+ result = self.connection.request('/key/sshrsa/', data=params,
+ method='POST').object
+ else:
+ if not key_group:
+ key_group = 4
+ if not password:
+ password = self.random_password()
+ data = {
+ 'name': name,
+ 'password': password,
+ 'key_group': key_group
+ }
+ params = urlencode(data)
+ result = self.connection.request('/key/password/', data=params,
+ method='POST').object
+ return result.get('data', {}).get('id', '')
+
+ def ex_delete_keypair(self, key_id, ssh=False):
+ """Delete an ssh key or password given it's id
+ """
+ if ssh:
+ result = self.connection.request('/key/sshrsa/%s/' % key_id,
+ method='DELETE').object
+ else:
+ result = self.connection.request('/key/password/%s/' % key_id,
+ method='DELETE').object
+ return result.get('response') in VALID_RESPONSE_CODES
+
+ def create_node(self, name, size, image, server_key=None,
+ console_key=None, zone=None, **kwargs):
+ """Creates the node, and sets the ssh key, console key
+ NephoScale will respond with a 200-200 response after sending a valid
+ request. If nowait=True is specified in the args, we then ask a few
+ times until the server is created and assigned a public IP address,
+ so that deploy_node can be run
+
+ >>> from libcloud.compute.types import Provider
+ >>> from libcloud.compute.providers import get_driver
+ >>> driver = get_driver('nephoscale')
+ >>> conn = driver('nepho_user','nepho_password')
+ >>> conn.list_nodes()
+ >>> name = 'staging-server'
+ >>> size = conn.list_sizes()[0]
+ <NodeSize: id=27, ...name=CS025 - 0.25GB, 10GB, ...>
+ >>> image = conn.list_images()[9]
+ <NodeImage: id=49, name=Linux Ubuntu Server 10.04 LTS 64-bit, ...>
+ >>> server_keys = conn.ex_list_keypairs(key_group=1)[0]
+ <NodeKey: id=71211, name=markos>
+ >>> server_key = conn.ex_list_keypairs(key_group=1)[0].id
+ 70867
+ >>> console_keys = conn.ex_list_keypairs(key_group=4)[0]
+ <NodeKey: id=71213, name=mistio28434>
+ >>> console_key = conn.ex_list_keypairs(key_group=4)[0].id
+ 70907
+ >>> node = conn.create_node(name=name, size=size, image=image, \
+ console_key=console_key, server_key=server_key)
+
+ We can also create an ssh key, plus a console key and
+ deploy node with them
+ >>> server_key = conn.ex_create_keypair(name, public_key=key)
+ 71211
+ >>> console_key = conn.ex_create_keypair(name, key_group=4)
+ 71213
+
+ We can increase the number of connect attempts to wait until
+ the node is created, so that deploy_node has ip address to
+ deploy the script
+ We can also specify the location
+ >>> location = conn.list_locations()[0]
+ >>> node = conn.create_node(name=name,
+ size=size,
+ image=image,
+ console_key=console_key,
+ server_key=server_key,
+ connect_attempts=10,
+ nowait=True,
+ zone=location.id)
+ """
+ try:
+ hostname = kwargs.get('hostname', name)
+ service_type = size.id
+ image = image.id
+ connect_attempts = int(kwargs.get('connect_attempts',
+ CONNECT_ATTEMPTS))
+ except Exception:
+ e = sys.exc_info()[1]
+ raise Exception("Error on create node: %s" % e)
+
+ data = {'name': name,
+ 'hostname': hostname,
+ 'service_type': service_type,
+ 'image': image,
+ 'server_key': server_key,
+ 'console_key': console_key,
+ 'zone': zone
+ }
+
+ params = urlencode(data)
+ try:
+ node = self.connection.request('/server/cloud/', data=params,
+ method='POST')
+ except Exception:
+ e = sys.exc_info()[1]
+ raise Exception("Failed to create node %s" % e)
+ node = Node(id='', name=name, state=NodeState.UNKNOWN, public_ips=[],
+ private_ips=[], driver=self)
+
+ nowait = kwargs.get('ex_wait', False)
+ if not nowait:
+ return node
+ else:
+ #try to get the created node public ips, for use in deploy_node
+ #At this point we don't have the id of the newly created Node,
+ #so search name in nodes
+ created_node = False
+ while connect_attempts > 0:
+ nodes = self.list_nodes()
+ created_node = [c_node for c_node in nodes if
+ c_node.name == name]
+ if created_node:
+ return created_node[0]
+ else:
+ time.sleep(60)
+ connect_attempts = connect_attempts - 1
+ return node
+
+ def _to_node(self, data):
+ """Convert node in Node instances
+ """
+
+ state = NODE_STATE_MAP.get(data.get('power_status'), '4')
+ public_ips = []
+ private_ips = []
+ ip_addresses = data.get('ipaddresses', '')
+ #E.g. "ipaddresses": "198.120.14.6, 10.132.60.1"
+ if ip_addresses:
+ for ip in ip_addresses.split(','):
+ ip = ip.replace(' ', '')
+ if is_private_subnet(ip):
+ private_ips.append(ip)
+ else:
+ public_ips.append(ip)
+ extra = {
+ 'zone_data': data.get('zone'),
+ 'zone': data.get('zone', {}).get('name'),
+ 'image': data.get('image', {}).get('friendly_name'),
+ 'create_time': data.get('create_time'),
+ 'network_ports': data.get('network_ports'),
+ 'is_console_enabled': data.get('is_console_enabled'),
+ 'service_type': data.get('service_type', {}).get('friendly_name'),
+ 'hostname': data.get('hostname')
+ }
+
+ node = Node(id=data.get('id'), name=data.get('name'), state=state,
+ public_ips=public_ips, private_ips=private_ips,
+ driver=self, extra=extra)
+ return node
+
+ def _to_key(self, data):
+ return NodeKey(id=data.get('id'),
+ name=data.get('name'),
+ password=data.get('password'),
+ key_group=data.get('key_group'),
+ public_key=data.get('public_key'))
+
+ def random_password(self, size=8):
+ value = os.urandom(size)
+ password = binascii.hexlify(value).decode('ascii')
+ return password[:size]
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/compute/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/providers.py b/libcloud/compute/providers.py
index fbc9c63..32c60d6 100644
--- a/libcloud/compute/providers.py
+++ b/libcloud/compute/providers.py
@@ -126,7 +126,9 @@ DRIVERS = {
Provider.ABIQUO:
('libcloud.compute.drivers.abiquo', 'AbiquoNodeDriver'),
Provider.DIGITAL_OCEAN:
- ('libcloud.compute.drivers.digitalocean', 'DigitalOceanNodeDriver')
+ ('libcloud.compute.drivers.digitalocean', 'DigitalOceanNodeDriver'),
+ Provider.NEPHOSCALE:
+ ('libcloud.compute.drivers.nephoscale', 'NephoscaleNodeDriver')
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/compute/types.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/types.py b/libcloud/compute/types.py
index 926c750..aefbf5a 100644
--- a/libcloud/compute/types.py
+++ b/libcloud/compute/types.py
@@ -71,6 +71,7 @@ class Provider(object):
:cvar KTUCLOUD: kt ucloud driver
:cvar GRIDSPOT: Gridspot driver
:cvar ABIQUO: Abiquo driver
+ @cvar NEPHOSCALE: NephoScale driver
"""
DUMMY = 'dummy'
EC2 = 'ec2_us_east'
@@ -117,6 +118,7 @@ class Provider(object):
HOSTVIRTUAL = 'hostvirtual'
ABIQUO = 'abiquo'
DIGITAL_OCEAN = 'digitalocean'
+ NEPHOSCALE = 'nephoscale'
# Deprecated constants which are still supported
EC2_US_EAST = 'ec2_us_east'
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/data/pricing.json
----------------------------------------------------------------------
diff --git a/libcloud/data/pricing.json b/libcloud/data/pricing.json
index 905d657..7a9b731 100644
--- a/libcloud/data/pricing.json
+++ b/libcloud/data/pricing.json
@@ -171,6 +171,22 @@
"m3.2xlarge": 1.40
},
+ "nephoscale" : {
+ "1": 0.60,
+ "3": 0.063,
+ "5": 0.031,
+ "7": 0.125,
+ "9": 0.188,
+ "11": 0.35,
+ "27": 0.0,
+ "46": 0.10,
+ "48": 0.15,
+ "50": 0.28,
+ "52": 0.48,
+ "54": 0.938,
+ "56": 0.75
+ },
+
"nimbus" : {
"m1.small": 0.0,
"m1.large": 0.0,
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_images.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_images.json b/libcloud/test/compute/fixtures/nephoscale/list_images.json
new file mode 100644
index 0000000..1ede35d
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_images.json
@@ -0,0 +1,243 @@
+{
+ "success": true,
+ "total_count": 18,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux CentOS 5.5 32-bit",
+ "uri": "https://api.nephoscale.com/image/server/3/",
+ "max_memory": 128,
+ "id": 3,
+ "is_default": true,
+ "create_time": "2010-12-20 14:25:36",
+ "architecture": "x86",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux CentOS 5.5 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/5/",
+ "max_memory": 128,
+ "id": 5,
+ "is_default": true,
+ "create_time": "2010-12-20 14:25:36",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Windows Server 2008 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/21/",
+ "max_memory": 128,
+ "id": 21,
+ "is_default": true,
+ "create_time": "2010-12-20 14:25:36",
+ "architecture": "x86_64",
+ "base_type": "windows"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Debian Server 5.05 32-bit",
+ "uri": "https://api.nephoscale.com/image/server/23/",
+ "max_memory": 128,
+ "id": 23,
+ "is_default": true,
+ "create_time": "2010-12-20 16:51:20",
+ "architecture": "x86",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Debian Server 5.05 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/25/",
+ "max_memory": 128,
+ "id": 25,
+ "is_default": true,
+ "create_time": "2010-12-20 16:55:42",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Windows Server 2003 Enterprise 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/33/",
+ "max_memory": 128,
+ "id": 33,
+ "is_default": true,
+ "create_time": "2011-03-02 14:20:49",
+ "architecture": "x86_64",
+ "base_type": "windows"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux CentOS 5.7 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/41/",
+ "max_memory": 128,
+ "id": 41,
+ "is_default": true,
+ "create_time": "2011-09-19 17:30:04",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Ubuntu Server 10.04 LTS 32-bit",
+ "uri": "https://api.nephoscale.com/image/server/43/",
+ "max_memory": 128,
+ "id": 43,
+ "is_default": true,
+ "create_time": "2011-10-01 02:26:17",
+ "architecture": "x86",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux CentOS 5.7 32-bit",
+ "uri": "https://api.nephoscale.com/image/server/45/",
+ "max_memory": 128,
+ "id": 45,
+ "is_default": true,
+ "create_time": "2011-10-05 19:41:30",
+ "architecture": "x86",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Ubuntu Server 10.04 LTS 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/49/",
+ "max_memory": 128,
+ "id": 49,
+ "is_default": true,
+ "create_time": "2011-10-08 05:01:10",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Debian Server 6.0.3 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/51/",
+ "max_memory": 128,
+ "id": 51,
+ "is_default": true,
+ "create_time": "2011-10-08 19:54:41",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Debian 5.0.9 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/55/",
+ "max_memory": 128,
+ "id": 55,
+ "is_default": false,
+ "create_time": "2011-10-13 12:53:36",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Debian 5.0.9 32-bit",
+ "uri": "https://api.nephoscale.com/image/server/57/",
+ "max_memory": 128,
+ "id": 57,
+ "is_default": false,
+ "create_time": "2011-10-13 12:55:09",
+ "architecture": "x86",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux CentOS 6.2 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/59/",
+ "max_memory": 128,
+ "id": 59,
+ "is_default": true,
+ "create_time": "2011-10-15 17:11:34",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux CentOS 5.8 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/64/",
+ "max_memory": 128,
+ "id": 64,
+ "is_default": true,
+ "create_time": "2012-03-28 19:54:10",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Ubuntu Server 12.04 LTS 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/75/",
+ "max_memory": 128,
+ "id": 75,
+ "is_default": true,
+ "create_time": "2012-05-18 08:41:03",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "cloud",
+ "is_active": true,
+ "friendly_name": "VOD Cloud Storage Proxy (FTP:HTTP)",
+ "uri": "https://api.nephoscale.com/image/server/101/",
+ "max_memory": 128,
+ "id": 101,
+ "is_default": false,
+ "create_time": "2012-08-30 08:49:55",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ },
+ {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Debian 7.1 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/177/",
+ "max_memory": 128,
+ "id": 177,
+ "is_default": true,
+ "create_time": "2013-09-10 16:12:10",
+ "architecture": "x86_64",
+ "base_type": "linux"
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_keys.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_keys.json b/libcloud/test/compute/fixtures/nephoscale/list_keys.json
new file mode 100644
index 0000000..f6f9205
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_keys.json
@@ -0,0 +1,25 @@
+{
+ "success": true,
+ "total_count": 2,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "name": "mistio-ssh",
+ "key_group": 1,
+ "uri": "https://api.nephoscale.com/key/sshrsa/72209/",
+ "key_type": 2,
+ "create_time": "2013-10-02 07:24:37",
+ "id": 72209
+ },
+ {
+ "name": "mistio-testing",
+ "key_group": 4,
+ "uri": "https://api.nephoscale.com/key/password/72211/",
+ "key_type": 1,
+ "create_time": "2013-10-02 07:27:10",
+ "id": 72211
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_locations.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_locations.json b/libcloud/test/compute/fixtures/nephoscale/list_locations.json
new file mode 100644
index 0000000..952fac4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_locations.json
@@ -0,0 +1,31 @@
+{
+ "success": true,
+ "total_count": 2,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "datacenter": {
+ "airport_code": "SJC",
+ "name": "SJC-1",
+ "uri": "https://api.nephoscale.com/datacenter/1/",
+ "id": 1
+ },
+ "uri": "https://api.nephoscale.com/datacenter/zone/86945/",
+ "id": 86945,
+ "name": "SJC-1"
+ },
+ {
+ "datacenter": {
+ "airport_code": "RIC",
+ "name": "RIC-1",
+ "uri": "https://api.nephoscale.com/datacenter/3/",
+ "id": 3
+ },
+ "uri": "https://api.nephoscale.com/datacenter/zone/87729/",
+ "id": 87729,
+ "name": "RIC-1"
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_nodes.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_nodes.json b/libcloud/test/compute/fixtures/nephoscale/list_nodes.json
new file mode 100644
index 0000000..7fdff6c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_nodes.json
@@ -0,0 +1,161 @@
+{
+ "success": true,
+ "total_count": 2,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "server_keys": [
+ {
+ "key_type": 2,
+ "key_group": 1,
+ "id": 71757,
+ "uri": "https://api.nephoscale.com/key/sshrsa/71157/"
+ }
+ ],
+ "name": "mongodb-staging",
+ "zone": {
+ "uri": "https://api.nephoscale.com/datacenter/zone/88211/",
+ "id": 87729,
+ "name": "RIC-1"
+ },
+ "image": {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Ubuntu Server 10.04 LTS 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/49/",
+ "max_memory": 128,
+ "id": 49,
+ "is_default": true,
+ "create_time": "2011-10-08 05:01:10",
+ "architecture": "x86_64",
+ "has_agent": true,
+ "base_type": "linux"
+ },
+ "hostname": "mongodb-staging",
+ "podzone": "P1A2",
+ "uri": "https://api.nephoscale.com/server/cloud/87241/",
+ "ipaddresses": "198.89.117.16",
+ "power_status": "on",
+ "create_time": "2013-09-25 07:38:53",
+ "postinit_state": 1,
+ "console_keys": [
+ {
+ "key_type": 1,
+ "key_group": 4,
+ "id": 71761,
+ "uri": "https://api.nephoscale.com/key/password/71761/"
+ }
+ ],
+ "memory": 512,
+ "service_type": {
+ "sku": {
+ "name": "CS05",
+ "description": "Cloud Server 0.5 GB RAM, 1 Core"
+ },
+ "uri": "https://api.nephoscale.com/server/type/cloud/5/",
+ "friendly_name": "CS05 - 0.5GB, 1Core, 25GB",
+ "id": 5,
+ "billable_type": 1
+ },
+ "network_ports": [
+ {
+ "macaddress": "00:16:3e:06:dc:41",
+ "devname": "eth0",
+ "network_domain": {
+ "domain_type": 0,
+ "name": "default_public_network_RIC"
+ }
+ },
+ {
+ "macaddress": "00:16:3e:06:dc:45",
+ "devname": "eth1",
+ "network_domain": {
+ "domain_type": 1,
+ "name": "default_private_network_RIC"
+ }
+ }
+ ],
+ "id": 88241,
+ "is_console_enabled": true
+ },
+ {
+ "server_keys": [
+ {
+ "key_type": 2,
+ "key_group": 1,
+ "id": 72049,
+ "uri": "https://api.nephoscale.com/key/sshrsa/72049/"
+ }
+ ],
+ "name": "backup-server2",
+ "zone": {
+ "uri": "https://api.nephoscale.com/datacenter/zone/88751/",
+ "id": 87729,
+ "name": "RIC-1"
+ },
+ "image": {
+ "max_cpu": 64,
+ "deployable_type": "both",
+ "is_active": true,
+ "friendly_name": "Linux Debian Server 6.0.3 64-bit",
+ "uri": "https://api.nephoscale.com/image/server/51/",
+ "max_memory": 128,
+ "id": 51,
+ "is_default": true,
+ "create_time": "2011-10-08 19:54:41",
+ "architecture": "x86_64",
+ "has_agent": true,
+ "base_type": "linux"
+ },
+ "hostname": "backup-server2",
+ "podzone": "P1A2",
+ "uri": "https://api.nephoscale.com/server/cloud/88751/",
+ "ipaddresses": "198.89.112.115",
+ "power_status": "on",
+ "create_time": "2013-10-02 05:02:50",
+ "postinit_state": 1,
+ "console_keys": [
+ {
+ "key_type": 1,
+ "key_group": 4,
+ "id": 72165,
+ "uri": "https://api.nephoscale.com/key/password/72165/"
+ }
+ ],
+ "memory": 512,
+ "service_type": {
+ "sku": {
+ "name": "CS05",
+ "description": "Cloud Server 0.5 GB RAM, 1 Core"
+ },
+ "uri": "https://api.nephoscale.com/server/type/cloud/5/",
+ "friendly_name": "CS05 - 0.5GB, 1Core, 25GB",
+ "id": 5,
+ "billable_type": 1
+ },
+ "network_ports": [
+ {
+ "macaddress": "00:16:3e:06:f5:2f",
+ "devname": "eth0",
+ "network_domain": {
+ "domain_type": 0,
+ "name": "default_public_network_RIC"
+ }
+ },
+ {
+ "macaddress": "00:16:3e:06:f5:33",
+ "devname": "eth1",
+ "network_domain": {
+ "domain_type": 1,
+ "name": "default_private_network_RIC"
+ }
+ }
+ ],
+ "id": 88751,
+ "is_console_enabled": true
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_password_keys.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_password_keys.json b/libcloud/test/compute/fixtures/nephoscale/list_password_keys.json
new file mode 100644
index 0000000..ca3c629
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_password_keys.json
@@ -0,0 +1,18 @@
+{
+ "success": true,
+ "total_count": 1,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "name": "mistio-testing",
+ "key_group": 4,
+ "uri": "https://api.nephoscale.com/key/password/72211/",
+ "key_type": 1,
+ "create_time": "2013-10-02 07:27:10",
+ "password": "23d493j5",
+ "id": 72211
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_sizes.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_sizes.json b/libcloud/test/compute/fixtures/nephoscale/list_sizes.json
new file mode 100644
index 0000000..c6d89f3
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_sizes.json
@@ -0,0 +1,178 @@
+{
+ "success": true,
+ "total_count": 13,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "sku": {
+ "name": "CS16.16",
+ "description": "Cloud Server 16 GB RAM, 16 Cores"
+ },
+ "storage": 800,
+ "ram": 16384,
+ "friendly_name": "CS16.16 - 16GB, 16Core, 800GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/1/",
+ "vcpus": 16,
+ "id": 1,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS1",
+ "description": "Cloud Server 1 GB RAM, 1 Core"
+ },
+ "storage": 50,
+ "ram": 1024,
+ "friendly_name": "CS1 - 1GB, 1Core, 50GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/3/",
+ "vcpus": 1,
+ "id": 3,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS05",
+ "description": "Cloud Server 0.5 GB RAM, 1 Core"
+ },
+ "storage": 25,
+ "ram": 512,
+ "friendly_name": "CS05 - 0.5GB, 1Core, 25GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/5/",
+ "vcpus": 1,
+ "id": 5,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS2.2",
+ "description": "Cloud Server 2 GB RAM, 2 Cores"
+ },
+ "storage": 100,
+ "ram": 2048,
+ "friendly_name": "CS2.2 - 2GB, 2Core, 100GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/7/",
+ "vcpus": 2,
+ "id": 7,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS4.4",
+ "description": "Cloud Server 4 GB RAM, 4 Cores"
+ },
+ "storage": 200,
+ "ram": 4096,
+ "friendly_name": "CS4.4 - 4GB, 4Core, 200GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/9/",
+ "vcpus": 4,
+ "id": 9,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS8.8",
+ "description": "Cloud Server 8 GB RAM, 8 Cores"
+ },
+ "storage": 400,
+ "ram": 8192,
+ "friendly_name": "CS8.8 - 8GB, 8Core, 400GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/11/",
+ "vcpus": 8,
+ "id": 11,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS025",
+ "description": "Cloud Server 0.25 GB RAM"
+ },
+ "storage": 15,
+ "ram": 256,
+ "friendly_name": "CS025 - 0.25GB, 10GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/27/",
+ "vcpus": 1,
+ "id": 27,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS2.1",
+ "description": "Cloud Server 2 GB RAM, 1 Core"
+ },
+ "storage": 75,
+ "ram": 2048,
+ "friendly_name": "CS2.1 - 2GB, 1Core, 75GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/46/",
+ "vcpus": 1,
+ "id": 46,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS4.2",
+ "description": "Cloud Server 4 GB RAM, 2 Cores"
+ },
+ "storage": 150,
+ "ram": 4096,
+ "friendly_name": "CS4.2 - 4GB, 2Core, 150GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/48/",
+ "vcpus": 2,
+ "id": 48,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS8.4",
+ "description": "Cloud Server 8 GB RAM, 4 Cores"
+ },
+ "storage": 300,
+ "ram": 8192,
+ "friendly_name": "CS8.4 - 8GB, 4Core, 300GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/50/",
+ "vcpus": 4,
+ "id": 50,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS16.8",
+ "description": "Cloud Server 16 GB RAM, 8 Cores"
+ },
+ "storage": 600,
+ "ram": 16384,
+ "friendly_name": "CS16.8 - 16GB, 8Core, 600GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/52/",
+ "vcpus": 8,
+ "id": 52,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS32.16",
+ "description": "Cloud Server 32 GB RAM, 16 Cores"
+ },
+ "storage": 1200,
+ "ram": 32768,
+ "friendly_name": "CS32.16 - 32GB, 16Core, 1200GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/54/",
+ "vcpus": 16,
+ "id": 54,
+ "billable_type": 1
+ },
+ {
+ "sku": {
+ "name": "CS32.8",
+ "description": "Cloud Server 32 GB RAM, 8 Cores"
+ },
+ "storage": 1000,
+ "ram": 32768,
+ "friendly_name": "CS32.8 - 32GB, 8Core, 1000GB",
+ "uri": "https://api.nephoscale.com/server/type/cloud/56/",
+ "vcpus": 8,
+ "id": 56,
+ "billable_type": 1
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/list_ssh_keys.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/list_ssh_keys.json b/libcloud/test/compute/fixtures/nephoscale/list_ssh_keys.json
new file mode 100644
index 0000000..dc83a8f
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/list_ssh_keys.json
@@ -0,0 +1,18 @@
+{
+ "success": true,
+ "total_count": 1,
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": [
+ {
+ "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBs+gQwoeFNa+4pYz2AKz5Op7EqrzeP3YsyTKxx7P9gt4aSt5w8Z+lRn3p3CVG+th5i6lZqOxWgCZ1kp2KEKNbSsA2HWl3OwkY8IqHGSEeMrF+3A2Ncz88kUIAWzCswxPY4uqb/yA4EzEQDk7PJj7Q1DruObhOm7qyHT40n2KJ3TqHJQlV9XE3RcXSaQcwUt0YFXFMx8wkgy0NKqqSiQuH8RofyfnOABEzKAARGbcQjZWxh2ITzUmwMxUCBa0X5wvblgcE6/pRZN5Xq6NQr2XEU5Z48+mLy6asdasdwrM0v10Y7ojDL/TosK/8T5+d5yaRsvtBlBstDZhNWY31n5iCLxx user@mistio",
+ "name": "mistio-ssh",
+ "key_group": 1,
+ "uri": "https://api.nephoscale.com/key/sshrsa/72209/",
+ "key_type": 2,
+ "create_time": "2013-10-02 07:24:37",
+ "id": 72209
+ }
+ ],
+ "response": 200
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/fixtures/nephoscale/success_action.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/nephoscale/success_action.json b/libcloud/test/compute/fixtures/nephoscale/success_action.json
new file mode 100644
index 0000000..62db155
--- /dev/null
+++ b/libcloud/test/compute/fixtures/nephoscale/success_action.json
@@ -0,0 +1,11 @@
+{
+ "subcode": 0,
+ "message": "Your request was processed successfully.",
+ "data": {
+ "id": 141229,
+ "resource_type": "/job",
+ "uri": "https://api.nephoscale.com/job/141229/"
+ },
+ "response": 202,
+ "success": true
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/da2fd8d8/libcloud/test/compute/test_nephoscale.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_nephoscale.py b/libcloud/test/compute/test_nephoscale.py
new file mode 100644
index 0000000..7a83808
--- /dev/null
+++ b/libcloud/test/compute/test_nephoscale.py
@@ -0,0 +1,189 @@
+# 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.
+#
+#Created by Markos Gogoulos (https://mist.io)
+#
+
+import sys
+import unittest
+from libcloud.utils.py3 import httplib
+
+from libcloud.compute.drivers.nephoscale import NephoscaleNodeDriver
+from libcloud.compute.base import Node
+
+from libcloud.test import MockHttp
+from libcloud.test.compute import TestCaseMixin
+from libcloud.test.file_fixtures import ComputeFileFixtures
+from libcloud.common.types import InvalidCredsError, LibcloudError
+
+
+class NephoScaleTest(unittest.TestCase, TestCaseMixin):
+ def setUp(self):
+ NephoscaleNodeDriver.connectionCls.conn_classes = (
+ None, NephoscaleMockHttp)
+ self.driver = NephoscaleNodeDriver('user', 'password')
+
+ def test_list_sizes(self):
+ sizes = self.driver.list_sizes()
+ self.assertEqual(len(sizes), 13)
+ for size in sizes:
+ self.assertEqual(type(size.disk), int)
+ self.assertEqual(type(size.ram), int)
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ self.assertEqual(len(images), 18)
+ for image in images:
+ arch = image.extra.get('architecture')
+ self.assertTrue(arch.startswith('x86'))
+
+ def test_list_locations(self):
+ locations = self.driver.list_locations()
+ self.assertEqual(len(locations), 2)
+ self.assertEqual(locations[0].name, "SJC-1")
+
+ def test_list_nodes(self):
+ nodes = self.driver.list_nodes()
+ self.assertEqual(len(nodes), 2)
+ self.assertEqual(nodes[0].extra.get('zone'), 'RIC-1')
+ self.assertEqual(nodes[0].name, 'mongodb-staging')
+ self.assertEqual(nodes[0].extra.get('service_type'),
+ 'CS05 - 0.5GB, 1Core, 25GB')
+
+ def test_list_keys(self):
+ keys = self.driver.ex_list_keypairs()
+ self.assertEqual(len(keys), 2)
+ self.assertEqual(keys[0].name, 'mistio-ssh')
+
+ def test_list_ssh_keys(self):
+ ssh_keys = self.driver.ex_list_keypairs(ssh=True)
+ self.assertEqual(len(ssh_keys), 1)
+ self.assertTrue(ssh_keys[0].public_key.startswith('ssh-rsa'))
+
+ def test_list_password_keys(self):
+ password_keys = self.driver.ex_list_keypairs(password=True)
+ self.assertEqual(len(password_keys), 1)
+ self.assertEquals(password_keys[0].password, '23d493j5')
+
+ def test_reboot_node(self):
+ node = self.driver.list_nodes()[0]
+ result = self.driver.reboot_node(node)
+ self.assertTrue(result)
+
+ def test_destroy_node(self):
+ node = self.driver.list_nodes()[0]
+ result = self.driver.destroy_node(node)
+ self.assertTrue(result)
+
+ def test_stop_node(self):
+ node = self.driver.list_nodes()[0]
+ result = self.driver.ex_stop_node(node)
+ self.assertTrue(result)
+
+ def test_start_node(self):
+ node = self.driver.list_nodes()[0]
+ result = self.driver.ex_start_node(node)
+ self.assertTrue(result)
+
+ def test_rename_node(self):
+ node = self.driver.list_nodes()[0]
+ result = self.driver.rename_node(node, 'new-name')
+ self.assertTrue(result)
+
+ def test_create_node(self):
+ name = 'mongodb-staging'
+ size = self.driver.list_sizes()[0]
+ image = self.driver.list_images()[3]
+ node = self.driver.create_node(name=name,
+ size=size,
+ nowait=True,
+ image=image)
+ self.assertEqual(node.name, 'mongodb-staging')
+
+ def test_create_node_no_name(self):
+ size = self.driver.list_sizes()[0]
+ image = self.driver.list_images()[3]
+ self.assertRaises(TypeError, self.driver.create_node, size=size,
+ image=image)
+
+ def test_delete_ssh_keys(self):
+ key = self.driver.ex_delete_keypair(key_id=72209, ssh=True)
+
+ def test_delete_password_keys(self):
+ key = self.driver.ex_delete_keypair(key_id=72211)
+
+
+class NephoscaleMockHttp(MockHttp):
+ fixtures = ComputeFileFixtures('nephoscale')
+
+ def _server_type_cloud(self, method, url, body, headers):
+ body = self.fixtures.load('list_sizes.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _server_cloud(self, method, url, body, headers):
+ if method == 'POST':
+ body = self.fixtures.load('success_action.json')
+ else:
+ body = self.fixtures.load('list_nodes.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _image_server(self, method, url, body, headers):
+ body = self.fixtures.load('list_images.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _datacenter_zone(self, method, url, body, headers):
+ body = self.fixtures.load('list_locations.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _key(self, method, url, body, headers):
+ body = self.fixtures.load('list_keys.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _key_sshrsa(self, method, url, body, headers):
+ body = self.fixtures.load('list_ssh_keys.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _key_password(self, method, url, body, headers):
+ body = self.fixtures.load('list_password_keys.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _server_cloud_88241(self, method, url, body, headers):
+ body = self.fixtures.load('success_action.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _server_cloud_88241_initiator_restart(self, method, url, body,
+ headers):
+ body = self.fixtures.load('success_action.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _server_cloud_88241_initiator_start(self, method, url, body, headers):
+ body = self.fixtures.load('success_action.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _server_cloud_88241_initiator_stop(self, method, url, body, headers):
+ body = self.fixtures.load('success_action.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _key_password_72211(self, method, url, body, headers):
+ body = self.fixtures.load('success_action.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _key_sshrsa_72209(self, method, url, body, headers):
+ body = self.fixtures.load('success_action.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
[5/5] git commit: pep8 fixes in the tests.
Posted by to...@apache.org.
pep8 fixes in the tests.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/34ec154b
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/34ec154b
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/34ec154b
Branch: refs/heads/trunk
Commit: 34ec154b125c9a7cf1717131dfe938fcf07876aa
Parents: 0ece13d
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Oct 7 13:10:45 2013 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Oct 7 13:10:45 2013 +0200
----------------------------------------------------------------------
libcloud/test/compute/test_nephoscale.py | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/34ec154b/libcloud/test/compute/test_nephoscale.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_nephoscale.py b/libcloud/test/compute/test_nephoscale.py
index 7a83808..cc3636a 100644
--- a/libcloud/test/compute/test_nephoscale.py
+++ b/libcloud/test/compute/test_nephoscale.py
@@ -21,18 +21,16 @@ import unittest
from libcloud.utils.py3 import httplib
from libcloud.compute.drivers.nephoscale import NephoscaleNodeDriver
-from libcloud.compute.base import Node
from libcloud.test import MockHttp
from libcloud.test.compute import TestCaseMixin
from libcloud.test.file_fixtures import ComputeFileFixtures
-from libcloud.common.types import InvalidCredsError, LibcloudError
class NephoScaleTest(unittest.TestCase, TestCaseMixin):
def setUp(self):
NephoscaleNodeDriver.connectionCls.conn_classes = (
- None, NephoscaleMockHttp)
+ NephoscaleMockHttp, NephoscaleMockHttp)
self.driver = NephoscaleNodeDriver('user', 'password')
def test_list_sizes(self):
@@ -119,10 +117,10 @@ class NephoScaleTest(unittest.TestCase, TestCaseMixin):
image=image)
def test_delete_ssh_keys(self):
- key = self.driver.ex_delete_keypair(key_id=72209, ssh=True)
+ self.assertTrue(self.driver.ex_delete_keypair(key_id=72209, ssh=True))
def test_delete_password_keys(self):
- key = self.driver.ex_delete_keypair(key_id=72211)
+ self.assertTrue(self.driver.ex_delete_keypair(key_id=72211))
class NephoscaleMockHttp(MockHttp):
[2/5] git commit: Fix pep8 issues.
Posted by to...@apache.org.
Fix pep8 issues.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/4bdf8462
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/4bdf8462
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/4bdf8462
Branch: refs/heads/trunk
Commit: 4bdf8462a846579270f279e1c90feb623e985ba9
Parents: da2fd8d
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Oct 7 13:07:06 2013 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Oct 7 13:07:06 2013 +0200
----------------------------------------------------------------------
libcloud/compute/drivers/nephoscale.py | 51 ++++++++++++-----------------
1 file changed, 21 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/4bdf8462/libcloud/compute/drivers/nephoscale.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/nephoscale.py b/libcloud/compute/drivers/nephoscale.py
index 80dba81..5d532c2 100644
--- a/libcloud/compute/drivers/nephoscale.py
+++ b/libcloud/compute/drivers/nephoscale.py
@@ -21,17 +21,10 @@ Created by Markos Gogoulos (https://mist.io)
import base64
import sys
-import string
-import random
import time
import os
import binascii
-try:
- import simplejson as json
-except:
- import json
-
from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import b
from libcloud.utils.py3 import urlencode
@@ -40,9 +33,9 @@ from libcloud.compute.providers import Provider
from libcloud.compute.base import is_private_subnet
from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.compute.types import (NodeState, InvalidCredsError,
- LibcloudError)
+ LibcloudError)
from libcloud.compute.base import (Node, NodeDriver, NodeImage, NodeSize,
- NodeLocation)
+ NodeLocation)
API_HOST = 'api.nephoscale.com'
@@ -115,7 +108,6 @@ class NephoscaleNodeDriver(NodeDriver):
"""
Nephoscale node driver class.
- >>> from libcloud.compute.types import Provider
>>> from libcloud.compute.providers import get_driver
>>> driver = get_driver('nephoscale')
>>> conn = driver('nepho_user','nepho_password')
@@ -161,7 +153,7 @@ class NephoscaleNodeDriver(NodeDriver):
'cores': value.get('cores'),
'uri': value.get('uri'),
'storage': value.get('storage'),
- }
+ }
image = NodeImage(id=value.get('id'),
name=value.get('friendly_name'),
driver=self,
@@ -273,7 +265,7 @@ get all keys call with no arguments')
return keys
def ex_create_keypair(self, name, public_key=None, password=None,
- key_group=None):
+ key_group=None):
"""Creates a key, ssh or password, for server or console
The group for the key (key_group) is 1 for Server and 4 for Console
Returns the id of the created key
@@ -289,7 +281,7 @@ get all keys call with no arguments')
}
params = urlencode(data)
result = self.connection.request('/key/sshrsa/', data=params,
- method='POST').object
+ method='POST').object
else:
if not key_group:
key_group = 4
@@ -302,7 +294,7 @@ get all keys call with no arguments')
}
params = urlencode(data)
result = self.connection.request('/key/password/', data=params,
- method='POST').object
+ method='POST').object
return result.get('data', {}).get('id', '')
def ex_delete_keypair(self, key_id, ssh=False):
@@ -313,7 +305,7 @@ get all keys call with no arguments')
method='DELETE').object
else:
result = self.connection.request('/key/password/%s/' % key_id,
- method='DELETE').object
+ method='DELETE').object
return result.get('response') in VALID_RESPONSE_CODES
def create_node(self, name, size, image, server_key=None,
@@ -324,7 +316,6 @@ get all keys call with no arguments')
times until the server is created and assigned a public IP address,
so that deploy_node can be run
- >>> from libcloud.compute.types import Provider
>>> from libcloud.compute.providers import get_driver
>>> driver = get_driver('nephoscale')
>>> conn = driver('nepho_user','nepho_password')
@@ -347,7 +338,7 @@ get all keys call with no arguments')
We can also create an ssh key, plus a console key and
deploy node with them
- >>> server_key = conn.ex_create_keypair(name, public_key=key)
+ >>> server_key = conn.ex_create_keypair(name, public_key='123')
71211
>>> console_key = conn.ex_create_keypair(name, key_group=4)
71213
@@ -358,13 +349,13 @@ get all keys call with no arguments')
We can also specify the location
>>> location = conn.list_locations()[0]
>>> node = conn.create_node(name=name,
- size=size,
- image=image,
- console_key=console_key,
- server_key=server_key,
- connect_attempts=10,
- nowait=True,
- zone=location.id)
+ ... size=size,
+ ... image=image,
+ ... console_key=console_key,
+ ... server_key=server_key,
+ ... connect_attempts=10,
+ ... nowait=True,
+ ... zone=location.id)
"""
try:
hostname = kwargs.get('hostname', name)
@@ -383,7 +374,7 @@ get all keys call with no arguments')
'server_key': server_key,
'console_key': console_key,
'zone': zone
- }
+ }
params = urlencode(data)
try:
@@ -406,7 +397,7 @@ get all keys call with no arguments')
while connect_attempts > 0:
nodes = self.list_nodes()
created_node = [c_node for c_node in nodes if
- c_node.name == name]
+ c_node.name == name]
if created_node:
return created_node[0]
else:
@@ -448,10 +439,10 @@ get all keys call with no arguments')
def _to_key(self, data):
return NodeKey(id=data.get('id'),
- name=data.get('name'),
- password=data.get('password'),
- key_group=data.get('key_group'),
- public_key=data.get('public_key'))
+ name=data.get('name'),
+ password=data.get('password'),
+ key_group=data.get('key_group'),
+ public_key=data.get('public_key'))
def random_password(self, size=8):
value = os.urandom(size)
[3/5] git commit: Remove try / except and raise which masks a more
specific exception.
Posted by to...@apache.org.
Remove try / except and raise which masks a more specific exception.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/9bbf21c1
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/9bbf21c1
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/9bbf21c1
Branch: refs/heads/trunk
Commit: 9bbf21c1284180e783eea4573ce188c29782bca5
Parents: 4bdf846
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Oct 7 13:08:12 2013 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Oct 7 13:08:12 2013 +0200
----------------------------------------------------------------------
libcloud/compute/drivers/nephoscale.py | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9bbf21c1/libcloud/compute/drivers/nephoscale.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/nephoscale.py b/libcloud/compute/drivers/nephoscale.py
index 5d532c2..dc100ce 100644
--- a/libcloud/compute/drivers/nephoscale.py
+++ b/libcloud/compute/drivers/nephoscale.py
@@ -357,15 +357,11 @@ get all keys call with no arguments')
... nowait=True,
... zone=location.id)
"""
- try:
- hostname = kwargs.get('hostname', name)
- service_type = size.id
- image = image.id
- connect_attempts = int(kwargs.get('connect_attempts',
- CONNECT_ATTEMPTS))
- except Exception:
- e = sys.exc_info()[1]
- raise Exception("Error on create node: %s" % e)
+ hostname = kwargs.get('hostname', name)
+ service_type = size.id
+ image = image.id
+ connect_attempts = int(kwargs.get('connect_attempts',
+ CONNECT_ATTEMPTS))
data = {'name': name,
'hostname': hostname,
[4/5] git commit: Updat docstring.
Posted by to...@apache.org.
Updat docstring.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0ece13d2
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0ece13d2
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0ece13d2
Branch: refs/heads/trunk
Commit: 0ece13d2db28b0d42239f17c325cfa644c50f1c8
Parents: 9bbf21c
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Oct 7 13:09:11 2013 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Oct 7 13:09:11 2013 +0200
----------------------------------------------------------------------
libcloud/pricing.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ece13d2/libcloud/pricing.py
----------------------------------------------------------------------
diff --git a/libcloud/pricing.py b/libcloud/pricing.py
index a4e9747..5e4cb89 100644
--- a/libcloud/pricing.py
+++ b/libcloud/pricing.py
@@ -133,7 +133,7 @@ def get_size_price(driver_type, driver_name, size_id):
:param size_id: Unique size ID (can be an integer or a string - depends on
the driver)
- :rtype: ``int``
+ :rtype: ``float``
:return: Size price.
"""
pricing = get_pricing(driver_type=driver_type, driver_name=driver_name)