Merge "Merged flavor_disabled extension into V3 core api"

This commit is contained in:
Jenkins
2013-08-12 17:55:32 +00:00
committed by Gerrit Code Review
7 changed files with 69 additions and 193 deletions
@@ -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})
@@ -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')
@@ -7,6 +7,7 @@
<attribute name="vcpus"> <text/> </attribute>
<attribute name="swap"> <text/> </attribute>
<attribute name="ephemeral"> <text/> </attribute>
<attribute name="disabled"> <text/> </attribute>
<zeroOrMore>
<externalRef href="../atom-link.rng"/>
</zeroOrMore>
@@ -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
@@ -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()
@@ -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",
-1
View File
@@ -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