Merge "update_cell allows more than once cell to have the same db/transport url"

This commit is contained in:
Zuul 2018-01-16 11:12:03 +00:00 committed by Gerrit Code Review
commit d9ba29fd6e
3 changed files with 77 additions and 10 deletions

View File

@ -231,9 +231,10 @@ Nova Cells v2
defined by ``[database]/connection`` in the configuration file. If a
transport_url is not specified, it will attempt to use the one defined by
``[DEFAULT]/transport_url`` in the configuration file. If the cell is not
found by uuid, this command will return an exit code of 1. If the
properties cannot be set, this will return 2. Otherwise, the exit code will
be 0.
found by uuid, this command will return an exit code of 1. If the provided
transport_url or/and database_connection is/are same as another cell,
this command will return an exit code of 3. If the properties cannot be set,
this will return 2. Otherwise, the exit code will be 0.
.. note::

View File

@ -931,6 +931,17 @@ class CellV2Commands(object):
'is not set in the configuration file.')
return transport_url
def _non_unique_transport_url_database_connection_checker(self, ctxt,
transport_url, database_connection):
for cell in objects.CellMappingList.get_all(ctxt):
if (cell.database_connection == database_connection or
cell.transport_url == transport_url):
print(_('The specified transport_url and/or '
'database_connection combination already exists '
'for another cell with uuid %s.') % cell.uuid)
return True
return False
@args('--transport-url', metavar='<transport_url>', dest='transport_url',
help='The transport url for the cell message queue')
def simple_cell_setup(self, transport_url=None):
@ -1308,11 +1319,8 @@ class CellV2Commands(object):
'if [database]/connection is not set '
'in the configuration file.'))
return 1
if any(cell.database_connection == database_connection
and cell.transport_url == transport_url
for cell in objects.CellMappingList.get_all(ctxt)):
print(_('Cell with the specified transport_url '
'and database_connection combination already exists'))
if (self._non_unique_transport_url_database_connection_checker(ctxt,
transport_url, database_connection)):
return 2
cell_mapping_uuid = uuidutils.generate_uuid()
cell_mapping = objects.CellMapping(
@ -1433,7 +1441,9 @@ class CellV2Commands(object):
"""Updates the properties of a cell by the given uuid.
If the cell is not found by uuid, this command will return an exit
code of 1. If the properties cannot be set, this will return 2.
code of 1. If the provided transport_url or/and database_connection
is/are same as another cell, this command will return an exit code
of 3. If the properties cannot be set, this will return 2.
Otherwise, the exit code will be 0.
NOTE: Updating the transport_url or database_connection fields on
@ -1451,10 +1461,17 @@ class CellV2Commands(object):
cell_mapping.name = name
transport_url = transport_url or CONF.transport_url
db_connection = db_connection or CONF.database.connection
if (self._non_unique_transport_url_database_connection_checker(ctxt,
transport_url, db_connection)):
# We use the return code 3 before 2 to avoid changing the
# semantic meanings of return codes.
return 3
if transport_url:
cell_mapping.transport_url = transport_url
db_connection = db_connection or CONF.database.connection
if db_connection:
cell_mapping.database_connection = db_connection

View File

@ -1554,6 +1554,26 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
self.assertEqual(from_cli,
self.commands._validate_transport_url(from_cli))
def test_non_unique_transport_url_database_connection_checker(self):
ctxt = context.RequestContext()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1,
name='cell1',
transport_url='fake://mq1',
database_connection='fake:///db1').create()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell2,
name='cell2',
transport_url='fake://mq2',
database_connection='fake:///db2').create()
resultf = self.commands.\
_non_unique_transport_url_database_connection_checker(
ctxt, 'fake://mq3', 'fake:///db3')
resultt = self.commands.\
_non_unique_transport_url_database_connection_checker(
ctxt, 'fake://mq1', 'fake:///db1')
self.assertFalse(resultf)
self.assertTrue(resultt)
self.assertIn('exists', self.output.getvalue())
def test_create_cell_use_params(self):
ctxt = context.get_context()
kwargs = dict(
@ -1778,6 +1798,35 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
uuidsentinel.cell1, 'foo', 'fake://new', 'fake:///new'))
self.assertIn('not found', self.output.getvalue())
def test_update_cell_failed_if_non_unique_transport_db_urls(self):
ctxt = context.get_admin_context()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1,
name='cell1',
transport_url='fake://mq1',
database_connection='fake:///db1').create()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell2,
name='cell2',
transport_url='fake://mq2',
database_connection='fake:///db2').create()
cell2_update1 = self.commands.update_cell(
uuidsentinel.cell2, 'foo', 'fake://mq1', 'fake:///db1')
self.assertEqual(3, cell2_update1)
self.assertIn('exists', self.output.getvalue())
cell2_update2 = self.commands.update_cell(
uuidsentinel.cell2, 'foo', 'fake://mq1', 'fake:///db3')
self.assertEqual(3, cell2_update2)
self.assertIn('exists', self.output.getvalue())
cell2_update3 = self.commands.update_cell(
uuidsentinel.cell2, 'foo', 'fake://mq3', 'fake:///db1')
self.assertEqual(3, cell2_update3)
self.assertIn('exists', self.output.getvalue())
cell2_update4 = self.commands.update_cell(
uuidsentinel.cell2, 'foo', 'fake://mq3', 'fake:///db3')
self.assertEqual(0, cell2_update4)
def test_update_cell_failed(self):
ctxt = context.get_admin_context()
objects.CellMapping(context=ctxt, uuid=uuidsentinel.cell1,