Merge branch 'trunk' into ost_flavor_extra_specs
diff --git a/CHANGES.rst b/CHANGES.rst
index 1cba946..05f28f7 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -57,6 +57,10 @@
(GITHUB-1495)
[Miguel Caballer - @micafer]
+- [OpenStack] Add ex_get_size_extra_specs function to OpenStack driver.
+ (GITHUB-1517)
+ [Miguel Caballer - @micafer]
+
- [OpenStack] Enable to get Neutron Quota details in OpenStack driver.
(GITHUB-1514)
[Miguel Caballer - @micafer]
diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py
index 5b9cd03..f08c75c 100644
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@ -2254,6 +2254,18 @@
return self._to_size(self.connection.request(
'/flavors/%s' % (size_id,)) .object['flavor'])
+ def ex_get_size_extra_specs(self, size_id):
+ """
+ Get the extra_specs field of a NodeSize
+
+ :param size_id: ID of the size which should be used
+ :type size_id: ``str``
+
+ :rtype: `dict`
+ """
+ return self.connection.request(
+ '/flavors/%s/os-extra_specs' % (size_id,)) .object['extra_specs']
+
def get_image(self, image_id):
"""
Get a NodeImage
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_flavor_extra_specs.json b/libcloud/test/compute/fixtures/openstack_v1.1/_flavor_extra_specs.json
new file mode 100644
index 0000000..b9084c3
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_flavor_extra_specs.json
@@ -0,0 +1,6 @@
+{
+ "extra_specs": {
+ "hw:cpu_policy": "shared",
+ "hw:numa_nodes": "1"
+ }
+}
\ No newline at end of file
diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py
index b37e5d1..2329f5f 100644
--- a/libcloud/test/compute/test_openstack.py
+++ b/libcloud/test/compute/test_openstack.py
@@ -1184,6 +1184,12 @@
self.assertEqual(size.id, size_id)
self.assertEqual(size.name, '15.5GB slice')
+ def test_ex_get_size_extra_specs(self):
+ size_id = '7'
+ extra_specs = self.driver.ex_get_size_extra_specs(size_id)
+ self.assertEqual(extra_specs, {"hw:cpu_policy": "shared",
+ "hw:numa_nodes": "1"})
+
def test_get_image(self):
image_id = '13'
image = self.driver.get_image(image_id)
@@ -2813,6 +2819,13 @@
body = self.fixtures.load('_v2_0__quota_set.json')
return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+ def _v2_1337_flavors_7_os_extra_specs(self, method, url, body, headers):
+ if method == "GET":
+ body = self.fixtures.load('_flavor_extra_specs.json')
+ return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+ else:
+ raise NotImplementedError()
+
def _v2_1337_servers_1000_action(self, method, url, body, headers):
if method != 'POST' or body != '{"removeSecurityGroup": {"name": "sgname"}}':
raise NotImplementedError(body)