diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-08-29 17:50:58 -0700 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-08-29 22:27:46 -0700 |
| commit | f9fa7a68a368cefd79ccc6d5d2b91cbdb4d17be7 (patch) | |
| tree | f4ad838b04c86d34f20bc0eb7caa25eae52411e0 | |
| parent | 4a6193b5d2cab2aaf4a5b3dfeb9b460d77677a2d (diff) | |
| download | nova-f9fa7a68a368cefd79ccc6d5d2b91cbdb4d17be7.tar.gz nova-f9fa7a68a368cefd79ccc6d5d2b91cbdb4d17be7.tar.xz nova-f9fa7a68a368cefd79ccc6d5d2b91cbdb4d17be7.zip | |
Clean up non-spec output in flavor extensions
Adds option to cache flavors in the request object like instances.
Modifies the flavorextradata extension to use the cache and optimizes
tests. Adds flavor_disabled extension to control the extra data and
includes tests. Fixes api samples to show the new extension.
Fixes bug 1043585
Change-Id: Ie89df24a2891e3869d3fb604e07c79e8c913f290
17 files changed, 294 insertions, 101 deletions
diff --git a/etc/nova/policy.json b/etc/nova/policy.json index 2a722b9a1..2704bdcd5 100644 --- a/etc/nova/policy.json +++ b/etc/nova/policy.json @@ -36,6 +36,7 @@ "compute_extension:extended_server_attributes": [["rule:admin_api"]], "compute_extension:extended_status": [], "compute_extension:flavor_access": [], + "compute_extension:flavor_disabled": [], "compute_extension:flavorextradata": [], "compute_extension:flavorextraspecs": [], "compute_extension:flavormanage": [["rule:admin_api"]], diff --git a/nova/api/openstack/compute/contrib/flavor_disabled.py b/nova/api/openstack/compute/contrib/flavor_disabled.py new file mode 100644 index 000000000..48181954b --- /dev/null +++ b/nova/api/openstack/compute/contrib/flavor_disabled.py @@ -0,0 +1,89 @@ +# Copyright 2012 Nebula, Inc. +# +# Licensed 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. + +"""The Flavor Disabled API extension.""" + +from nova.api.openstack import extensions +from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil + + +authorize = extensions.soft_extension_authorizer('compute', 'flavor_disabled') + + +class FlavorDisabledController(wsgi.Controller): + def _extend_flavors(self, req, flavors): + for flavor in flavors: + db_flavor = req.get_db_flavor(flavor['id']) + key = "%s:disabled" % Flavor_disabled.alias + flavor[key] = db_flavor['disabled'] + + def _show(self, req, resp_obj): + if not authorize(req.environ['nova.context']): + return + if 'flavor' in resp_obj.obj: + resp_obj.attach(xml=FlavorDisabledTemplate()) + self._extend_flavors(req, [resp_obj.obj['flavor']]) + + @wsgi.extends + def show(self, req, resp_obj, id): + return self._show(req, resp_obj) + + @wsgi.extends(action='create') + def create(self, req, resp_obj, body): + return self._show(req, resp_obj) + + @wsgi.extends + def detail(self, req, resp_obj): + if not authorize(req.environ['nova.context']): + return + resp_obj.attach(xml=FlavorsDisabledTemplate()) + self._extend_flavors(req, list(resp_obj.obj['flavors'])) + + +class Flavor_disabled(extensions.ExtensionDescriptor): + """Support to show the disabled status of a flavor""" + + name = "FlavorDisabled" + alias = "OS-FLV-DISABLED" + namespace = ("http://docs.openstack.org/compute/ext/" + "flavor_disabled/api/v1.1") + updated = "2012-08-29T00:00:00+00:00" + + def get_controller_extensions(self): + controller = FlavorDisabledController() + extension = extensions.ControllerExtension(self, 'flavors', controller) + return [extension] + + +def make_flavor(elem): + elem.set('{%s}disabled' % Flavor_disabled.namespace, + '%s:disabled' % Flavor_disabled.alias) + + +class FlavorDisabledTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('flavor', selector='flavor') + make_flavor(root) + return xmlutil.SlaveTemplate(root, 1, nsmap={ + Flavor_disabled.alias: Flavor_disabled.namespace}) + + +class FlavorsDisabledTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('flavors') + elem = xmlutil.SubTemplateElement(root, 'flavor', selector='flavors') + make_flavor(elem) + return xmlutil.SlaveTemplate(root, 1, nsmap={ + Flavor_disabled.alias: Flavor_disabled.namespace}) diff --git a/nova/api/openstack/compute/contrib/flavorextradata.py b/nova/api/openstack/compute/contrib/flavorextradata.py index 834b68c60..e2bdadf16 100644 --- a/nova/api/openstack/compute/contrib/flavorextradata.py +++ b/nova/api/openstack/compute/contrib/flavorextradata.py @@ -27,71 +27,39 @@ attributes. This extension adds to that list: from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil -from nova.compute import instance_types -from nova import exception authorize = extensions.soft_extension_authorizer('compute', 'flavorextradata') class FlavorextradataController(wsgi.Controller): - def _get_flavor_refs(self, context): - """Return a dictionary mapping flavorid to flavor_ref.""" - - flavor_refs = instance_types.get_all_types(context) - rval = {} - for name, obj in flavor_refs.iteritems(): - rval[obj['flavorid']] = obj - return rval - - def _extend_flavor(self, flavor_rval, flavor_ref): - key = "%s:ephemeral" % (Flavorextradata.alias) - flavor_rval[key] = flavor_ref['ephemeral_gb'] + def _extend_flavors(self, req, flavors): + for flavor in flavors: + db_flavor = req.get_db_flavor(flavor['id']) + key = "%s:ephemeral" % Flavorextradata.alias + flavor[key] = db_flavor['ephemeral_gb'] + + def _show(self, req, resp_obj): + if not authorize(req.environ['nova.context']): + return + if 'flavor' in resp_obj.obj: + resp_obj.attach(xml=FlavorextradatumTemplate()) + self._extend_flavors(req, [resp_obj.obj['flavor']]) @wsgi.extends def show(self, req, resp_obj, id): - context = req.environ['nova.context'] - if authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=FlavorextradatumTemplate()) + return self._show(req, resp_obj) - try: - flavor_ref = instance_types.get_instance_type_by_flavor_id(id) - except exception.FlavorNotFound: - explanation = _("Flavor not found.") - raise exception.HTTPNotFound(explanation=explanation) - - self._extend_flavor(resp_obj.obj['flavor'], flavor_ref) + @wsgi.extends(action='create') + def create(self, req, resp_obj, body): + return self._show(req, resp_obj) @wsgi.extends def detail(self, req, resp_obj): - context = req.environ['nova.context'] - if authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=FlavorextradataTemplate()) - - flavors = list(resp_obj.obj['flavors']) - flavor_refs = self._get_flavor_refs(context) - - for flavor_rval in flavors: - flavor_ref = flavor_refs[flavor_rval['id']] - self._extend_flavor(flavor_rval, flavor_ref) - - @wsgi.extends(action='create') - def create(self, req, body, resp_obj): - context = req.environ['nova.context'] - if authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=FlavorextradatumTemplate()) - - try: - fid = resp_obj.obj['flavor']['id'] - flavor_ref = instance_types.get_instance_type_by_flavor_id(fid) - except exception.FlavorNotFound: - explanation = _("Flavor not found.") - raise exception.HTTPNotFound(explanation=explanation) - - self._extend_flavor(resp_obj.obj['flavor'], flavor_ref) + if not authorize(req.environ['nova.context']): + return + resp_obj.attach(xml=FlavorextradataTemplate()) + self._extend_flavors(req, list(resp_obj.obj['flavors'])) class Flavorextradata(extensions.ExtensionDescriptor): diff --git a/nova/api/openstack/compute/contrib/flavormanage.py b/nova/api/openstack/compute/contrib/flavormanage.py index 3bcbf6981..e3d57f3a1 100644 --- a/nova/api/openstack/compute/contrib/flavormanage.py +++ b/nova/api/openstack/compute/contrib/flavormanage.py @@ -71,6 +71,7 @@ class FlavorManageController(wsgi.Controller): flavor = instance_types.create(name, memory_mb, vcpus, root_gb, ephemeral_gb, flavorid, swap, rxtx_factor, is_public) + req.cache_db_flavor(flavor) except exception.InstanceTypeExists as err: raise webob.exc.HTTPConflict(explanation=str(err)) diff --git a/nova/api/openstack/compute/flavors.py b/nova/api/openstack/compute/flavors.py index 1a96c1346..e04ade437 100644 --- a/nova/api/openstack/compute/flavors.py +++ b/nova/api/openstack/compute/flavors.py @@ -79,6 +79,7 @@ class Controller(wsgi.Controller): def detail(self, req): """Return all flavors in detail.""" flavors = self._get_flavors(req) + req.cache_db_flavors(flavors) return self._view_builder.detail(req, flavors) @wsgi.serializers(xml=FlavorTemplate) @@ -86,6 +87,7 @@ class Controller(wsgi.Controller): """Return data about the given flavor id.""" try: flavor = instance_types.get_instance_type_by_flavor_id(id) + req.cache_db_flavor(flavor) except exception.NotFound: raise webob.exc.HTTPNotFound() diff --git a/nova/api/openstack/compute/views/flavors.py b/nova/api/openstack/compute/views/flavors.py index c299170b0..2900ccf64 100644 --- a/nova/api/openstack/compute/views/flavors.py +++ b/nova/api/openstack/compute/views/flavors.py @@ -49,12 +49,6 @@ class ViewBuilder(common.ViewBuilder): }, } - # NOTE(sirp): disabled attribute is namespaced for now for - # compatability with the OpenStack API. This should ultimately be made - # a first class attribute. - flavor_dict["flavor"]["OS-FLV-DISABLED:disabled"] =\ - flavor.get("disabled", "") - return flavor_dict def index(self, request, flavors): diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 9f8bf6367..658b59645 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -66,49 +66,62 @@ class Request(webob.Request): def __init__(self, *args, **kwargs): super(Request, self).__init__(*args, **kwargs) - self._extension_data = {'db_instances': {}} + self._extension_data = {'db_items': {}} - def cache_db_instances(self, instances): + def cache_db_items(self, key, items, item_key='id'): """ - Allow API methods to store instances from a DB query to be + Allow API methods to store objects from a DB query to be used by API extensions within the same API request. An instance of this class only lives for the lifetime of a single API request, so there's no need to implement full cache management. """ - db_instances = self._extension_data['db_instances'] - for instance in instances: - db_instances[instance['uuid']] = instance + db_items = self._extension_data['db_items'].setdefault(key, {}) + for item in items: + db_items[item[item_key]] = item - def cache_db_instance(self, instance): + def get_db_items(self, key): """ - Allow API methods to store an instance from a DB query to be - used by API extensions within the same API request. + Allow an API extension to get previously stored objects within + the same API request. - An instance of this class only lives for the lifetime of a - single API request, so there's no need to implement full - cache management. + Note that the object data will be slightly stale. """ - self.cache_db_instances([instance]) + return self._extension_data['db_items'][key] - def get_db_instances(self): + def get_db_item(self, key, item_key): """ - Allow an API extension to get previously stored instances within - the same API request. + Allow an API extension to get a previously stored object + within the same API request. - Note that the instance data will be slightly stale. + Note that the object data will be slightly stale. """ - return self._extension_data['db_instances'] + return self.get_db_items(key).get(item_key) + + def cache_db_instances(self, instances): + self.cache_db_items('instances', instances, 'uuid') + + def cache_db_instance(self, instance): + self.cache_db_items('instances', [instance], 'uuid') + + def get_db_instances(self): + return self.get_db_items('instances') def get_db_instance(self, instance_uuid): - """ - Allow an API extension to get a previously stored instance - within the same API request. + return self.get_db_item('instances', instance_uuid) - Note that the instance data will be slightly stale. - """ - return self._extension_data['db_instances'].get(instance_uuid) + def cache_db_flavors(self, flavors): + self.cache_db_items('flavors', flavors, 'flavorid') + + def cache_db_flavor(self, flavor): + self.cache_db_items('flavors', [flavor], 'flavorid') + + def get_db_flavors(self): + return self.get_db_items('flavors') + + def get_db_flavor(self, flavorid): + return self.get_db_item('flavors', flavorid) def best_match_content_type(self): """Determine the requested response content-type.""" diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py b/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py new file mode 100644 index 000000000..ab2066e38 --- /dev/null +++ b/nova/tests/api/openstack/compute/contrib/test_flavor_disabled.py @@ -0,0 +1,112 @@ +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed 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. + +from lxml import etree +import webob + +from nova.api.openstack.compute.contrib import flavor_disabled +from nova.compute import instance_types +from nova import flags +from nova.openstack.common import jsonutils +from nova import test +from nova.tests.api.openstack import fakes + + +FLAGS = flags.FLAGS + + +FAKE_FLAVORS = { + 'flavor 1': { + "flavorid": '1', + "name": 'flavor 1', + "memory_mb": '256', + "root_gb": '10', + "disabled": False, + }, + 'flavor 2': { + "flavorid": '2', + "name": 'flavor 2', + "memory_mb": '512', + "root_gb": '20', + "disabled": True, + }, +} + + +def fake_instance_type_get_by_flavor_id(flavorid): + return FAKE_FLAVORS['flavor %s' % flavorid] + + +def fake_instance_type_get_all(*args, **kwargs): + return FAKE_FLAVORS + + +class FlavorDisabledTest(test.TestCase): + content_type = 'application/json' + prefix = '%s:' % flavor_disabled.Flavor_disabled.alias + + def setUp(self): + super(FlavorDisabledTest, self).setUp() + ext = ('nova.api.openstack.compute.contrib' + '.flavor_disabled.Flavor_disabled') + self.flags(osapi_compute_extension=[ext]) + fakes.stub_out_nw_api(self.stubs) + self.stubs.Set(instance_types, "get_all_types", + fake_instance_type_get_all) + self.stubs.Set(instance_types, + "get_instance_type_by_flavor_id", + fake_instance_type_get_by_flavor_id) + + def _make_request(self, url): + req = webob.Request.blank(url) + req.headers['Accept'] = self.content_type + res = req.get_response(fakes.wsgi_app()) + return res + + def _get_flavor(self, body): + return jsonutils.loads(body).get('flavor') + + def _get_flavors(self, body): + return jsonutils.loads(body).get('flavors') + + def assertFlavorDisabled(self, flavor, disabled): + self.assertEqual(str(flavor.get('%sdisabled' % self.prefix)), disabled) + + def test_show(self): + url = '/v2/fake/flavors/1' + res = self._make_request(url) + + self.assertEqual(res.status_int, 200) + self.assertFlavorDisabled(self._get_flavor(res.body), 'False') + + def test_detail(self): + url = '/v2/fake/flavors/detail' + res = self._make_request(url) + + self.assertEqual(res.status_int, 200) + flavors = self._get_flavors(res.body) + self.assertFlavorDisabled(flavors[0], 'False') + self.assertFlavorDisabled(flavors[1], 'True') + + +class FlavorDisabledXmlTest(FlavorDisabledTest): + content_type = 'application/xml' + prefix = '{%s}' % flavor_disabled.Flavor_disabled.namespace + + def _get_flavor(self, body): + return etree.XML(body) + + def _get_flavors(self, body): + return etree.XML(body).getchildren() diff --git a/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py b/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py index 84ff8a1ea..68d8ee750 100644 --- a/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py +++ b/nova/tests/api/openstack/compute/contrib/test_flavor_manage.py @@ -47,7 +47,8 @@ def fake_get_instance_type_by_flavor_id(flavorid): 'deleted_at': None, 'vcpu_weight': None, 'id': 7, - 'is_public': True + 'is_public': True, + 'disabled': False, } diff --git a/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py b/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py index 3c4a84e2a..3f13f4c1d 100644 --- a/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py +++ b/nova/tests/api/openstack/compute/contrib/test_flavorextradata.py @@ -40,7 +40,6 @@ def fake_get_instance_type_by_flavor_id(flavorid): 'extra_specs': {}, 'deleted_at': None, 'vcpu_weight': None, - 'is_public': True } @@ -54,11 +53,14 @@ def fake_get_all_types(inactive=0, filters=None): class FlavorextradataTest(test.TestCase): def setUp(self): super(FlavorextradataTest, self).setUp() + ext = ('nova.api.openstack.compute.contrib' + '.flavorextradata.Flavorextradata') + self.flags(osapi_compute_extension=[ext]) self.stubs.Set(instance_types, 'get_instance_type_by_flavor_id', fake_get_instance_type_by_flavor_id) self.stubs.Set(instance_types, 'get_all_types', fake_get_all_types) - def _verify_server_response(self, flavor, expected): + def _verify_flavor_response(self, flavor, expected): for key in expected: self.assertEquals(flavor[key], expected[key]) @@ -73,7 +75,6 @@ class FlavorextradataTest(test.TestCase): 'OS-FLV-EXT-DATA:ephemeral': 1, 'swap': 512, 'rxtx_factor': 1, - 'os-flavor-access:is_public': True, } } @@ -82,7 +83,7 @@ class FlavorextradataTest(test.TestCase): req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app()) body = jsonutils.loads(res.body) - self._verify_server_response(body['flavor'], expected['flavor']) + self._verify_flavor_response(body['flavor'], expected['flavor']) def test_detail(self): expected = [ @@ -95,7 +96,6 @@ class FlavorextradataTest(test.TestCase): 'OS-FLV-EXT-DATA:ephemeral': 1, 'swap': 512, 'rxtx_factor': 1, - 'os-flavor-access:is_public': True, }, { 'id': '2', @@ -106,7 +106,6 @@ class FlavorextradataTest(test.TestCase): 'OS-FLV-EXT-DATA:ephemeral': 1, 'swap': 512, 'rxtx_factor': 1, - 'os-flavor-access:is_public': True, }, ] @@ -116,4 +115,4 @@ class FlavorextradataTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) body = jsonutils.loads(res.body) for i, flavor in enumerate(body['flavors']): - self._verify_server_response(flavor, expected[i]) + self._verify_flavor_response(flavor, expected[i]) diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py index 1a4d3902f..0c4f90815 100644 --- a/nova/tests/api/openstack/compute/test_extensions.py +++ b/nova/tests/api/openstack/compute/test_extensions.py @@ -167,6 +167,7 @@ class ExtensionControllerTest(ExtensionTestCase): "ExtendedStatus", "ExtendedServerAttributes", "FlavorAccess", + "FlavorDisabled", "FlavorExtraSpecs", "FlavorExtraData", "FlavorManage", diff --git a/nova/tests/api/openstack/compute/test_flavors.py b/nova/tests/api/openstack/compute/test_flavors.py index 2f9493a05..aaf929736 100644 --- a/nova/tests/api/openstack/compute/test_flavors.py +++ b/nova/tests/api/openstack/compute/test_flavors.py @@ -113,7 +113,6 @@ class FlavorsTest(test.TestCase): expected = { "flavor": { "id": "1", - "OS-FLV-DISABLED:disabled": False, "name": "flavor 1", "ram": "256", "disk": "10", @@ -142,7 +141,6 @@ class FlavorsTest(test.TestCase): expected = { "flavor": { "id": "1", - "OS-FLV-DISABLED:disabled": False, "name": "flavor 1", "ram": "256", "disk": "10", @@ -313,7 +311,6 @@ class FlavorsTest(test.TestCase): "flavors": [ { "id": "1", - "OS-FLV-DISABLED:disabled": False, "name": "flavor 1", "ram": "256", "disk": "10", @@ -333,7 +330,6 @@ class FlavorsTest(test.TestCase): }, { "id": "2", - "OS-FLV-DISABLED:disabled": False, "name": "flavor 2", "ram": "512", "disk": "20", @@ -435,7 +431,6 @@ class FlavorsTest(test.TestCase): "flavors": [ { "id": "2", - "OS-FLV-DISABLED:disabled": False, "name": "flavor 2", "ram": "512", "disk": "20", @@ -793,11 +788,6 @@ class DisabledFlavorsWithRealDBTest(test.TestCase): self.assertEqual(flavor['name'], self.disabled_type['name']) - # FIXME(sirp): the disabled field is currently namespaced so that we - # don't impact the OpenStack API. Eventually this should probably be - # made a first-class attribute in the next OSAPI version. - self.assert_('OS-FLV-DISABLED:disabled' in flavor) - def test_show_should_include_disabled_flavor_for_admin(self): self.context.is_admin = True @@ -805,4 +795,3 @@ class DisabledFlavorsWithRealDBTest(test.TestCase): self.req, self.disabled_type['flavorid'])['flavor'] self.assertEqual(flavor['name'], self.disabled_type['name']) - self.assert_('OS-FLV-DISABLED:disabled' in flavor) diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json index 16922dd14..1340259a7 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json @@ -33,6 +33,14 @@ "updated": "2011-11-03T00:00:00+00:00" }, { + "alias": "OS-FLV-DISABLED", + "description": "Support to show the disabled status of a flavor", + "links": [], + "name": "FlavorDisabled", + "namespace": "http://docs.openstack.org/compute/ext/flavor_disabled/api/v1.1", + "updated": "2012-08-29T00:00:00+00:00" + }, + { "alias": "OS-FLV-EXT-DATA", "description": "Provide additional data for flavors", "links": [], diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl index 06a824602..1e479f666 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl @@ -33,6 +33,14 @@ "updated": "%(timestamp)s" }, { + "alias": "OS-FLV-DISABLED", + "description": "%(text)s", + "links": [], + "name": "FlavorDisabled", + "namespace": "http://docs.openstack.org/compute/ext/flavor_disabled/api/v1.1", + "updated": "%(timestamp)s" + }, + { "alias": "OS-FLV-EXT-DATA", "description": "%(text)s", "links": [], diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml index a512bbc86..1644781cc 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml @@ -12,6 +12,9 @@ <extension alias="OS-EXT-STS" updated="2011-11-03T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/extended_status/api/v1.1" name="ExtendedStatus"> <description>Extended Status support</description> </extension> + <extension alias="OS-FLV-DISABLED" updated="2012-08-29T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/flavor_disabled/api/v1.1" name="FlavorDisabled"> + <description>Support to show the disabled status of a flavor</description> + </extension> <extension alias="OS-FLV-EXT-DATA" updated="2011-09-14T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/flavor_extra_data/api/v1.1" name="FlavorExtraData"> <description>Provide additional data for flavors</description> </extension> diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl index 0ee0cfd4b..bd8ff6d1e 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl @@ -12,6 +12,9 @@ <extension alias="OS-EXT-STS" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/extended_status/api/v1.1" name="ExtendedStatus"> <description>%(text)s</description> </extension> + <extension alias="OS-FLV-DISABLED" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/flavor_disabled/api/v1.1" name="FlavorDisabled"> + <description>%(text)s</description> + </extension> <extension alias="OS-FLV-EXT-DATA" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/flavor_extra_data/api/v1.1" name="FlavorExtraData"> <description>%(text)s</description> </extension> diff --git a/nova/tests/policy.json b/nova/tests/policy.json index 08577ed04..51d811db1 100644 --- a/nova/tests/policy.json +++ b/nova/tests/policy.json @@ -93,6 +93,7 @@ "compute_extension:extended_server_attributes": [], "compute_extension:extended_status": [], "compute_extension:flavor_access": [], + "compute_extension:flavor_disabled": [], "compute_extension:flavorextradata": [], "compute_extension:flavorextraspecs": [], "compute_extension:flavormanage": [], |
