An update patch for the OpenNebula compute node for consideration.
Changes:
* Removed unused JSON import.
* Added two new node drivers for OpenNebula, for OpenNebula v3.0 and
v3.2, which support additional functionality over the OpenNebula v2.0
driver.
* Added test suites for those additional capabilities.
* Removed destroy() from OpenNebulaNetwork which is not supported by
the compute node driver.
* Removed unused assignments, mostly pertaining to ET.SubElement.
* Added ability to define the name under which the node image will be
saved after shutting down for v3.0+.
* Added support for a network attribute for v3.0+.
* Added support for the upcoming OpenNebula v3.2, and it's new instance
type interface.
* Added additional tests for a more complete test coverage.-- Hutson Betts Computer Science and Engineering Texas A&M University
=== modified file 'libcloud/compute/drivers/opennebula.py'
--- libcloud/compute/drivers/opennebula.py 2011-12-05 00:22:16 +0000
+++ libcloud/compute/drivers/opennebula.py 2011-12-06 07:44:04 +0000
@@ -22,11 +22,6 @@
__docformat__ = 'epytext'
-try:
- import simplejson as json
-except ImportError:
- import json
-
from xml.etree import ElementTree as ET
from base64 import b64encode
import hashlib
@@ -49,7 +44,9 @@
'OpenNebulaNetwork',
'OpenNebulaNodeDriver',
'OpenNebula_1_4_NodeDriver',
- 'OpenNebula_2_0_NodeDriver']
+ 'OpenNebula_2_0_NodeDriver',
+ 'OpenNebula_3_0_NodeDriver',
+ 'OpenNebula_3_2_NodeDriver']
API_HOST = ''
API_PORT = (4567, 443)
@@ -197,24 +194,8 @@
@rtype: C{string}
@return: Unique identifier for this instance.
"""
- return hashlib.sha1(b("%s:%d" % (self.id, self.driver.type))).hexdigest()
-
- def destroy(self):
- """
- Destroy this network.
-
- This calls the networks's driver and destroys the network.
-
- >>> from libcloud.network.drivers.dummy import DummyNetworkDriver
- >>> driver = DummyNetworkDriver()
- >>> network = driver.create_network()
- >>> network.destroy()
- True
-
- @return: True is the network was destroyed, else False.
- @rtype: C{bool}
- """
- return self.driver.destroy_network(self)
+ return hashlib.sha1(b("%s:%d" % (self.id,
+ self.driver.type))).hexdigest()
def __repr__(self):
return (('<OpenNebulaNetwork: uuid=%s, name=%s, address=%s, size=%s, '
@@ -250,8 +231,12 @@
if cls is OpenNebulaNodeDriver:
if api_version in ['1.4']:
cls = OpenNebula_1_4_NodeDriver
- elif api_version in ['2.0', '2.2', '3.0', '3.2']:
+ elif api_version in ['2.0', '2.2']:
cls = OpenNebula_2_0_NodeDriver
+ elif api_version in ['3.0']:
+ cls = OpenNebula_3_0_NodeDriver
+ elif api_version in ['3.2']:
+ cls = OpenNebula_3_2_NodeDriver
else:
raise NotImplementedError(
"No OpenNebulaNodeDriver found for API version %s" %
@@ -280,7 +265,7 @@
instance_type.text = kwargs['size'].name
storage = ET.SubElement(compute, 'STORAGE')
- disk = ET.SubElement(storage, 'DISK', {'image': '%s' %
+ ET.SubElement(storage, 'DISK', {'image': '%s' %
(str(kwargs['image'].id))})
if 'networks' in kwargs:
@@ -290,11 +275,11 @@
networkGroup = ET.SubElement(compute, 'NETWORK')
for network in kwargs['networks']:
if network.address:
- nic = ET.SubElement(networkGroup, 'NIC',
+ ET.SubElement(networkGroup, 'NIC',
{'network': '%s' % (str(network.id)),
'ip': network.address})
else:
- nic = ET.SubElement(networkGroup, 'NIC',
+ ET.SubElement(networkGroup, 'NIC',
{'network': '%s' % (str(network.id))})
xml = ET.tostring(compute)
@@ -396,7 +381,7 @@
compute = ET.Element('COMPUTE')
compute_id = ET.SubElement(compute, 'ID')
- compute_id.text = str(compute_node_id)
+ compute_id.text = compute_node_id
state = ET.SubElement(compute, 'STATE')
state.text = action
@@ -528,12 +513,10 @@
except KeyError:
state = NodeState.UNKNOWN
- networks = self._extract_networks(compute)
-
return Node(id=compute.findtext('ID'),
name=compute.findtext('NAME'),
state=state,
- public_ips=networks,
+ public_ips=self._extract_networks(compute),
private_ips=[],
driver=self.connection.driver,
image=self._extract_images(compute))
@@ -607,7 +590,7 @@
class OpenNebula_2_0_NodeDriver(OpenNebulaNodeDriver):
"""
OpenNebula.org node driver for OpenNebula.org v2.0 through OpenNebula.org
- v3.2.
+ v2.2.
"""
def create_node(self, **kwargs):
@@ -635,7 +618,7 @@
instance_type.text = kwargs['size'].name
disk = ET.SubElement(compute, 'DISK')
- storage = ET.SubElement(disk, 'STORAGE', {'href': '/storage/%s' %
+ ET.SubElement(disk, 'STORAGE', {'href': '/storage/%s' %
(str(kwargs['image'].id))})
if 'networks' in kwargs:
@@ -644,7 +627,7 @@
for network in kwargs['networks']:
nic = ET.SubElement(compute, 'NIC')
- network_line = ET.SubElement(nic, 'NETWORK',
+ ET.SubElement(nic, 'NETWORK',
{'href': '/network/%s' % (str(network.id))})
if network.address:
ip_line = ET.SubElement(nic, 'IP')
@@ -772,12 +755,10 @@
except KeyError:
state = NodeState.UNKNOWN
- networks = self._extract_networks(compute)
-
return Node(id=compute.findtext('ID'),
name=compute.findtext('NAME'),
state=state,
- public_ips=networks,
+ public_ips=self._extract_networks(compute),
private_ips=[],
driver=self.connection.driver,
image=self._extract_images(compute),
@@ -889,3 +870,115 @@
contexts[context_element.tag.lower()] = context_element.text
return contexts
+
+
+class OpenNebula_3_0_NodeDriver(OpenNebula_2_0_NodeDriver):
+ """
+ OpenNebula.org node driver for OpenNebula.org v3.0.
+ """
+
+ def ex_node_set_save_name(self, node, name):
+ """
+ Build action representation and instruct node to commit action.
+
+ Build action representation from the compute node ID, the disk image
+ which will be saved, and the name under which the image will be saved
+ upon shutting down the compute node.
+
+ @type node: L{Node}
+ @param node: Compute node instance.
+ @type name: C{str}
+ @param name: Name under which the image should be saved after shutting
+ down the compute node.
+
+ @rtype: C{bool}
+ @return: False if an HTTP Bad Request is received, else, True is
+ returned.
+ """
+ compute_node_id = str(node.id)
+
+ compute = ET.Element('COMPUTE')
+
+ compute_id = ET.SubElement(compute, 'ID')
+ compute_id.text = compute_node_id
+
+ disk = ET.SubElement(compute, 'DISK', {'id': str(node.image.id)})
+
+ ET.SubElement(disk, 'STORAGE', {'href': '/storage/%s' %
+ (str(node.image.id)),
+ 'name': node.image.name})
+
+ ET.SubElement(disk, 'SAVE_AS', {'name': str(name)})
+
+ xml = ET.tostring(compute)
+
+ url = '/compute/%s' % compute_node_id
+ resp = self.connection.request(url, method='PUT',
+ data=xml)
+
+ if resp.status == httplib.BAD_REQUEST:
+ return False
+ else:
+ return True
+
+ def _to_network(self, element):
+ """
+ Take XML object containing a network description and convert to
+ OpenNebulaNetwork object.
+
+ Take XML representation containing a network description and
+ convert to OpenNebulaNetwork object.
+
+ @rtype: L{OpenNebulaNetwork}
+ @return: The newly extracted L{OpenNebulaNetwork}.
+ """
+ return OpenNebulaNetwork(id=element.findtext('ID'),
+ name=element.findtext('NAME'),
+ address=element.findtext('ADDRESS'),
+ size=element.findtext('SIZE'),
+ driver=self.connection.driver,
+ extra={'public': element.findtext('PUBLIC')})
+
+
+class OpenNebula_3_2_NodeDriver(OpenNebula_3_0_NodeDriver):
+ """
+ OpenNebula.org node driver for OpenNebula.org v3.2.
+ """
+
+ def list_sizes(self, location=None):
+ """
+ Return list of sizes on a provider.
+
+ See L{NodeDriver.list_sizes} for more args.
+
+ @rtype: C{list} of L{OpenNebulaNodeSize}
+ @return: List of compute node sizes supported by the cloud provider.
+ """
+ return self._to_sizes(self.connection.request('/instance_type').object)
+
+ def _to_sizes(self, object):
+ """
+ Request a list of instance types and convert that list to a list of
+ OpenNebulaNodeSize objects.
+
+ Request a list of instance types from the OpenNebula web interface,
+ and issue a request to convert each XML object representation of an
+ instance type to an OpenNebulaNodeSize object.
+
+ @rtype: C{list} of L{OpenNebulaNodeSize}
+ @return: List of instance types.
+ """
+ sizes = []
+ ids = 1
+ for element in object.findall('INSTANCE_TYPE'):
+ sizes.append(OpenNebulaNodeSize(id=ids,
+ name=element.findtext('NAME'),
+ ram=int(element.findtext('MEMORY', None)),
+ cpu=int(element.findtext('CPU', None)),
+ disk=element.findtext('DISK', None),
+ bandwidth=element.findtext('BANDWIDTH', None),
+ price=element.findtext('PRICE', None),
+ driver=self))
+ ids += 1
+
+ return sizes
=== added file 'test/compute/fixtures/opennebula_2_0/compute_25.xml'
--- test/compute/fixtures/opennebula_2_0/compute_25.xml 1970-01-01 00:00:00 +0000
+++ test/compute/fixtures/opennebula_2_0/compute_25.xml 2011-12-05 06:50:32 +0000
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<COMPUTE href='http://www.opennebula.org/compute/25'>
+ <ID>25</ID>
+ <NAME>Compute 25</NAME>
+ <INSTANCE_TYPE>none</INSTANCE_TYPE>
+ <STATE>none</STATE>
+ <NIC>
+ <NETWORK href='http://www.opennebula.org/network/5' name='Network 5'/>
+ <IP>192.168.0.3</IP>
+ <MAC>02:00:c0:a8:00:03</MAC>
+ </NIC>
+ <NIC>
+ <NETWORK href='http://www.opennebula.org/network/15' name='Network 15'/>
+ <IP>192.168.1.3</IP>
+ <MAC>02:00:c0:a8:01:03</MAC>
+ </NIC>
+ <CONTEXT>
+ <HOSTNAME>compute-25</HOSTNAME>
+ </CONTEXT>
+</COMPUTE>
=== modified file 'test/compute/fixtures/opennebula_2_0/compute_collection.xml'
--- test/compute/fixtures/opennebula_2_0/compute_collection.xml 2011-12-05 00:22:16 +0000
+++ test/compute/fixtures/opennebula_2_0/compute_collection.xml 2011-12-05 06:17:24 +0000
@@ -2,4 +2,5 @@
<COMPUTE_COLLECTION>
<COMPUTE href="http://www.opennebula.org/compute/5" name="Compute 5"/>
<COMPUTE href="http://www.opennebula.org/compute/15" name="Compute 15"/>
+ <COMPUTE href="http://www.opennebula.org/compute/25" name="Compute 25"/>
</COMPUTE_COLLECTION>
=== added directory 'test/compute/fixtures/opennebula_3_0'
=== added file 'test/compute/fixtures/opennebula_3_0/network_15.xml'
--- test/compute/fixtures/opennebula_3_0/network_15.xml 1970-01-01 00:00:00 +0000
+++ test/compute/fixtures/opennebula_3_0/network_15.xml 2011-12-05 03:35:24 +0000
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<NETWORK>
+ <ID>15</ID>
+ <NAME>Network 15</NAME>
+ <ADDRESS>192.168.1.0</ADDRESS>
+ <SIZE>256</SIZE>
+ <PUBLIC>NO</PUBLIC>
+</NETWORK>
=== added file 'test/compute/fixtures/opennebula_3_0/network_5.xml'
--- test/compute/fixtures/opennebula_3_0/network_5.xml 1970-01-01 00:00:00 +0000
+++ test/compute/fixtures/opennebula_3_0/network_5.xml 2011-12-05 03:35:30 +0000
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<NETWORK>
+ <ID>5</ID>
+ <NAME>Network 5</NAME>
+ <ADDRESS>192.168.0.0</ADDRESS>
+ <SIZE>256</SIZE>
+ <PUBLIC>YES</PUBLIC>
+</NETWORK>
=== added file 'test/compute/fixtures/opennebula_3_0/network_collection.xml'
--- test/compute/fixtures/opennebula_3_0/network_collection.xml 1970-01-01 00:00:00 +0000
+++ test/compute/fixtures/opennebula_3_0/network_collection.xml 2011-12-05 00:38:18 +0000
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<NETWORK_COLLECTION>
+ <NETWORK href="http://www.opennebula.org/network/5" name="Network 5"/>
+ <NETWORK href="http://www.opennebula.org/network/15" name="Network 15"/>
+</NETWORK_COLLECTION>
=== added directory 'test/compute/fixtures/opennebula_3_2'
=== added file 'test/compute/fixtures/opennebula_3_2/instance_type_collection.xml'
--- test/compute/fixtures/opennebula_3_2/instance_type_collection.xml 1970-01-01 00:00:00 +0000
+++ test/compute/fixtures/opennebula_3_2/instance_type_collection.xml 2011-12-05 04:33:14 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<INSTANCE_TYPE_COLLECTION>
+ <INSTANCE_TYPE href="http://www.opennebula.org/instance_type/small">
+ <NAME>small</NAME>
+ <CPU>1</CPU>
+ <MEMORY>1024</MEMORY>
+ </INSTANCE_TYPE>
+ <INSTANCE_TYPE href="http://www.opennebula.org/instance_type/medium">
+ <NAME>medium</NAME>
+ <CPU>4</CPU>
+ <MEMORY>4096</MEMORY>
+ </INSTANCE_TYPE>
+ <INSTANCE_TYPE href="http://www.opennebula.org/instance_type/large">
+ <NAME>large</NAME>
+ <CPU>8</CPU>
+ <MEMORY>8192</MEMORY>
+ </INSTANCE_TYPE>
+</INSTANCE_TYPE_COLLECTION>
=== modified file 'test/compute/test_opennebula.py'
--- test/compute/test_opennebula.py 2011-12-05 00:22:16 +0000
+++ test/compute/test_opennebula.py 2011-12-06 07:44:45 +0000
@@ -31,12 +31,27 @@
from libcloud.compute.drivers.opennebula import *
from test.file_fixtures import ComputeFileFixtures
+from libcloud.common.types import InvalidCredsError
+from test import MockResponse, MockHttp
from test.compute import TestCaseMixin
-from test import MockHttp
from test.secrets import OPENNEBULA_PARAMS
+class OpenNebula_ResponseTests(unittest.TestCase):
+ XML = """<?xml version="1.0" encoding="UTF-8"?><root/>"""
+
+ def test_unauthorized_response(self):
+ http_response = MockResponse(httplib.UNAUTHORIZED,
+ OpenNebula_ResponseTests.XML,
+ headers={'content-type':
+ 'application/xml'})
+ try:
+ OpenNebulaResponse(http_response, None).parse_body()
+ except InvalidCredsError as detail:
+ self.assertEqual(type(detail), type(InvalidCredsError()))
+
+
class OpenNebula_1_4_Tests(unittest.TestCase, TestCaseMixin):
"""
OpenNebula.org test suite for OpenNebula v1.4.
@@ -217,7 +232,7 @@
self.assertEqual(network.address, '192.168.1.0')
self.assertEqual(network.size, '256')
- def test_node_action(self):
+ def test_ex_node_action(self):
"""
Test ex_node_action functionality.
"""
@@ -228,7 +243,7 @@
class OpenNebula_2_0_Tests(unittest.TestCase, TestCaseMixin):
"""
- OpenNebula.org test suite for OpenNebula v2.0 through v3.2.
+ OpenNebula.org test suite for OpenNebula v2.0 through v2.2.
"""
def setUp(self):
@@ -304,7 +319,7 @@
"""
nodes = self.driver.list_nodes()
- self.assertEqual(len(nodes), 2)
+ self.assertEqual(len(nodes), 3)
node = nodes[0]
self.assertEqual(node.id, '5')
self.assertEqual(node.name, 'Compute 5')
@@ -323,6 +338,18 @@
self.assertEqual(node.private_ips, [])
self.assertTrue(len([size for size in self.driver.list_sizes() \
if size.id == node.size.id]) == 1)
+ self.assertEqual(node.size.id, '1')
+ self.assertEqual(node.size.name, 'small')
+ self.assertEqual(node.size.ram, 1024)
+ self.assertTrue(node.size.cpu is None or isinstance(size.cpu, int))
+ self.assertTrue(node.size.vcpu is None or isinstance(size.vcpu, int))
+ self.assertEqual(node.size.cpu, 1)
+ self.assertEqual(node.size.vcpu, None)
+ self.assertEqual(node.size.disk, None)
+ self.assertEqual(node.size.bandwidth, None)
+ self.assertEqual(node.size.price, None)
+ self.assertTrue(len([image for image in self.driver.list_images() \
+ if image.id == node.image.id]) == 1)
self.assertEqual(node.image.id, '5')
self.assertEqual(node.image.name, 'Ubuntu 9.04 LAMP')
self.assertEqual(node.image.extra['type'], 'DISK')
@@ -347,12 +374,44 @@
self.assertEqual(node.private_ips, [])
self.assertTrue(len([size for size in self.driver.list_sizes() \
if size.id == node.size.id]) == 1)
+ self.assertEqual(node.size.id, '1')
+ self.assertEqual(node.size.name, 'small')
+ self.assertEqual(node.size.ram, 1024)
+ self.assertTrue(node.size.cpu is None or isinstance(size.cpu, int))
+ self.assertTrue(node.size.vcpu is None or isinstance(size.vcpu, int))
+ self.assertEqual(node.size.cpu, 1)
+ self.assertEqual(node.size.vcpu, None)
+ self.assertEqual(node.size.disk, None)
+ self.assertEqual(node.size.bandwidth, None)
+ self.assertEqual(node.size.price, None)
+ self.assertTrue(len([image for image in self.driver.list_images() \
+ if image.id == node.image.id]) == 1)
self.assertEqual(node.image.id, '15')
self.assertEqual(node.image.name, 'Ubuntu 9.04 LAMP')
self.assertEqual(node.image.extra['type'], 'DISK')
self.assertEqual(node.image.extra['target'], 'hda')
context = node.extra['context']
self.assertEqual(context['hostname'], 'compute-15')
+ node = nodes[2]
+ self.assertEqual(node.id, '25')
+ self.assertEqual(node.name, 'Compute 25')
+ self.assertEqual(node.state,
+ OpenNebulaNodeDriver.NODE_STATE_MAP['UNKNOWN'])
+ self.assertEqual(node.public_ips[0].id, '5')
+ self.assertEqual(node.public_ips[0].name, 'Network 5')
+ self.assertEqual(node.public_ips[0].address, '192.168.0.3')
+ self.assertEqual(node.public_ips[0].size, 1)
+ self.assertEqual(node.public_ips[0].extra['mac'], '02:00:c0:a8:00:03')
+ self.assertEqual(node.public_ips[1].id, '15')
+ self.assertEqual(node.public_ips[1].name, 'Network 15')
+ self.assertEqual(node.public_ips[1].address, '192.168.1.3')
+ self.assertEqual(node.public_ips[1].size, 1)
+ self.assertEqual(node.public_ips[1].extra['mac'], '02:00:c0:a8:01:03')
+ self.assertEqual(node.private_ips, [])
+ self.assertEqual(node.size, None)
+ self.assertEqual(node.image, None)
+ context = node.extra['context']
+ self.assertEqual(context['hostname'], 'compute-25')
def test_list_images(self):
"""
@@ -457,6 +516,104 @@
self.assertEqual(network.size, '256')
+class OpenNebula_3_0_Tests(unittest.TestCase, TestCaseMixin):
+ """
+ OpenNebula.org test suite for OpenNebula v3.0.
+ """
+
+ def setUp(self):
+ """
+ Setup test environment.
+ """
+ OpenNebulaNodeDriver.connectionCls.conn_classes = (
+ OpenNebula_3_0_MockHttp, OpenNebula_3_0_MockHttp)
+ self.driver = OpenNebulaNodeDriver(*OPENNEBULA_PARAMS + ('3.0',))
+
+ def test_ex_list_networks(self):
+ """
+ Test ex_list_networks functionality.
+ """
+ networks = self.driver.ex_list_networks()
+
+ self.assertEqual(len(networks), 2)
+ network = networks[0]
+ self.assertEqual(network.id, '5')
+ self.assertEqual(network.name, 'Network 5')
+ self.assertEqual(network.address, '192.168.0.0')
+ self.assertEqual(network.size, '256')
+ self.assertEqual(network.extra['public'], 'YES')
+ network = networks[1]
+ self.assertEqual(network.id, '15')
+ self.assertEqual(network.name, 'Network 15')
+ self.assertEqual(network.address, '192.168.1.0')
+ self.assertEqual(network.size, '256')
+ self.assertEqual(network.extra['public'], 'NO')
+
+ def test_ex_node_set_save_name(self):
+ """
+ Test ex_node_action functionality.
+ """
+ image = NodeImage(id=5, name='Ubuntu 9.04 LAMP', driver=self.driver)
+ node = Node(5, None, None, None, None, self.driver, image=image)
+ ret = self.driver.ex_node_set_save_name(node, 'test')
+ self.assertTrue(ret)
+
+
+class OpenNebula_3_2_Tests(unittest.TestCase, TestCaseMixin):
+ """
+ OpenNebula.org test suite for OpenNebula v3.2.
+ """
+
+ def setUp(self):
+ """
+ Setup test environment.
+ """
+ OpenNebulaNodeDriver.connectionCls.conn_classes = (
+ OpenNebula_3_2_MockHttp, OpenNebula_3_2_MockHttp)
+ self.driver = OpenNebulaNodeDriver(*OPENNEBULA_PARAMS + ('3.2',))
+
+ def test_list_sizes(self):
+ """
+ Test ex_list_networks functionality.
+ """
+ sizes = self.driver.list_sizes()
+
+ self.assertEqual(len(sizes), 3)
+ size = sizes[0]
+ self.assertEqual(size.id, '1')
+ self.assertEqual(size.name, 'small')
+ self.assertEqual(size.ram, 1024)
+ self.assertTrue(size.cpu is None or isinstance(size.cpu, int))
+ self.assertTrue(size.vcpu is None or isinstance(size.vcpu, int))
+ self.assertEqual(size.cpu, 1)
+ self.assertEqual(size.vcpu, None)
+ self.assertEqual(size.disk, None)
+ self.assertEqual(size.bandwidth, None)
+ self.assertEqual(size.price, None)
+ size = sizes[1]
+ self.assertEqual(size.id, '2')
+ self.assertEqual(size.name, 'medium')
+ self.assertEqual(size.ram, 4096)
+ self.assertTrue(size.cpu is None or isinstance(size.cpu, int))
+ self.assertTrue(size.vcpu is None or isinstance(size.vcpu, int))
+ self.assertEqual(size.cpu, 4)
+ self.assertEqual(size.vcpu, None)
+ self.assertEqual(size.disk, None)
+ self.assertEqual(size.bandwidth, None)
+ self.assertEqual(size.price, None)
+ size = sizes[2]
+ self.assertEqual(size.id, '3')
+ self.assertEqual(size.name, 'large')
+ self.assertEqual(size.ram, 8192)
+ self.assertTrue(size.cpu is None or isinstance(size.cpu, int))
+ self.assertTrue(size.vcpu is None or isinstance(size.vcpu, int))
+ self.assertEqual(size.cpu, 8)
+ self.assertEqual(size.vcpu, None)
+ self.assertEqual(size.disk, None)
+ self.assertEqual(size.bandwidth, None)
+ self.assertEqual(size.price, None)
+
+
class OpenNebula_1_4_MockHttp(MockHttp):
"""
Mock HTTP server for testing v1.4 of the OpenNebula.org compute driver.
@@ -675,6 +832,24 @@
return (httplib.NO_CONTENT, body, {},
httplib.responses[httplib.NO_CONTENT])
+ def _compute_25(self, method, url, body, headers):
+ """
+ Compute entry resource.
+ """
+ if method == 'GET':
+ body = self.fixtures.load('compute_25.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ if method == 'PUT':
+ body = ""
+ return (httplib.ACCEPTED, body, {},
+ httplib.responses[httplib.ACCEPTED])
+
+ if method == 'DELETE':
+ body = ""
+ return (httplib.NO_CONTENT, body, {},
+ httplib.responses[httplib.NO_CONTENT])
+
def _storage_5(self, method, url, body, headers):
"""
Storage entry resource.
@@ -727,5 +902,68 @@
return (httplib.NO_CONTENT, body, {},
httplib.responses[httplib.NO_CONTENT])
+
+class OpenNebula_3_0_MockHttp(OpenNebula_2_0_MockHttp):
+ """
+ Mock HTTP server for testing v3.0 of the OpenNebula.org compute driver.
+ """
+
+ fixtures_3_0 = ComputeFileFixtures('opennebula_3_0')
+
+ def _network(self, method, url, body, headers):
+ """
+ Network pool resources.
+ """
+ if method == 'GET':
+ body = self.fixtures_3_0.load('network_collection.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ if method == 'POST':
+ body = self.fixtures.load('network_5.xml')
+ return (httplib.CREATED, body, {},
+ httplib.responses[httplib.CREATED])
+
+ def _network_5(self, method, url, body, headers):
+ """
+ Network entry resource.
+ """
+ if method == 'GET':
+ body = self.fixtures_3_0.load('network_5.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ if method == 'DELETE':
+ body = ""
+ return (httplib.NO_CONTENT, body, {},
+ httplib.responses[httplib.NO_CONTENT])
+
+ def _network_15(self, method, url, body, headers):
+ """
+ Network entry resource.
+ """
+ if method == 'GET':
+ body = self.fixtures_3_0.load('network_15.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ if method == 'DELETE':
+ body = ""
+ return (httplib.NO_CONTENT, body, {},
+ httplib.responses[httplib.NO_CONTENT])
+
+
+class OpenNebula_3_2_MockHttp(OpenNebula_3_0_MockHttp):
+ """
+ Mock HTTP server for testing v3.2 of the OpenNebula.org compute driver.
+ """
+
+ fixtures_3_2 = ComputeFileFixtures('opennebula_3_2')
+
+ def _instance_type(self, method, url, body, headers):
+ """
+ Instance type pool.
+ """
+ if method == 'GET':
+ body = self.fixtures_3_2.load('instance_type_collection.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
if __name__ == '__main__':
sys.exit(unittest.main())
signature.asc
Description: This is a digitally signed message part
