Object-ify APIv2 flavorextraspecs extension

This makes the flavorextraspecs extension use the Flavor object.

Related to blueprint compute-manager-objects-juno

Change-Id: I28bcc24382f1e993b98b3f7342fed53c9ae85cbf
This commit is contained in:
Dan Smith 2014-06-17 17:59:04 -07:00
parent 4115b522b3
commit 0c1484ec03
2 changed files with 66 additions and 24 deletions

View File

@ -21,8 +21,8 @@ from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova.compute import flavors
from nova import db
from nova import exception
from nova import objects
from nova.openstack.common.gettextutils import _
from nova import utils
@ -48,8 +48,8 @@ class FlavorExtraSpecsController(object):
"""The flavor extra specs API controller for the OpenStack API."""
def _get_extra_specs(self, context, flavor_id):
extra_specs = db.flavor_extra_specs_get(context, flavor_id)
return dict(extra_specs=extra_specs)
flavor = objects.Flavor.get_by_flavor_id(context, flavor_id)
return dict(extra_specs=flavor.extra_specs)
def _check_body(self, body):
if body is None or body == "":
@ -90,11 +90,13 @@ class FlavorExtraSpecsController(object):
specs = body.get('extra_specs')
self._check_extra_specs(specs)
try:
db.flavor_extra_specs_update_or_create(context,
flavor_id,
specs)
flavor = objects.Flavor.get_by_flavor_id(context, flavor_id)
flavor.extra_specs = dict(flavor.extra_specs, **specs)
flavor.save()
except exception.MetadataLimitExceeded as error:
raise exc.HTTPBadRequest(explanation=error.format_message())
except exception.FlavorNotFound as error:
raise exc.HTTPNotFound(explanation=error.format_message())
return body
@wsgi.serializers(xml=ExtraSpecTemplate)
@ -109,11 +111,13 @@ class FlavorExtraSpecsController(object):
expl = _('Request body contains too many items')
raise exc.HTTPBadRequest(explanation=expl)
try:
db.flavor_extra_specs_update_or_create(context,
flavor_id,
body)
flavor = objects.Flavor.get_by_flavor_id(context, flavor_id)
flavor.extra_specs = dict(flavor.extra_specs, **body)
flavor.save()
except exception.MetadataLimitExceeded as error:
raise exc.HTTPBadRequest(explanation=error.format_message())
except exception.FlavorNotFound as error:
raise exc.HTTPNotFound(explanation=error.format_message())
return body
@wsgi.serializers(xml=ExtraSpecTemplate)
@ -122,20 +126,31 @@ class FlavorExtraSpecsController(object):
context = req.environ['nova.context']
authorize(context, action='show')
try:
extra_spec = db.flavor_extra_specs_get_item(context,
flavor_id, id)
return extra_spec
except exception.FlavorExtraSpecsNotFound:
raise exc.HTTPNotFound()
flavor = objects.Flavor.get_by_flavor_id(context, flavor_id)
return {id: flavor.extra_specs[id]}
except exception.FlavorNotFound as error:
raise exc.HTTPNotFound(explanation=error.format_message())
except KeyError:
msg = _("Flavor %(flavor_id)s has no extra specs with "
"key %(key)s.") % dict(flavor_id=flavor_id,
key=id)
raise exc.HTTPNotFound(explanation=msg)
def delete(self, req, flavor_id, id):
"""Deletes an existing extra spec."""
context = req.environ['nova.context']
authorize(context, action='delete')
try:
db.flavor_extra_specs_delete(context, flavor_id, id)
except exception.FlavorExtraSpecsNotFound as e:
flavor = objects.Flavor.get_by_flavor_id(context, flavor_id)
del flavor.extra_specs[id]
flavor.save()
except exception.FlavorNotFound as e:
raise exc.HTTPNotFound(explanation=e.format_message())
except KeyError:
msg = _("Flavor %(flavor_id)s has no extra specs with "
"key %(key)s.") % dict(flavor_id=flavor_id,
key=id)
raise exc.HTTPNotFound(explanation=msg)
class Flavorextraspecs(extensions.ExtensionDescriptor):

View File

@ -21,6 +21,7 @@ import nova.db
from nova import exception
from nova import test
from nova.tests.api.openstack import fakes
from nova.tests.objects import test_flavor
def return_create_flavor_extra_specs(context, flavor_id, extra_specs):
@ -61,11 +62,13 @@ class FlavorsExtraSpecsTest(test.TestCase):
self.controller = flavorextraspecs.FlavorExtraSpecsController()
def test_index(self):
self.stubs.Set(nova.db, 'flavor_extra_specs_get',
return_flavor_extra_specs)
flavor = dict(test_flavor.fake_flavor,
extra_specs={'key1': 'value1'})
req = fakes.HTTPRequest.blank('/v2/fake/flavors/1/os-extra_specs')
res_dict = self.controller.index(req, 1)
with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
mock_get.return_value = flavor
res_dict = self.controller.index(req, 1)
self.assertEqual('value1', res_dict['extra_specs']['key1'])
@ -79,12 +82,13 @@ class FlavorsExtraSpecsTest(test.TestCase):
self.assertEqual(0, len(res_dict['extra_specs']))
def test_show(self):
self.stubs.Set(nova.db, 'flavor_extra_specs_get_item',
return_flavor_extra_specs_item)
flavor = dict(test_flavor.fake_flavor,
extra_specs={'key5': 'value5'})
req = fakes.HTTPRequest.blank('/v2/fake/flavors/1/os-extra_specs' +
'/key5')
res_dict = self.controller.show(req, 1, 'key5')
with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
mock_get.return_value = flavor
res_dict = self.controller.show(req, 1, 'key5')
self.assertEqual('value5', res_dict['key5'])
@ -97,13 +101,36 @@ class FlavorsExtraSpecsTest(test.TestCase):
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
req, 1, 'key6')
def test_not_found_because_flavor(self):
req = fakes.HTTPRequestV3.blank('/flavors/1/extra-specs/key5',
use_admin_context=True)
with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
mock_get.side_effect = exception.FlavorNotFound(flavor_id='1')
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
req, 1, 'key5')
self.assertRaises(webob.exc.HTTPNotFound, self.controller.update,
req, 1, 'key5', {'key5': 'value5'})
self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
req, 1, 'key5')
req = fakes.HTTPRequestV3.blank('/flavors/1/extra-specs',
use_admin_context=True)
with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
mock_get.side_effect = exception.FlavorNotFound(flavor_id='1')
self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
req, 1, {'extra_specs': {'key5': 'value5'}})
def test_delete(self):
flavor = dict(test_flavor.fake_flavor,
extra_specs={'key5': 'value5'})
self.stubs.Set(nova.db, 'flavor_extra_specs_delete',
delete_flavor_extra_specs)
req = fakes.HTTPRequest.blank('/v2/fake/flavors/1/os-extra_specs' +
'/key5', use_admin_context=True)
self.controller.delete(req, 1, 'key5')
with mock.patch('nova.db.flavor_get_by_flavor_id') as mock_get:
mock_get.return_value = flavor
self.controller.delete(req, 1, 'key5')
def test_delete_no_admin(self):
self.stubs.Set(nova.db, 'flavor_extra_specs_delete',