You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by je...@apache.org on 2010/12/24 20:16:49 UTC
svn commit: r1052557 - in /incubator/libcloud/trunk: libcloud/
libcloud/drivers/ test/ test/fixtures/brightbox/
Author: jerry
Date: Fri Dec 24 19:16:48 2010
New Revision: 1052557
URL: http://svn.apache.org/viewvc?rev=1052557&view=rev
Log:
Brightbox Cloud Driver; LIBCLOUD-63
Submitted By: Tim Fletcher <ma...@tfletcher.com>
Added:
incubator/libcloud/trunk/libcloud/drivers/brightbox.py
incubator/libcloud/trunk/test/fixtures/brightbox/
incubator/libcloud/trunk/test/fixtures/brightbox/create_server.json
incubator/libcloud/trunk/test/fixtures/brightbox/list_images.json
incubator/libcloud/trunk/test/fixtures/brightbox/list_server_types.json
incubator/libcloud/trunk/test/fixtures/brightbox/list_servers.json
incubator/libcloud/trunk/test/fixtures/brightbox/list_zones.json
incubator/libcloud/trunk/test/fixtures/brightbox/token.json
incubator/libcloud/trunk/test/test_brightbox.py
Modified:
incubator/libcloud/trunk/libcloud/drivers/__init__.py
incubator/libcloud/trunk/libcloud/providers.py
incubator/libcloud/trunk/libcloud/types.py
incubator/libcloud/trunk/test/secrets.py-dist
Modified: incubator/libcloud/trunk/libcloud/drivers/__init__.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/drivers/__init__.py?rev=1052557&r1=1052556&r2=1052557&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/drivers/__init__.py (original)
+++ incubator/libcloud/trunk/libcloud/drivers/__init__.py Fri Dec 24 19:16:48 2010
@@ -18,6 +18,7 @@ Drivers for working with different provi
"""
__all__ = [
+ 'brightbox',
'dummy',
'ec2',
'ecp',
Added: incubator/libcloud/trunk/libcloud/drivers/brightbox.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/drivers/brightbox.py?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/libcloud/drivers/brightbox.py (added)
+++ incubator/libcloud/trunk/libcloud/drivers/brightbox.py Fri Dec 24 19:16:48 2010
@@ -0,0 +1,216 @@
+# 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.
+"""
+Brightbox Driver
+"""
+from libcloud.types import Provider, NodeState, InvalidCredsError
+from libcloud.base import ConnectionUserAndKey, Response, NodeDriver
+from libcloud.base import Node, NodeImage, NodeSize, NodeLocation
+import httplib
+import base64
+import json
+
+
+API_VERSION = '1.0'
+
+
+class BrightboxResponse(Response):
+ def success(self):
+ return self.status >= 200 and self.status < 400
+
+ def parse_body(self):
+ if self.headers['content-type'].split('; ')[0] == 'application/json' and len(self.body) > 0:
+ return json.loads(self.body)
+ else:
+ return self.body
+
+ def parse_error(self):
+ return json.loads(self.body)['error']
+
+
+class BrightboxConnection(ConnectionUserAndKey):
+ """
+ Connection class for the Brightbox driver
+ """
+
+ host = 'api.gb1.brightbox.com'
+ responseCls = BrightboxResponse
+
+ def _fetch_oauth_token(self):
+ body = json.dumps({'client_id': self.user_id, 'grant_type': 'none'})
+
+ authorization = 'Basic ' + base64.encodestring('%s:%s' % (self.user_id, self.key)).rstrip()
+
+ self.connect()
+
+ response = self.connection.request(method='POST', url='/token', body=body, headers={
+ 'Host': self.host,
+ 'User-Agent': self._user_agent(),
+ 'Authorization': authorization,
+ 'Content-Type': 'application/json',
+ 'Content-Length': str(len(body))
+ })
+
+ response = self.connection.getresponse()
+
+ if response.status == 200:
+ return json.loads(response.read())['access_token']
+ else:
+ message = '%s (%s)' % (json.loads(response.read())['error'], response.status)
+
+ raise InvalidCredsError, message
+
+ def add_default_headers(self, headers):
+ try:
+ headers['Authorization'] = 'OAuth ' + self.token
+ except AttributeError:
+ self.token = self._fetch_oauth_token()
+
+ headers['Authorization'] = 'OAuth ' + self.token
+
+ return headers
+
+ def encode_data(self, data):
+ return json.dumps(data)
+
+
+class BrightboxNodeDriver(NodeDriver):
+ """
+ Brightbox node driver
+ """
+
+ connectionCls = BrightboxConnection
+
+ type = Provider.BRIGHTBOX
+ name = 'Brightbox'
+
+ NODE_STATE_MAP = { 'creating': NodeState.PENDING,
+ 'active': NodeState.RUNNING,
+ 'inactive': NodeState.UNKNOWN,
+ 'deleting': NodeState.UNKNOWN,
+ 'deleted': NodeState.TERMINATED,
+ 'failed': NodeState.UNKNOWN }
+
+ def _to_node(self, data):
+ return Node(
+ id = data['id'],
+ name = data['name'],
+ state = self.NODE_STATE_MAP[data['status']],
+ public_ip = map(lambda cloud_ip: cloud_ip['public_ip'], data['cloud_ips']),
+ private_ip = map(lambda interface: interface['ipv4_address'], data['interfaces']),
+ driver = self.connection.driver,
+ extra = {
+ 'status': data['status'],
+ 'interfaces': data['interfaces']
+ }
+ )
+
+ def _to_image(self, data):
+ return NodeImage(
+ id = data['id'],
+ name = data['name'],
+ driver = self,
+ extra = {
+ 'description': data['description'],
+ 'arch': data['arch']
+ }
+ )
+
+ def _to_size(self, data):
+ return NodeSize(
+ id = data['id'],
+ name = data['name'],
+ ram = data['ram'],
+ disk = data['disk_size'],
+ bandwidth = 0,
+ price = '',
+ driver = self
+ )
+
+ def _to_location(self, data):
+ return NodeLocation(
+ id = data['id'],
+ name = data['handle'],
+ country = 'GB',
+ driver = self
+ )
+
+ def _post(self, path, data={}):
+ headers = {'Content-Type': 'application/json'}
+
+ return self.connection.request(path, data=data, headers=headers, method='POST')
+
+ def create_node(self, **kwargs):
+ data = {
+ 'name': kwargs['name'],
+ 'server_type': kwargs['size'].id,
+ 'image': kwargs['image'].id,
+ 'user_data': ''
+ }
+
+ if kwargs.has_key('location'):
+ data['zone'] = kwargs['location'].id
+ else:
+ data['zone'] = ''
+
+ data = self._post('/%s/servers' % API_VERSION, data).object
+
+ return self._to_node(data)
+
+ def destroy_node(self, node):
+ response = self.connection.request('/%s/servers/%s' % (API_VERSION, node.id), method='DELETE')
+
+ return response.status == httplib.ACCEPTED
+
+ def list_nodes(self):
+ data = self.connection.request('/%s/servers' % API_VERSION).object
+
+ return map(self._to_node, data)
+
+ def list_images(self):
+ data = self.connection.request('/%s/images' % API_VERSION).object
+
+ return map(self._to_image, data)
+
+ def list_sizes(self):
+ data = self.connection.request('/%s/server_types' % API_VERSION).object
+
+ return map(self._to_size, data)
+
+ def list_locations(self):
+ data = self.connection.request('/%s/zones' % API_VERSION).object
+
+ return map(self._to_location, data)
+
+ def ex_list_cloud_ips(self):
+ return self.connection.request('/%s/cloud_ips' % API_VERSION).object
+
+ def ex_create_cloud_ip(self):
+ return self._post('/%s/cloud_ips' % API_VERSION).object
+
+ def ex_map_cloud_ip(self, cloud_ip_id, interface_id):
+ response = self._post('/%s/cloud_ips/%s/map' % (API_VERSION, cloud_ip_id), {'interface': interface_id})
+
+ return response.status == httplib.ACCEPTED
+
+ def ex_unmap_cloud_ip(self, cloud_ip_id):
+ response = self._post('/%s/cloud_ips/%s/unmap' % (API_VERSION, cloud_ip_id))
+
+ return response.status == httplib.ACCEPTED
+
+ def ex_destroy_cloud_ip(self, cloud_ip_id):
+ response = self.connection.request('/%s/cloud_ips/%s' % (API_VERSION, cloud_ip_id), method='DELETE')
+
+ return response.status == httplib.OK
Modified: incubator/libcloud/trunk/libcloud/providers.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/providers.py?rev=1052557&r1=1052556&r2=1052557&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/providers.py (original)
+++ incubator/libcloud/trunk/libcloud/providers.py Fri Dec 24 19:16:48 2010
@@ -63,6 +63,8 @@ DRIVERS = {
('libcloud.drivers.opennebula', 'OpenNebulaNodeDriver'),
Provider.DREAMHOST:
('libcloud.drivers.dreamhost', 'DreamhostNodeDriver'),
+ Provider.BRIGHTBOX:
+ ('libcloud.drivers.brightbox', 'BrightboxNodeDriver'),
}
def get_driver(provider):
Modified: incubator/libcloud/trunk/libcloud/types.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/types.py?rev=1052557&r1=1052556&r2=1052557&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/types.py (original)
+++ incubator/libcloud/trunk/libcloud/types.py Fri Dec 24 19:16:48 2010
@@ -63,6 +63,7 @@ class Provider(object):
ELASTICHOSTS_US1 = 21
EC2_AP_SOUTHEAST = 22
RACKSPACE_UK = 23
+ BRIGHTBOX = 24
class NodeState(object):
"""
Added: incubator/libcloud/trunk/test/fixtures/brightbox/create_server.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/fixtures/brightbox/create_server.json?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/fixtures/brightbox/create_server.json (added)
+++ incubator/libcloud/trunk/test/fixtures/brightbox/create_server.json Fri Dec 24 19:16:48 2010
@@ -0,0 +1,62 @@
+{"id": "srv-3a97e",
+ "url": "servers/(server_id)",
+ "name": "My web server",
+ "status": "active",
+ "hostname": "srv-3a97e.gb1.brightbox.com",
+ "created_at": "",
+ "deleted_at": "",
+ "started_at": "",
+ "account":
+ {"id": "acc-3jd8s",
+ "url": "accounts/(account_id)",
+ "name": "Brightbox Systems Ltd.",
+ "status": "verified",
+ "ram_limit": 20480,
+ "ram_used": 2048,
+ "limits_cloudips": 5},
+ "image":
+ {"id": "img-9vxqi",
+ "url": "images/(image_id)",
+ "name": "Brightbox Lucid 32",
+ "status": "available",
+ "description": "Jeremy's debian ec2 image",
+ "source": "jeremy_debian-32_ec2",
+ "source_type": "upload",
+ "arch": "32-bit",
+ "created_at": "",
+ "owner": "acc-bright"},
+ "server_type":
+ {"id": "typ-a97e6",
+ "url": "server_types/(server_type_id)",
+ "handle": "nano",
+ "name": "Brightbox Nano",
+ "status": "",
+ "cores": 2,
+ "ram": 2048,
+ "disk_size": ""},
+ "zone":
+ {"id": "zon-8ja0a",
+ "url": "zones/(zone_id)",
+ "handle": "gb1-a"},
+ "snapshots":
+ [{"id": "img-9vxqi",
+ "url": "images/(image_id)",
+ "name": "Brightbox Lucid 32",
+ "status": "available",
+ "description": "Jeremy's debian ec2 image",
+ "source": "jeremy_debian-32_ec2",
+ "source_type": "upload",
+ "arch": "32-bit",
+ "created_at": "",
+ "owner": "acc-bright"}],
+ "cloud_ips":
+ [{"id": "cip-ja8ub",
+ "url": "cloud_ips/(cloud_ip_id)",
+ "public_ip": "109.107.42.129",
+ "status": "mapped",
+ "reverse_dns": "cip-109-107-42-129.gb1.brightbox.com"}],
+ "interfaces":
+ [{"id": "int-mc3a9",
+ "url": "interfaces/(interface_id)",
+ "mac_address": "02:24:19:6e:18:36",
+ "ipv4_address": "10.110.24.54"}]}
\ No newline at end of file
Added: incubator/libcloud/trunk/test/fixtures/brightbox/list_images.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/fixtures/brightbox/list_images.json?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/fixtures/brightbox/list_images.json (added)
+++ incubator/libcloud/trunk/test/fixtures/brightbox/list_images.json Fri Dec 24 19:16:48 2010
@@ -0,0 +1,21 @@
+[{"id": "img-9vxqi",
+ "url": "images/(image_id)",
+ "name": "Brightbox Lucid 32",
+ "status": "available",
+ "description": "Jeremy's debian ec2 image",
+ "source": "jeremy_debian-32_ec2",
+ "source_type": "upload",
+ "arch": "32-bit",
+ "created_at": "",
+ "owner": "acc-bright",
+ "ancestor":
+ {"id": "img-9vxqi",
+ "url": "images/(image_id)",
+ "name": "Brightbox Lucid 32",
+ "status": "available",
+ "description": "Jeremy's debian ec2 image",
+ "source": "jeremy_debian-32_ec2",
+ "source_type": "upload",
+ "arch": "32-bit",
+ "created_at": "",
+ "owner": "acc-bright"}}]
Added: incubator/libcloud/trunk/test/fixtures/brightbox/list_server_types.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/fixtures/brightbox/list_server_types.json?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/fixtures/brightbox/list_server_types.json (added)
+++ incubator/libcloud/trunk/test/fixtures/brightbox/list_server_types.json Fri Dec 24 19:16:48 2010
@@ -0,0 +1,8 @@
+[{"id": "typ-4nssg",
+ "url": "server_types/typ-4nssg",
+ "handle": "nano",
+ "name": "Brightbox Nano Instance",
+ "status": "",
+ "cores": 1,
+ "ram": 512,
+ "disk_size": 10240}]
Added: incubator/libcloud/trunk/test/fixtures/brightbox/list_servers.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/fixtures/brightbox/list_servers.json?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/fixtures/brightbox/list_servers.json (added)
+++ incubator/libcloud/trunk/test/fixtures/brightbox/list_servers.json Fri Dec 24 19:16:48 2010
@@ -0,0 +1,62 @@
+[{"id": "srv-3a97e",
+ "url": "servers/(server_id)",
+ "name": "My web server",
+ "status": "active",
+ "hostname": "srv-3a97e.gb1.brightbox.com",
+ "created_at": "",
+ "deleted_at": "",
+ "started_at": "",
+ "account":
+ {"id": "acc-3jd8s",
+ "url": "accounts/(account_id)",
+ "name": "Brightbox Systems Ltd.",
+ "status": "verified",
+ "ram_limit": 20480,
+ "ram_used": 2048,
+ "limits_cloudips": 5},
+ "image":
+ {"id": "img-9vxqi",
+ "url": "images/(image_id)",
+ "name": "Brightbox Lucid 32",
+ "status": "available",
+ "description": "Jeremy's debian ec2 image",
+ "source": "jeremy_debian-32_ec2",
+ "source_type": "upload",
+ "arch": "32-bit",
+ "created_at": "",
+ "owner": "acc-bright"},
+ "server_type":
+ {"id": "typ-a97e6",
+ "url": "server_types/(server_type_id)",
+ "handle": "nano",
+ "name": "Brightbox Nano",
+ "status": "",
+ "cores": 2,
+ "ram": 2048,
+ "disk_size": ""},
+ "zone":
+ {"id": "zon-8ja0a",
+ "url": "zones/(zone_id)",
+ "handle": "gb1-a"},
+ "snapshots":
+ [{"id": "img-9vxqi",
+ "url": "images/(image_id)",
+ "name": "Brightbox Lucid 32",
+ "status": "available",
+ "description": "Jeremy's debian ec2 image",
+ "source": "jeremy_debian-32_ec2",
+ "source_type": "upload",
+ "arch": "32-bit",
+ "created_at": "",
+ "owner": "acc-bright"}],
+ "cloud_ips":
+ [{"id": "cip-ja8ub",
+ "url": "cloud_ips/(cloud_ip_id)",
+ "public_ip": "109.107.42.129",
+ "status": "mapped",
+ "reverse_dns": "cip-109-107-42-129.gb1.brightbox.com"}],
+ "interfaces":
+ [{"id": "int-mc3a9",
+ "url": "interfaces/(interface_id)",
+ "mac_address": "02:24:19:6e:18:36",
+ "ipv4_address": "10.110.24.54"}]}]
Added: incubator/libcloud/trunk/test/fixtures/brightbox/list_zones.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/fixtures/brightbox/list_zones.json?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/fixtures/brightbox/list_zones.json (added)
+++ incubator/libcloud/trunk/test/fixtures/brightbox/list_zones.json Fri Dec 24 19:16:48 2010
@@ -0,0 +1,3 @@
+[{"id": "zon-8ja0a",
+ "url": "zones/(zone_id)",
+ "handle": "gb1-a"}]
Added: incubator/libcloud/trunk/test/fixtures/brightbox/token.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/fixtures/brightbox/token.json?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/fixtures/brightbox/token.json (added)
+++ incubator/libcloud/trunk/test/fixtures/brightbox/token.json Fri Dec 24 19:16:48 2010
@@ -0,0 +1 @@
+{"access_token":"k1bjflpsaj8wnrbrwzad0eqo36nxiha", "expires_in": 3600}
Modified: incubator/libcloud/trunk/test/secrets.py-dist
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/secrets.py-dist?rev=1052557&r1=1052556&r2=1052557&view=diff
==============================================================================
--- incubator/libcloud/trunk/test/secrets.py-dist (original)
+++ incubator/libcloud/trunk/test/secrets.py-dist Fri Dec 24 19:16:48 2010
@@ -20,6 +20,9 @@
EC2_ACCESS_ID='YoUR K3Y'
EC2_SECRET='secr3t'
+BRIGHTBOX_CLIENT_ID=''
+BRIGHTBOX_CLIENT_SECRET=''
+
RACKSPACE_USER=''
RACKSPACE_KEY=''
Added: incubator/libcloud/trunk/test/test_brightbox.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/test_brightbox.py?rev=1052557&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/test_brightbox.py (added)
+++ incubator/libcloud/trunk/test/test_brightbox.py Fri Dec 24 19:16:48 2010
@@ -0,0 +1,123 @@
+# 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, unittest, httplib, json
+
+from libcloud.drivers.brightbox import BrightboxNodeDriver
+from libcloud.types import NodeState, InvalidCredsError
+
+from test import MockHttp, TestCaseMixin
+from test.file_fixtures import FileFixtures
+from secrets import BRIGHTBOX_CLIENT_ID, BRIGHTBOX_CLIENT_SECRET
+
+
+class BrightboxTest(unittest.TestCase, TestCaseMixin):
+ def setUp(self):
+ BrightboxNodeDriver.connectionCls.conn_classes = (None, BrightboxMockHttp)
+ BrightboxMockHttp.type = None
+ self.driver = BrightboxNodeDriver(BRIGHTBOX_CLIENT_ID, BRIGHTBOX_CLIENT_SECRET)
+
+ def test_authentication(self):
+ BrightboxMockHttp.type = 'INVALID_CLIENT'
+ self.assertRaises(InvalidCredsError, self.driver.list_nodes)
+
+ BrightboxMockHttp.type = 'UNAUTHORIZED_CLIENT'
+ self.assertRaises(InvalidCredsError, self.driver.list_nodes)
+
+ def test_list_nodes(self):
+ nodes = self.driver.list_nodes()
+ self.assertEqual(len(nodes), 1)
+ self.assertTrue('109.107.42.129' in nodes[0].public_ip)
+ self.assertTrue('10.110.24.54' in nodes[0].private_ip)
+ self.assertEqual(nodes[0].state, NodeState.RUNNING)
+
+ def test_list_sizes(self):
+ sizes = self.driver.list_sizes()
+ self.assertEqual(len(sizes), 1)
+ self.assertEqual(sizes[0].id, 'typ-4nssg')
+ self.assertEqual(sizes[0].name, 'Brightbox Nano Instance')
+ self.assertEqual(sizes[0].ram, 512)
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ self.assertEqual(len(images), 1)
+ self.assertEqual(images[0].id, 'img-9vxqi')
+ self.assertEqual(images[0].name, 'Brightbox Lucid 32')
+ self.assertEqual(images[0].extra['arch'], '32-bit')
+
+ def test_reboot_node_response(self):
+ node = self.driver.list_nodes()[0]
+ self.assertRaises(NotImplementedError, self.driver.reboot_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):
+ size = self.driver.list_sizes()[0]
+ image = self.driver.list_images()[0]
+ node = self.driver.create_node(name='Test Node', image=image, size=size)
+ self.assertEqual('srv-3a97e', node.id)
+ self.assertEqual('Test Node', node.name)
+
+
+class BrightboxMockHttp(MockHttp):
+ fixtures = FileFixtures('brightbox')
+
+ def _token(self, method, url, body, headers):
+ if method == 'POST':
+ return self.response(httplib.OK, self.fixtures.load('token.json'))
+
+ def _token_INVALID_CLIENT(self, method, url, body, headers):
+ if method == 'POST':
+ return self.response(httplib.BAD_REQUEST, '{"error":"invalid_client"}')
+
+ def _token_UNAUTHORIZED_CLIENT(self, method, url, body, headers):
+ if method == 'POST':
+ return self.response(httplib.UNAUTHORIZED, '{"error":"unauthorized_client"}')
+
+ def _1_0_images(self, method, url, body, headers):
+ if method == 'GET':
+ return self.response(httplib.OK, self.fixtures.load('list_images.json'))
+
+ def _1_0_servers(self, method, url, body, headers):
+ if method == 'GET':
+ return self.response(httplib.OK, self.fixtures.load('list_servers.json'))
+ elif method == 'POST':
+ body = json.loads(body)
+
+ node = json.loads(self.fixtures.load('create_server.json'))
+
+ node['name'] = body['name']
+
+ return self.response(httplib.ACCEPTED, json.dumps(node))
+
+ def _1_0_servers_srv_3a97e(self, method, url, body, headers):
+ if method == 'DELETE':
+ return self.response(httplib.ACCEPTED, '')
+
+ def _1_0_server_types(self, method, url, body, headers):
+ if method == 'GET':
+ return self.response(httplib.OK, self.fixtures.load('list_server_types.json'))
+
+ def _1_0_zones(self, method, url, body, headers):
+ if method == 'GET':
+ return self.response(httplib.OK, self.fixtures.load('list_zones.json'))
+
+ def response(self, status, body):
+ return (status, body, {'content-type': 'application/json'}, httplib.responses[status])
+
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())