Prevent updating os_id of db items

Updating of db item's os_id should be disabled. But a special case (None
-> smth) should be allowed.

Change-Id: I9a38c99d1a5d024ef38339e8d41eff7856cb3ebe
This commit is contained in:
Feodor Tersin 2015-09-09 17:52:18 +03:00
parent 4f35af8502
commit 4cd4f28870
3 changed files with 28 additions and 1 deletions

View File

@ -29,6 +29,7 @@ from sqlalchemy.sql import bindparam
import ec2api.context
from ec2api.db.sqlalchemy import models
from ec2api import exception
CONF = cfg.CONF
@ -142,8 +143,12 @@ def add_item_id(context, kind, os_id, project_id=None):
def update_item(context, item):
item_ref = (model_query(context, models.Item).
filter_by(project_id=context.project_id,
id=item["id"]).
id=item['id']).
one())
if item_ref.os_id and item_ref.os_id != item['os_id']:
raise exception.EC2DBInvalidOsIdUpdate(item_id=item['id'],
old_os_id=item_ref.os_id,
new_os_id=item['os_id'])
item_ref.update(_pack_item_data(item))
item_ref.save()
return _unpack_item_data(item_ref)

View File

@ -100,6 +100,11 @@ class EC2KeystoneDiscoverFailure(EC2APIException):
msg_fmt = _("Could not discover keystone versions.")
class EC2DBInvalidOsIdUpdate(EC2APIException):
msg_fmt = _('Invalid update of os_id of %(item_id)s item '
'from %(old_os_id)s to %(new_os_id)s')
# Internal ec2api metadata exceptions
class EC2MetadataException(EC2APIException):

View File

@ -17,6 +17,7 @@ from sqlalchemy.orm import exc as orm_exception
from ec2api.api import validator
from ec2api.db import api as db_api
from ec2api import exception
from ec2api.tests.unit import base
from ec2api.tests.unit import fakes
from ec2api.tests.unit import matchers
@ -142,6 +143,22 @@ class DbApiTestCase(base.DbTestCase):
{'id': fakes.random_ec2_id('fake'),
'key': 'val'})
def test_update_item_os_id(self):
item = db_api.add_item(self.context, 'fake', {})
item['os_id'] = 'fake_os_id'
db_api.update_item(self.context, item)
item = db_api.get_item_by_id(self.context, item['id'])
self.assertThat({'os_id': 'fake_os_id'},
matchers.IsSubDictOf(item))
item['os_id'] = 'other_fake_os_id'
self.assertRaises(exception.EC2DBInvalidOsIdUpdate,
db_api.update_item,
self.context, item)
item['os_id'] = None
self.assertRaises(exception.EC2DBInvalidOsIdUpdate,
db_api.update_item,
self.context, item)
def test_delete_item(self):
item = db_api.add_item(self.context, 'fake', {})
db_api.delete_item(self.context, item['id'])