Skip to content

Commit

Permalink
LIBCLOUD-516: Add list_size() support into Eucalyptus for cluster ver…
Browse files Browse the repository at this point in the history
…sions >= 3.3.0. In this version Eucalyptus introduced the DescribeInstanceTypes call which is specific to EUCA and is not AWS compatible. This call requires a different XML namespace.

Closes #249.

Signed-off-by: Tomaz Muraus <tomaz@apache.org>
  • Loading branch information
Chris DeRamus authored and Kami committed Feb 12, 2014
1 parent 711d8e3 commit 773cd3d
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
56 changes: 55 additions & 1 deletion libcloud/compute/drivers/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
'API_VERSION',
'NAMESPACE',
'INSTANCE_TYPES',
'DEFAULT_EUCA_API_VERSION',
'EUCA_NAMESPACE',

'EC2NodeDriver',
'BaseEC2NodeDriver',
Expand All @@ -64,6 +66,10 @@
API_VERSION = '2013-10-15'
NAMESPACE = 'http://ec2.amazonaws.com/doc/%s/' % (API_VERSION)

# Eucalyptus Constants
DEFAULT_EUCA_API_VERSION = '3.3.0'
EUCA_NAMESPACE = 'http://msgs.eucalyptus.com/%s' % (DEFAULT_EUCA_API_VERSION)

"""
Sizes must be hardcoded, because Amazon doesn't provide an API to fetch them.
From http://aws.amazon.com/ec2/instance-types/
Expand Down Expand Up @@ -3875,22 +3881,70 @@ class EucNodeDriver(BaseEC2NodeDriver):
connectionCls = EucConnection

def __init__(self, key, secret=None, secure=True, host=None,
path=None, port=None):
path=None, port=None, api_version=DEFAULT_EUCA_API_VERSION):
"""
@inherits: :class:`EC2NodeDriver.__init__`
:param path: The host where the API can be reached.
:type path: ``str``
:param api_version: The API version to extend support for
Eucalyptus proprietary API calls
:type api_version: ``str``
"""
super(EucNodeDriver, self).__init__(key, secret, secure, host, port)

if path is None:
path = '/services/Eucalyptus'

self.path = path
self.EUCA_NAMESPACE = 'http://msgs.eucalyptus.com/%s' % (api_version)

def list_locations(self):
raise NotImplementedError(
'list_locations not implemented for this driver')

def _to_sizes(self, response):
return [self._to_size(el) for el in response.findall(
fixxpath(xpath='instanceTypeDetails/item',
namespace=self.EUCA_NAMESPACE))]

def _to_size(self, el):
name = findtext(element=el,
xpath='name',
namespace=self.EUCA_NAMESPACE)
cpu = findtext(element=el,
xpath='cpu',
namespace=self.EUCA_NAMESPACE)
disk = findtext(element=el,
xpath='disk',
namespace=self.EUCA_NAMESPACE)
memory = findtext(element=el,
xpath='memory',
namespace=self.EUCA_NAMESPACE)

return NodeSize(id=name,
name=name,
ram=int(memory),
disk=int(disk),
bandwidth=None,
price=None,
driver=EucNodeDriver,
extra={
'cpu': int(cpu)
})

def list_sizes(self):
"""
List available instance flavors/sizes
:rtype: ``list`` of :class:`NodeSize`
"""
params = {'Action': 'DescribeInstanceTypes'}
response = self.connection.request(self.path, params=params).object

return self._to_sizes(response)

def _add_instance_filter(self, params, node):
"""
Eucalyptus driver doesn't support filtering on instance id so this is a
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<euca:DescribeInstanceTypesResponseType xmlns:euca="http://msgs.eucalyptus.com/3.4.1"><euca:VmTypeMessage><euca:_return>true</euca:_return><euca:_services/><euca:_disabledServices/><euca:_notreadyServices/><euca:_stoppedServices/></euca:VmTypeMessage><euca:instanceTypeDetails><euca:item><euca:name>m1.small</euca:name><euca:cpu>1</euca:cpu><euca:disk>5</euca:disk><euca:memory>256</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>t1.micro</euca:name><euca:cpu>1</euca:cpu><euca:disk>5</euca:disk><euca:memory>256</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m1.medium</euca:name><euca:cpu>1</euca:cpu><euca:disk>10</euca:disk><euca:memory>512</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>c1.medium</euca:name><euca:cpu>2</euca:cpu><euca:disk>10</euca:disk><euca:memory>512</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m1.large</euca:name><euca:cpu>1</euca:cpu><euca:disk>10</euca:disk><euca:memory>1024</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>c1.xlarge</euca:name><euca:cpu>2</euca:cpu><euca:disk>10</euca:disk><euca:memory>1024</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m1.xlarge</euca:name><euca:cpu>1</euca:cpu><euca:disk>10</euca:disk><euca:memory>2048</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m2.xlarge</euca:name><euca:cpu>2</euca:cpu><euca:disk>10</euca:disk><euca:memory>2048</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m3.xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>15</euca:disk><euca:memory>2048</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m2.2xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>30</euca:disk><euca:memory>4096</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m3.2xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>30</euca:disk><euca:memory>4096</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>cc1.4xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>60</euca:disk><euca:memory>3072</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>m2.4xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>60</euca:disk><euca:memory>4096</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>cc2.8xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>120</euca:disk><euca:memory>6144</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>hi1.4xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>120</euca:disk><euca:memory>6144</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>cg1.4xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>200</euca:disk><euca:memory>12288</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>cr1.8xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>240</euca:disk><euca:memory>16384</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item><euca:item><euca:name>hs1.8xlarge</euca:name><euca:cpu>16</euca:cpu><euca:disk>24000</euca:disk><euca:memory>119808</euca:memory><euca:availability/><euca:ephemeralDisk/></euca:item></euca:instanceTypeDetails></euca:DescribeInstanceTypesResponseType>
15 changes: 14 additions & 1 deletion libcloud/test/compute/test_ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,11 @@ def _services_Eucalyptus_CreateTags(self, method, url, body,
headers):
return self._CreateTags(method, url, body, headers)

def _services_Eucalyptus_DescribeInstanceTypes(self, method, url, body,
headers):
body = self.fixtures.load('describe_instance_types.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])


class NimbusTests(EC2Tests):

Expand Down Expand Up @@ -1444,7 +1449,7 @@ def setUp(self):
EC2MockHttp.use_param = 'Action'
EC2MockHttp.type = None
self.driver = EucNodeDriver(key=EC2_PARAMS[0], secret=EC2_PARAMS[1],
host='some.eucalyptus.com')
host='some.eucalyptus.com', api_version='3.4.1')

def test_list_locations_response(self):
try:
Expand All @@ -1457,6 +1462,14 @@ def test_list_locations_response(self):
def test_list_location(self):
pass

def test_list_sizes(self):
sizes = self.driver.list_sizes()
ids = [s.id for s in sizes]
self.assertEqual(len(ids), 18)
self.assertTrue('t1.micro' in ids)
self.assertTrue('m1.medium' in ids)
self.assertTrue('m3.xlarge' in ids)


if __name__ == '__main__':
sys.exit(unittest.main())

0 comments on commit 773cd3d

Please sign in to comment.