summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nova/api/openstack/compute/flavor_manage.py7
-rw-r--r--nova/api/openstack/compute/legacy_v2/contrib/flavormanage.py8
-rw-r--r--nova/compute/flavors.py16
-rw-r--r--nova/db/api.py4
-rw-r--r--nova/db/sqlalchemy/api.py6
-rw-r--r--nova/objects/flavor.py19
-rw-r--r--nova/tests/functional/db/test_flavor.py14
-rw-r--r--nova/tests/unit/api/openstack/compute/test_flavor_manage.py25
-rw-r--r--nova/tests/unit/db/test_db_api.py12
-rw-r--r--nova/tests/unit/objects/test_flavor.py15
-rw-r--r--nova/tests/unit/test_flavors.py13
11 files changed, 47 insertions, 92 deletions
diff --git a/nova/api/openstack/compute/flavor_manage.py b/nova/api/openstack/compute/flavor_manage.py
index 4cd936ab1a..b4b73f415d 100644
--- a/nova/api/openstack/compute/flavor_manage.py
+++ b/nova/api/openstack/compute/flavor_manage.py
@@ -20,6 +20,7 @@ from nova.api import validation
from nova.compute import flavors
from nova import exception
from nova.i18n import _
+from nova import objects
ALIAS = "os-flavor-manage"
@@ -43,14 +44,12 @@ class FlavorManageController(wsgi.Controller):
context = req.environ['nova.context']
authorize(context)
+ flavor = objects.Flavor(context=context, flavorid=id)
try:
- flavor = flavors.get_flavor_by_flavor_id(
- id, ctxt=context, read_deleted="no")
+ flavor.destroy()
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
- flavors.destroy(flavor['name'])
-
# NOTE(oomichi): Return 200 for backwards compatibility but should be 201
# as this operation complete the creation of flavor resource.
@wsgi.action("create")
diff --git a/nova/api/openstack/compute/legacy_v2/contrib/flavormanage.py b/nova/api/openstack/compute/legacy_v2/contrib/flavormanage.py
index 073ec965e8..7d8deaa1ad 100644
--- a/nova/api/openstack/compute/legacy_v2/contrib/flavormanage.py
+++ b/nova/api/openstack/compute/legacy_v2/contrib/flavormanage.py
@@ -18,6 +18,7 @@ from nova.api.openstack import wsgi
from nova.compute import flavors
from nova import exception
from nova.i18n import _
+from nova import objects
authorize = extensions.extension_authorizer('compute', 'flavormanage')
@@ -34,14 +35,13 @@ class FlavorManageController(wsgi.Controller):
def _delete(self, req, id):
context = req.environ['nova.context']
authorize(context)
+
+ flavor = objects.Flavor(context=context, flavorid=id)
try:
- flavor = flavors.get_flavor_by_flavor_id(
- id, ctxt=context, read_deleted="no")
+ flavor.destroy()
except exception.FlavorNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
- flavors.destroy(flavor['name'])
-
return webob.Response(status_int=202)
@wsgi.action("create")
diff --git a/nova/compute/flavors.py b/nova/compute/flavors.py
index ded0e35055..660923da76 100644
--- a/nova/compute/flavors.py
+++ b/nova/compute/flavors.py
@@ -21,7 +21,6 @@
import re
import uuid
-from oslo_log import log as logging
from oslo_utils import strutils
import six
@@ -31,14 +30,11 @@ from nova import context
from nova import db
from nova import exception
from nova.i18n import _
-from nova.i18n import _LE
from nova import objects
from nova import utils
CONF = nova.conf.CONF
-LOG = logging.getLogger(__name__)
-
# NOTE(luisg): Flavor names can include non-ascii characters so that users can
# create flavor names in locales that use them, however flavor IDs are limited
# to ascii characters.
@@ -168,18 +164,6 @@ def create(name, memory, vcpus, root_gb, ephemeral_gb=0, flavorid=None,
return flavor
-def destroy(name):
- """Marks flavor as deleted."""
- try:
- if not name:
- raise ValueError()
- flavor = objects.Flavor(context=context.get_admin_context(), name=name)
- flavor.destroy()
- except (ValueError, exception.NotFound):
- LOG.exception(_LE('Instance type %s not found for deletion'), name)
- raise exception.FlavorNotFoundByName(flavor_name=name)
-
-
def get_all_flavors_sorted_list(ctxt=None, filters=None, sort_key='flavorid',
sort_dir='asc', limit=None, marker=None):
"""Get all non-deleted flavors as a sorted list.
diff --git a/nova/db/api.py b/nova/db/api.py
index a5bc8fe167..0036829872 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -1527,9 +1527,9 @@ def flavor_get_by_flavor_id(context, id, read_deleted=None):
return IMPL.flavor_get_by_flavor_id(context, id, read_deleted)
-def flavor_destroy(context, name):
+def flavor_destroy(context, flavor_id):
"""Delete an instance type."""
- return IMPL.flavor_destroy(context, name)
+ return IMPL.flavor_destroy(context, flavor_id)
def flavor_access_get_by_flavor_id(context, flavor_id):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 416fad8b10..0407e62ff0 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -5204,13 +5204,13 @@ def flavor_get_by_flavor_id(context, flavor_id, read_deleted):
@main_context_manager.writer
-def flavor_destroy(context, name):
+def flavor_destroy(context, flavor_id):
"""Marks specific flavor as deleted."""
ref = model_query(context, models.InstanceTypes, read_deleted="no").\
- filter_by(name=name).\
+ filter_by(flavorid=flavor_id).\
first()
if not ref:
- raise exception.FlavorNotFoundByName(flavor_name=name)
+ raise exception.FlavorNotFound(flavor_id=flavor_id)
ref.soft_delete(context.session)
model_query(context, models.InstanceTypeExtraSpecs, read_deleted="no").\
diff --git a/nova/objects/flavor.py b/nova/objects/flavor.py
index dc8efd8b3e..0007b2099e 100644
--- a/nova/objects/flavor.py
+++ b/nova/objects/flavor.py
@@ -168,20 +168,17 @@ def _flavor_create(context, values):
@db_api.api_context_manager.writer
-def _flavor_destroy(context, flavor_id=None, name=None):
+def _flavor_destroy(context, flavor_id=None, flavorid=None):
query = context.session.query(api_models.Flavors)
if flavor_id is not None:
query = query.filter(api_models.Flavors.id == flavor_id)
else:
- query = query.filter(api_models.Flavors.name == name)
+ query = query.filter(api_models.Flavors.flavorid == flavorid)
result = query.first()
if not result:
- if flavor_id is not None:
- raise exception.FlavorNotFound(flavor_id=flavor_id)
- else:
- raise exception.FlavorNotFoundByName(flavor_name=name)
+ raise exception.FlavorNotFound(flavor_id=(flavor_id or flavorid))
context.session.query(api_models.FlavorProjects).\
filter_by(flavor_id=result.id).delete()
@@ -576,8 +573,8 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
self.save_projects(added_projects, deleted_projects)
@staticmethod
- def _flavor_destroy(context, flavor_id=None, name=None):
- return _flavor_destroy(context, flavor_id=flavor_id, name=name)
+ def _flavor_destroy(context, flavor_id=None, flavorid=None):
+ return _flavor_destroy(context, flavor_id=flavor_id, flavorid=flavorid)
@base.remotable
def destroy(self):
@@ -591,9 +588,9 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
if 'id' in self:
self._flavor_destroy(self._context, flavor_id=self.id)
else:
- self._flavor_destroy(self._context, name=self.name)
+ self._flavor_destroy(self._context, flavorid=self.flavorid)
except exception.FlavorNotFound:
- db.flavor_destroy(self._context, self.name)
+ db.flavor_destroy(self._context, self.flavorid)
@db_api.api_context_manager.reader
@@ -721,7 +718,7 @@ def migrate_flavors(ctxt, count, hard_delete=False):
if hard_delete:
_destroy_flavor_hard(ctxt, flavor.name)
else:
- db.flavor_destroy(ctxt, flavor.name)
+ db.flavor_destroy(ctxt, flavor.flavorid)
except exception.FlavorNotFound:
LOG.warning(_LW('Flavor id %(id)i disappeared during migration'),
{'id': flavor_id})
diff --git a/nova/tests/functional/db/test_flavor.py b/nova/tests/functional/db/test_flavor.py
index 6ff52030c7..5d0574a955 100644
--- a/nova/tests/functional/db/test_flavor.py
+++ b/nova/tests/functional/db/test_flavor.py
@@ -61,7 +61,7 @@ class FlavorObjectTestCase(test.NoDBTestCase):
def _delete_main_flavors(self):
flavors = db_api.flavor_get_all(self.context)
for flavor in flavors:
- db_api.flavor_destroy(self.context, flavor['name'])
+ db_api.flavor_destroy(self.context, flavor['flavorid'])
def test_create(self):
self._delete_main_flavors()
@@ -181,13 +181,13 @@ class FlavorObjectTestCase(test.NoDBTestCase):
flavor = objects.Flavor.get_by_flavor_id(self.context, 'mainflavor')
self._test_destroy(flavor)
- def test_destroy_missing_flavor_by_name(self):
- flavor = objects.Flavor(context=self.context, name='foo')
- self.assertRaises(exception.FlavorNotFoundByName,
+ def test_destroy_missing_flavor_by_flavorid(self):
+ flavor = objects.Flavor(context=self.context, flavorid='foo')
+ self.assertRaises(exception.FlavorNotFound,
flavor.destroy)
def test_destroy_missing_flavor_by_id(self):
- flavor = objects.Flavor(context=self.context, name='foo', id=1234)
+ flavor = objects.Flavor(context=self.context, flavorid='foo', id=1234)
self.assertRaises(exception.FlavorNotFound,
flavor.destroy)
@@ -208,9 +208,7 @@ class FlavorObjectTestCase(test.NoDBTestCase):
self._test_get_all(expect_len + 1)
def test_get_all_with_all_api_flavors(self):
- db_flavors = db_api.flavor_get_all(self.context)
- for flavor in db_flavors:
- db_api.flavor_destroy(self.context, flavor['name'])
+ self._delete_main_flavors()
flavor = ForcedFlavor(context=self.context, **fake_api_flavor)
flavor.create()
self._test_get_all(1)
diff --git a/nova/tests/unit/api/openstack/compute/test_flavor_manage.py b/nova/tests/unit/api/openstack/compute/test_flavor_manage.py
index 368013ac3d..13baa9aa6b 100644
--- a/nova/tests/unit/api/openstack/compute/test_flavor_manage.py
+++ b/nova/tests/unit/api/openstack/compute/test_flavor_manage.py
@@ -15,6 +15,7 @@
import datetime
+import mock
from oslo_serialization import jsonutils
import six
import webob
@@ -52,20 +53,6 @@ def fake_db_flavor(**updates):
return db_flavor
-def fake_get_flavor_by_flavor_id(flavorid, ctxt=None, read_deleted='yes'):
- if flavorid == 'failtest':
- raise exception.FlavorNotFound(flavor_id=flavorid)
- elif not str(flavorid) == '1234':
- raise Exception("This test expects flavorid 1234, not %s" % flavorid)
- if read_deleted != 'no':
- raise test.TestingException("Should not be reading deleted")
- return fake_db_flavor(flavorid=flavorid)
-
-
-def fake_destroy(flavorname):
- pass
-
-
def fake_create(newflavor):
newflavor['flavorid'] = 1234
newflavor["name"] = 'test'
@@ -86,10 +73,6 @@ class FlavorManageTestV21(test.NoDBTestCase):
def setUp(self):
super(FlavorManageTestV21, self).setUp()
- self.stubs.Set(flavors,
- "get_flavor_by_flavor_id",
- fake_get_flavor_by_flavor_id)
- self.stubs.Set(flavors, "destroy", fake_destroy)
self.stub_out("nova.objects.Flavor.create", fake_create)
self.request_body = {
@@ -117,7 +100,8 @@ class FlavorManageTestV21(test.NoDBTestCase):
'os-flavor-access', 'flavors',
'os-flavor-extra-data'))
- def test_delete(self):
+ @mock.patch('nova.objects.Flavor.destroy')
+ def test_delete(self, mock_destroy):
res = self.controller._delete(self._get_http_request(), 1234)
# NOTE: on v2.1, http status code is set as wsgi_code of API
@@ -130,9 +114,10 @@ class FlavorManageTestV21(test.NoDBTestCase):
self.assertEqual(202, status_int)
# subsequent delete should fail
+ mock_destroy.side_effect = exception.FlavorNotFound(flavor_id=1234)
self.assertRaises(webob.exc.HTTPNotFound,
self.controller._delete, self._get_http_request(),
- "failtest")
+ 1234)
def _test_create_missing_parameter(self, parameter):
body = {
diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py
index bb7a2c9c4e..ca83f510d7 100644
--- a/nova/tests/unit/db/test_db_api.py
+++ b/nova/tests/unit/db/test_db_api.py
@@ -4018,7 +4018,7 @@ class InstanceTypeTestCase(BaseInstanceTypeTestCase):
flavor2 = self._create_flavor({'name': 'name2', 'flavorid': 'a2',
'extra_specs': specs2})
- db.flavor_destroy(self.ctxt, 'name1')
+ db.flavor_destroy(self.ctxt, 'a1')
self.assertRaises(exception.FlavorNotFound,
db.flavor_get, self.ctxt, flavor1['id'])
@@ -4067,7 +4067,7 @@ class InstanceTypeTestCase(BaseInstanceTypeTestCase):
def test_flavor_get_all(self):
# NOTE(boris-42): Remove base instance types
for it in db.flavor_get_all(self.ctxt):
- db.flavor_destroy(self.ctxt, it['name'])
+ db.flavor_destroy(self.ctxt, it['flavorid'])
flavors = [
{'root_gb': 600, 'memory_mb': 100, 'disabled': True,
@@ -4294,7 +4294,7 @@ class InstanceTypeTestCase(BaseInstanceTypeTestCase):
def test_flavor_get_by_flavor_id_deleted(self):
flavor = self._create_flavor({'name': 'abc', 'flavorid': '123'})
- db.flavor_destroy(self.ctxt, 'abc')
+ db.flavor_destroy(self.ctxt, '123')
flavor_by_fid = db.flavor_get_by_flavor_id(self.ctxt,
flavor['flavorid'], read_deleted='yes')
@@ -4306,7 +4306,7 @@ class InstanceTypeTestCase(BaseInstanceTypeTestCase):
param_dict = {'name': 'abc', 'flavorid': '123'}
self._create_flavor(param_dict)
- db.flavor_destroy(self.ctxt, 'abc')
+ db.flavor_destroy(self.ctxt, '123')
# Recreate the flavor with the same params
flavor = self._create_flavor(param_dict)
@@ -4472,13 +4472,13 @@ class InstanceTypeAccessTestCase(BaseInstanceTypeTestCase):
for v in values:
self._create_flavor_access(*v)
- db.flavor_destroy(self.ctxt, flavor1['name'])
+ db.flavor_destroy(self.ctxt, flavor1['flavorid'])
p = (self.ctxt, flavor1['flavorid'])
self.assertEqual(0, len(db.flavor_access_get_by_flavor_id(*p)))
p = (self.ctxt, flavor2['flavorid'])
self.assertEqual(1, len(db.flavor_access_get_by_flavor_id(*p)))
- db.flavor_destroy(self.ctxt, flavor2['name'])
+ db.flavor_destroy(self.ctxt, flavor2['flavorid'])
self.assertEqual(0, len(db.flavor_access_get_by_flavor_id(*p)))
diff --git a/nova/tests/unit/objects/test_flavor.py b/nova/tests/unit/objects/test_flavor.py
index cffad0f2ee..408ae0499c 100644
--- a/nova/tests/unit/objects/test_flavor.py
+++ b/nova/tests/unit/objects/test_flavor.py
@@ -353,11 +353,13 @@ class _TestFlavor(object):
flavor = flavor_obj.Flavor(id=123)
self.assertRaises(exception.ObjectActionError, flavor.save)
- def test_destroy(self):
- flavor = flavor_obj.Flavor(context=self.context, name='foo')
+ @mock.patch('nova.objects.Flavor._flavor_destroy')
+ def test_destroy(self, mock_destroy):
+ mock_destroy.side_effect = exception.FlavorNotFound(flavor_id='foo')
+ flavor = flavor_obj.Flavor(context=self.context, flavorid='foo')
with mock.patch.object(db, 'flavor_destroy') as destroy:
flavor.destroy()
- destroy.assert_called_once_with(self.context, flavor.name)
+ destroy.assert_called_once_with(self.context, flavor.flavorid)
@mock.patch('nova.objects.Flavor._flavor_destroy')
def test_destroy_api_by_id(self, mock_destroy):
@@ -366,10 +368,11 @@ class _TestFlavor(object):
mock_destroy.assert_called_once_with(self.context, flavor_id=flavor.id)
@mock.patch('nova.objects.Flavor._flavor_destroy')
- def test_destroy_api_by_name(self, mock_destroy):
- flavor = flavor_obj.Flavor(context=self.context, name='foo')
+ def test_destroy_api_by_flavorid(self, mock_destroy):
+ flavor = flavor_obj.Flavor(context=self.context, flavorid='foo')
flavor.destroy()
- mock_destroy.assert_called_once_with(self.context, name=flavor.name)
+ mock_destroy.assert_called_once_with(self.context,
+ flavorid=flavor.flavorid)
def test_load_projects(self):
flavor = flavor_obj.Flavor(context=self.context, flavorid='foo')
diff --git a/nova/tests/unit/test_flavors.py b/nova/tests/unit/test_flavors.py
index 69f9f0ebfb..0673735cf9 100644
--- a/nova/tests/unit/test_flavors.py
+++ b/nova/tests/unit/test_flavors.py
@@ -61,17 +61,6 @@ DEFAULT_FLAVOR_OBJS = [
class InstanceTypeTestCase(test.TestCase):
"""Test cases for flavor code."""
- def test_non_existent_inst_type_should_not_delete(self):
- # Ensures that flavor creation fails with invalid args.
- self.assertRaises(exception.FlavorNotFoundByName,
- flavors.destroy,
- 'unknown_flavor')
-
- def test_will_not_destroy_with_no_name(self):
- # Ensure destroy said path of no name raises error.
- self.assertRaises(exception.FlavorNotFoundByName,
- flavors.destroy, None)
-
def test_will_not_get_bad_default_instance_type(self):
# ensures error raised on bad default flavor.
self.flags(default_flavor='unknown_flavor')
@@ -432,7 +421,7 @@ class CreateInstanceTypeTest(test.TestCase):
self.assertNotEqual(len(original_list), len(new_list),
'instance type was not created')
- flavors.destroy('flavor')
+ flavor.destroy()
self.assertRaises(exception.FlavorNotFound,
objects.Flavor.get_by_name, ctxt, flavor.name)