diff --git a/nova/api/openstack/compute/plugins/v3/flavor_disabled.py b/nova/api/openstack/compute/plugins/v3/flavor_disabled.py deleted file mode 100644 index 79f6df9ceb..0000000000 --- a/nova/api/openstack/compute/plugins/v3/flavor_disabled.py +++ /dev/null @@ -1,91 +0,0 @@ -# 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 - -ALIAS = 'os-flavor-disabled' -authorize = extensions.soft_extension_authorizer('compute', 'v3:' + ALIAS) - - -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" % FlavorDisabled.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 FlavorDisabled(extensions.V3APIExtensionBase): - """Support to show the disabled status of a flavor.""" - - name = "FlavorDisabled" - alias = ALIAS - namespace = "http://docs.openstack.org/compute/ext/%s/api/v3" % ALIAS - version = 1 - - def get_controller_extensions(self): - controller = FlavorDisabledController() - extension = extensions.ControllerExtension(self, 'flavors', controller) - return [extension] - - def get_resources(self): - return [] - - -def make_flavor(elem): - elem.set('{%s}disabled' % FlavorDisabled.namespace, - '%s:disabled' % FlavorDisabled.alias) - - -class FlavorDisabledTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('flavor', selector='flavor') - make_flavor(root) - return xmlutil.SlaveTemplate(root, 1, nsmap={ - FlavorDisabled.alias: FlavorDisabled.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={ - FlavorDisabled.alias: FlavorDisabled.namespace}) diff --git a/nova/api/openstack/compute/plugins/v3/flavors.py b/nova/api/openstack/compute/plugins/v3/flavors.py index 5e0c3f2d6c..f503b41213 100644 --- a/nova/api/openstack/compute/plugins/v3/flavors.py +++ b/nova/api/openstack/compute/plugins/v3/flavors.py @@ -38,6 +38,7 @@ def make_flavor(elem, detailed=False): # NOTE(vish): this was originally added without a namespace elem.set('swap', xmlutil.EmptyStringSelector('swap')) elem.set('ephemeral', xmlutil.EmptyStringSelector('ephemeral')) + elem.set('disabled') xmlutil.make_links(elem, 'links') diff --git a/nova/api/openstack/compute/schemas/v3/flavor.rng b/nova/api/openstack/compute/schemas/v3/flavor.rng index da31595c37..691c3682bf 100644 --- a/nova/api/openstack/compute/schemas/v3/flavor.rng +++ b/nova/api/openstack/compute/schemas/v3/flavor.rng @@ -7,6 +7,7 @@ + diff --git a/nova/api/openstack/compute/views/flavors.py b/nova/api/openstack/compute/views/flavors.py index aa9f0f95bd..bc83d67819 100644 --- a/nova/api/openstack/compute/views/flavors.py +++ b/nova/api/openstack/compute/views/flavors.py @@ -78,5 +78,6 @@ class V3ViewBuilder(ViewBuilder): flavor_dict['flavor'].update({ "swap": flavor.get("swap") or "", "ephemeral": flavor.get("ephemeral_gb") or "", + "disabled": flavor.get("disabled", False) }) return flavor_dict diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_flavor_disabled.py b/nova/tests/api/openstack/compute/plugins/v3/test_flavor_disabled.py deleted file mode 100644 index 5ff7f4035f..0000000000 --- a/nova/tests/api/openstack/compute/plugins/v3/test_flavor_disabled.py +++ /dev/null @@ -1,101 +0,0 @@ -# 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. - -from lxml import etree -import webob - -from nova.api.openstack.compute.plugins.v3 import flavor_disabled -from nova.compute import flavors -from nova.openstack.common import jsonutils -from nova import test -from nova.tests.api.openstack import fakes - -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_flavor_get_by_flavor_id(flavorid): - return FAKE_FLAVORS['flavor %s' % flavorid] - - -def fake_flavor_get_all(*args, **kwargs): - return FAKE_FLAVORS - - -class FlavorDisabledTest(test.TestCase): - content_type = 'application/json' - prefix = '%s:' % flavor_disabled.FlavorDisabled.alias - - def setUp(self): - super(FlavorDisabledTest, self).setUp() - fakes.stub_out_nw_api(self.stubs) - self.stubs.Set(flavors, "get_all_flavors", - fake_flavor_get_all) - self.stubs.Set(flavors, - "get_flavor_by_flavor_id", - fake_flavor_get_by_flavor_id) - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - app = fakes.wsgi_app_v3(init_only=('servers', 'flavors', - 'os-flavor-disabled')) - return req.get_response(app) - - 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): - res = self._make_request('/v3/flavors/1') - self.assertEqual(res.status_int, 200, res.body) - self.assertFlavorDisabled(self._get_flavor(res.body), 'False') - - def test_detail(self): - res = self._make_request('/v3/flavors/detail') - - self.assertEqual(res.status_int, 200, res.body) - 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.FlavorDisabled.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/plugins/v3/test_flavors.py b/nova/tests/api/openstack/compute/plugins/v3/test_flavors.py index ec8b5548c6..4dad998811 100644 --- a/nova/tests/api/openstack/compute/plugins/v3/test_flavors.py +++ b/nova/tests/api/openstack/compute/plugins/v3/test_flavors.py @@ -22,6 +22,8 @@ import urlparse from nova.api.openstack.compute.plugins.v3 import flavors from nova.api.openstack import xmlutil +from nova.openstack.common import jsonutils + import nova.compute.flavors from nova import context from nova import db @@ -42,6 +44,7 @@ FAKE_FLAVORS = { "root_gb": '10', "swap": '512', "ephemeral_gb": '1', + "disabled": False, }, 'flavor 2': { "flavorid": '2', @@ -50,6 +53,7 @@ FAKE_FLAVORS = { "root_gb": '20', "swap": '1024', "ephemeral_gb": '10', + "disabled": True, }, } @@ -118,6 +122,7 @@ class FlavorsTest(test.TestCase): "vcpus": "", "swap": '512', "ephemeral": "1", + "disabled": False, "links": [ { "rel": "self", @@ -146,6 +151,7 @@ class FlavorsTest(test.TestCase): "vcpus": "", "swap": '512', "ephemeral": "1", + "disabled": False, "links": [ { "rel": "self", @@ -314,6 +320,7 @@ class FlavorsTest(test.TestCase): "vcpus": "", "swap": '512', "ephemeral": "1", + "disabled": False, "links": [ { "rel": "self", @@ -333,6 +340,7 @@ class FlavorsTest(test.TestCase): "vcpus": "", "swap": '1024', "ephemeral": "10", + "disabled": True, "links": [ { "rel": "self", @@ -434,6 +442,7 @@ class FlavorsTest(test.TestCase): "vcpus": "", "swap": '1024', "ephemeral": "10", + "disabled": True, "links": [ { "rel": "self", @@ -450,6 +459,62 @@ class FlavorsTest(test.TestCase): self.assertEqual(flavor, expected) +class FlavorDisabledTest(test.TestCase): + content_type = 'application/json' + + def setUp(self): + super(FlavorDisabledTest, self).setUp() + fakes.stub_out_nw_api(self.stubs) + + #def fake_flavor_get_all(*args, **kwargs): + # return FAKE_FLAVORS + # + self.stubs.Set(nova.compute.flavors, "get_all_flavors", + fake_flavor_get_all) + self.stubs.Set(nova.compute.flavors, + "get_flavor_by_flavor_id", + fake_flavor_get_by_flavor_id) + + def _make_request(self, url): + req = webob.Request.blank(url) + req.headers['Accept'] = self.content_type + app = fakes.wsgi_app_v3(init_only=('servers', 'flavors', + 'os-flavor-disabled')) + return req.get_response(app) + + 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('disabled')), disabled) + + def test_show(self): + res = self._make_request('/v3/flavors/1') + self.assertEqual(res.status_int, 200, res.body) + self.assertFlavorDisabled(self._get_flavor(res.body), 'False') + + def test_detail(self): + res = self._make_request('/v3/flavors/detail') + + self.assertEqual(res.status_int, 200, res.body) + flavors = self._get_flavors(res.body) + self.assertFlavorDisabled(flavors[0], 'False') + self.assertFlavorDisabled(flavors[1], 'True') + + +class FlavorDisabledXmlTest(FlavorDisabledTest): + content_type = 'application/xml' + + def _get_flavor(self, body): + return etree.XML(body) + + def _get_flavors(self, body): + return etree.XML(body).getchildren() + + class FlavorsXMLSerializationTest(test.TestCase): def _create_flavor(self): id = 0 @@ -463,6 +528,7 @@ class FlavorsXMLSerializationTest(test.TestCase): "vcpus": "", "swap": "512", "ephemeral": "512", + "disabled": False, "links": [ { "rel": "self", diff --git a/setup.cfg b/setup.cfg index 0b38f566aa..4c67d3227c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -80,7 +80,6 @@ nova.api.v3.extensions = flavors = nova.api.openstack.compute.plugins.v3.flavors:Flavors flavors_extraspecs = nova.api.openstack.compute.plugins.v3.flavors_extraspecs:FlavorsExtraSpecs flavor_access = nova.api.openstack.compute.plugins.v3.flavor_access:FlavorAccess - flavor_disabled = nova.api.openstack.compute.plugins.v3.flavor_disabled:FlavorDisabled flavor_rxtx = nova.api.openstack.compute.plugins.v3.flavor_rxtx:FlavorRxtx hide_server_addresses = nova.api.openstack.compute.plugins.v3.hide_server_addresses:HideServerAddresses hosts = nova.api.openstack.compute.plugins.v3.hosts:Hosts