Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 267 additions & 0 deletions libcloud/compute/drivers/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
DEFAULT_EUCA_API_VERSION = '3.3.0'
EUCA_NAMESPACE = 'http://msgs.eucalyptus.com/%s' % (DEFAULT_EUCA_API_VERSION)

# Outscale Constants
DEFAULT_OUTSCALE_API_VERSION = '2016-04-01'
OUTSCALE_NAMESPACE = 'http://api.outscale.com/wsdl/fcuext/2014-04-15/'

"""
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 @@ -6559,6 +6563,7 @@ class OutscaleConnection(EC2Connection):
Connection class for Outscale
"""

version = DEFAULT_OUTSCALE_API_VERSION
host = None


Expand Down Expand Up @@ -6806,6 +6811,268 @@ def list_sizes(self, location=None):
sizes.append(NodeSize(driver=self, **attributes))
return sizes

def ex_modify_instance_keypair(self, instance_id, key_name=None):
"""
Modifies the keypair associated with a specified instance.
Once the modification done, you must restart the instance.

:param instance_id: The ID of the instance
:type instance_id: ``string``

:param key_name: The name of the keypair
:type key_name: ``string``
"""

params = {'Action': 'ModifyInstanceKeypair'}

params.update({'instanceId': instance_id})

if key_name is not None:
params.update({'keyName': key_name})

response = self.connection.request(self.path, params=params,
method='GET').object

return (findtext(element=response, xpath='return',
namespace=OUTSCALE_NAMESPACE) == 'true')

def _to_quota(self, elem):
"""
To Quota
"""

quota = {}
for reference_quota_item in findall(element=elem,
xpath='referenceQuotaSet/item',
namespace=OUTSCALE_NAMESPACE):
reference = findtext(element=reference_quota_item,
xpath='reference',
namespace=OUTSCALE_NAMESPACE)
quota_set = []
for quota_item in findall(element=reference_quota_item,
xpath='quotaSet/item',
namespace=OUTSCALE_NAMESPACE):
ownerId = findtext(element=quota_item,
xpath='ownerId',
namespace=OUTSCALE_NAMESPACE)
name = findtext(element=quota_item,
xpath='name',
namespace=OUTSCALE_NAMESPACE)
displayName = findtext(element=quota_item,
xpath='displayName',
namespace=OUTSCALE_NAMESPACE)
description = findtext(element=quota_item,
xpath='description',
namespace=OUTSCALE_NAMESPACE)
groupName = findtext(element=quota_item,
xpath='groupName',
namespace=OUTSCALE_NAMESPACE)
maxQuotaValue = findtext(element=quota_item,
xpath='maxQuotaValue',
namespace=OUTSCALE_NAMESPACE)
usedQuotaValue = findtext(element=quota_item,
xpath='usedQuotaValue',
namespace=OUTSCALE_NAMESPACE)
quota_set.append({'ownerId': ownerId,
'name': name,
'displayName': displayName,
'description': description,
'groupName': groupName,
'maxQuotaValue': maxQuotaValue,
'usedQuotaValue': usedQuotaValue})
quota[reference] = quota_set

return quota

def ex_describe_quota(self, dry_run=False, filters=None,
max_results=None, marker=None):
"""
Describes one or more of your quotas.

:param dry_run: dry_run
:type dry_run: ``bool``

:param filters: The filters so that the response includes
information for only certain quotas
:type filters: ``dict``

:param max_results: The maximum number of items that can be
returned in a single page (by default, 100)
:type max_results: ``int``

:param marker: Set quota marker
:type marker: ``string``

:return: (is_truncated, quota) tuple
:rtype: ``(bool, dict)``
"""

if filters:
raise NotImplementedError(
'quota filters are not implemented')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when will this be implemented?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonybaloney thanks for reviewing. we hope a new release of FCU at the end of November or December. Filters in this API are being reworked cause the original implementation is raising some non expected issues in the server side and we had to rollback although the API doc was published and the interface spec is stable. This way users get a clear message and they would not report this well-know bug.

BTW this first patchset would be also a first update to catch up with the new features and improvements in the FCU. Outscale would like to contribute new APIs and available features implemented along the previous months in the server side. As expected, with each new FCU release we would revisit the non implemented bits and bugfixes to support the new features as soon as they hit production in the server side.


if marker:
raise NotImplementedError(
'quota marker is not implemented')

params = {'Action': 'DescribeQuota'}

if dry_run:
params.update({'DryRun': dry_run})

if max_results:
params.update({'MaxResults': max_results})

response = self.connection.request(self.path, params=params,
method='GET').object

quota = self._to_quota(response)

is_truncated = findtext(element=response, xpath='isTruncated',
namespace=OUTSCALE_NAMESPACE)

return is_truncated, quota

def _to_product_type(self, elem):

productTypeId = findtext(element=elem, xpath='productTypeId',
namespace=OUTSCALE_NAMESPACE)
description = findtext(element=elem, xpath='description',
namespace=OUTSCALE_NAMESPACE)

return {'productTypeId': productTypeId,
'description': description}

def ex_get_product_type(self, image_id, snapshot_id=None):
"""
Get the product type of a specified OMI or snapshot.

:param image_id: The ID of the OMI
:type image_id: ``string``

:param snapshot_id: The ID of the snapshot
:type snapshot_id: ``string``

:return: A product type
:rtype: ``dict``
"""

params = {'Action': 'GetProductType'}

params.update({'ImageId': image_id})
if snapshot_id is not None:
params.update({'SnapshotId': snapshot_id})

response = self.connection.request(self.path, params=params,
method='GET').object

product_type = self._to_product_type(response)

return product_type

def _to_product_types(self, elem):

product_types = []
for product_types_item in findall(element=elem,
xpath='productTypeSet/item',
namespace=OUTSCALE_NAMESPACE):
productTypeId = findtext(element=product_types_item,
xpath='productTypeId',
namespace=OUTSCALE_NAMESPACE)
description = findtext(element=product_types_item,
xpath='description',
namespace=OUTSCALE_NAMESPACE)
product_types.append({'productTypeId': productTypeId,
'description': description})

return product_types

def ex_describe_product_types(self, filters=None):
"""
Describes Product Types.

:param filters: The filters so that the response includes
information for only certain quotas
:type filters: ``dict``

:return: A product types list
:rtype: ``list``
"""

params = {'Action': 'DescribeProductTypes'}

if filters:
params.update(self._build_filters(filters))

response = self.connection.request(self.path, params=params,
method='GET').object

product_types = self._to_product_types(response)

return product_types

def _to_instance_types(self, elem):

instance_types = []
for instance_types_item in findall(element=elem,
xpath='instanceTypeSet/item',
namespace=OUTSCALE_NAMESPACE):
name = findtext(element=instance_types_item,
xpath='name',
namespace=OUTSCALE_NAMESPACE)
vcpu = findtext(element=instance_types_item,
xpath='vcpu',
namespace=OUTSCALE_NAMESPACE)
memory = findtext(element=instance_types_item,
xpath='memory',
namespace=OUTSCALE_NAMESPACE)
storageSize = findtext(element=instance_types_item,
xpath='storageSize',
namespace=OUTSCALE_NAMESPACE)
storageCount = findtext(element=instance_types_item,
xpath='storageCount',
namespace=OUTSCALE_NAMESPACE)
maxIpAddresses = findtext(element=instance_types_item,
xpath='maxIpAddresses',
namespace=OUTSCALE_NAMESPACE)
ebsOptimizedAvailable = findtext(element=instance_types_item,
xpath='ebsOptimizedAvailable',
namespace=OUTSCALE_NAMESPACE)
d = {'name': name,
'vcpu': vcpu,
'memory': memory,
'storageSize': storageSize,
'storageCount': storageCount,
'maxIpAddresses': maxIpAddresses,
'ebsOptimizedAvailable': ebsOptimizedAvailable}
instance_types.append(d)

return instance_types

def ex_describe_instance_types(self, filters=None):
"""
Describes Instance Types.

:param filters: The filters so that the response includes
information for only instance types
:type filters: ``dict``

:return: A instance types list
:rtype: ``list``
"""

params = {'Action': 'DescribeInstanceTypes'}

if filters:
params.update(self._build_filters(filters))

response = self.connection.request(self.path, params=params,
method='GET').object

instance_types = self._to_instance_types(response)

return instance_types


class OutscaleSASNodeDriver(OutscaleNodeDriver):
"""
Expand Down
33 changes: 33 additions & 0 deletions libcloud/test/compute/fixtures/fcu/ex_describe_instance_types.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<DescribeInstanceTypesResponse
xmlns="http://api.outscale.com/wsdl/fcuext/2014-04-15/">
<requestId>0556395e-4fe3-4cc1-80cb-c98b9f44ca4b</requestId>
<instanceTypeSet>
<item>
<name>og4.4xlarge</name>
<vcpu>24</vcpu>
<memory>193273528320</memory>
<storageSize>412316860416</storageSize>
<storageCount>1</storageCount>
<maxIpAddresses>30</maxIpAddresses>
<ebsOptimizedAvailable>true</ebsOptimizedAvailable>
</item>
<item>
<name>m3.large</name>
<vcpu>2</vcpu>
<memory>8050966528</memory>
<storageSize>34359738368</storageSize>
<storageCount>1</storageCount>
<maxIpAddresses>10</maxIpAddresses>
<ebsOptimizedAvailable>false</ebsOptimizedAvailable>
</item>
<item>
<name>oc2.8xlarge</name>
<vcpu>15</vcpu>
<memory>68718428160</memory>
<storageSize>901943132160</storageSize>
<storageCount>4</storageCount>
<maxIpAddresses>30</maxIpAddresses>
<ebsOptimizedAvailable>false</ebsOptimizedAvailable>
</item>
</instanceTypeSet>
</DescribeInstanceTypesResponse>
18 changes: 18 additions & 0 deletions libcloud/test/compute/fixtures/fcu/ex_describe_product_types.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<DescribeProductTypesResponse
xmlns="http://api.outscale.com/wsdl/fcuext/2014-04-15/">
<requestId>6f5287ac-2833-43d5-8675-b1ffd7b658d3</requestId>
<productTypeSet>
<item>
<productTypeId>0001</productTypeId>
<description>Linux/UNIX</description>
</item>
<item>
<productTypeId>0002</productTypeId>
<description>Windows</description>
</item>
<item>
<productTypeId>0003</productTypeId>
<description>MapR</description>
</item>
</productTypeSet>
</DescribeProductTypesResponse>
53 changes: 53 additions & 0 deletions libcloud/test/compute/fixtures/fcu/ex_describe_quota.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<DescribeQuotaResponse
xmlns="http://api.outscale.com/wsdl/fcuext/2014-04-15/">
<requestId>31ef7689-2521-445f-b634-2a5e3e66f699</requestId>
<isTruncated>true</isTruncated>
<referenceQuotaSet>
<item>
<reference>global</reference>
<quotaSet>
<item>
<ownerId>366866344682</ownerId>
<name>vm_limit</name>
<displayName>VM Limit</displayName>
<description>Maximum number of VM this user can own</description>
<groupName>Compute</groupName>
<maxQuotaValue>20</maxQuotaValue>
<usedQuotaValue>1</usedQuotaValue>
</item>
<item>
<ownerId>366866344682</ownerId>
<name>core_limit</name>
<displayName>Core Limit</displayName>
<description>Maximum number of total cores (virtual core)</description>
<groupName>Compute</groupName>
<maxQuotaValue>800</maxQuotaValue>
<usedQuotaValue>2</usedQuotaValue>
</item>
<item>
<ownerId>366866344682</ownerId>
<name>memory_limit</name>
<displayName>Memory Limit</displayName>
<description>Maximum number of total memory (GiB)</description>
<groupName>Compute</groupName>
<maxQuotaValue>4880</maxQuotaValue>
<usedQuotaValue>7</usedQuotaValue>
</item>
</quotaSet>
</item>
<item>
<reference>vpc-00000000</reference>
<quotaSet>
<item>
<ownerId>366866344682</ownerId>
<name>sg_limit</name>
<displayName>Security Groups Limit</displayName>
<description>Maximum number of security groups</description>
<groupName>Security Groups</groupName>
<maxQuotaValue>100</maxQuotaValue>
<usedQuotaValue>2</usedQuotaValue>
</item>
</quotaSet>
</item>
</referenceQuotaSet>
</DescribeQuotaResponse>
Loading