Update aggregate should not allow duplicated names

It is not allow to create 2 aggregates with the same name
but if update an existing one with a name already used
by other aggregate that check should be made.
This patch doesn't allow to change the name to an existing
one.

Change-Id: Icfe315594beaec94229e5a4a4c1bb80fc366b66e
Closes-Bug: #1288296
This commit is contained in:
Juan Manuel Olle 2014-03-06 17:38:07 -03:00
parent 7611173937
commit 2b2decfd1b
6 changed files with 50 additions and 1 deletions

View File

@ -127,6 +127,8 @@ class AggregateController(object):
try:
aggregate = self.api.update_aggregate(context, id, updates)
except exception.AggregateNameExists as e:
raise exc.HTTPConflict(explanation=e.format_message())
except exception.AggregateNotFound:
LOG.info(_('Cannot update aggregate: %s'), id)
raise exc.HTTPNotFound()

View File

@ -111,7 +111,7 @@ class AggregateController(wsgi.Controller):
raise exc.HTTPNotFound(explanation=e.format_message())
return self._marshall_aggregate(aggregate)
@extensions.expected_errors((400, 404))
@extensions.expected_errors((400, 404, 409))
def update(self, req, id, body):
"""Updates the name and/or availability_zone of given aggregate."""
context = _get_context(req)
@ -136,6 +136,8 @@ class AggregateController(wsgi.Controller):
try:
aggregate = self.api.update_aggregate(context, id, updates)
except exception.AggregateNameExists as e:
raise exc.HTTPConflict(explanation=e.format_message())
except exception.AggregateNotFound as e:
raise exc.HTTPNotFound(explanation=e.format_message())
except exception.InvalidAggregateAction as e:

View File

@ -5095,6 +5095,18 @@ def aggregate_host_get_by_metadata_key(context, key):
def aggregate_update(context, aggregate_id, values):
session = get_session()
if "name" in values:
aggregate_by_name = (_aggregate_get_query(context,
models.Aggregate,
models.Aggregate.name,
values['name'],
session=session,
read_deleted='no').first())
if aggregate_by_name and aggregate_by_name.id != aggregate_id:
# there is another aggregate with the new name
raise exception.AggregateNameExists(aggregate_name=values['name'])
aggregate = (_aggregate_get_query(context,
models.Aggregate,
models.Aggregate.id,

View File

@ -264,6 +264,17 @@ class AggregateTestCase(test.NoDBTestCase):
self.assertRaises(exc.HTTPNotFound, self.controller.update,
self.req, "2", body=test_metadata)
def test_update_with_duplicated_name(self):
test_metadata = {"aggregate": {"name": "test_name"}}
def stub_update_aggregate(context, aggregate, metadata):
raise exception.AggregateNameExists(aggregate_name="test_name")
self.stubs.Set(self.controller.api, "update_aggregate",
stub_update_aggregate)
self.assertRaises(exc.HTTPConflict, self.controller.update,
self.req, "2", body=test_metadata)
def test_invalid_action(self):
body = {"append_host": {"host": "host1"}}
self.assertRaises(exc.HTTPBadRequest,

View File

@ -256,6 +256,17 @@ class AggregateTestCase(test.NoDBTestCase):
self.assertRaises(exc.HTTPNotFound, self.controller.update,
self.req, "2", body=test_metadata)
def test_update_with_duplicated_name(self):
test_metadata = {"aggregate": {"name": "test_name"}}
def stub_update_aggregate(context, aggregate, metadata):
raise exception.AggregateNameExists(aggregate_name="test_name")
self.stubs.Set(self.controller.api, "update_aggregate",
stub_update_aggregate)
self.assertRaises(exc.HTTPConflict, self.controller.update,
self.req, "2", body=test_metadata)
def test_update_with_invalid_request(self):
test_metadata = {"aggregate": 1}
self.assertRaises(exc.HTTPBadRequest, self.controller.update,

View File

@ -528,6 +528,17 @@ class AggregateDBApiTestCase(test.TestCase):
self.assertRaises(exception.AggregateNotFound,
db.aggregate_update, ctxt, aggregate_id, new_values)
def test_aggregate_update_raise_name_exist(self):
ctxt = context.get_admin_context()
_create_aggregate(context=ctxt, values={'name': 'test1'},
metadata={'availability_zone': 'fake_avail_zone'})
_create_aggregate(context=ctxt, values={'name': 'test2'},
metadata={'availability_zone': 'fake_avail_zone'})
aggregate_id = 1
new_values = {'name': 'test2'}
self.assertRaises(exception.AggregateNameExists,
db.aggregate_update, ctxt, aggregate_id, new_values)
def test_aggregate_get_all(self):
ctxt = context.get_admin_context()
counter = 3