diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index 70413fafd51a..ceb365380b6f 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -103,6 +103,7 @@ _EXTRA_DEFAULT_LOG_LEVELS = ['oslo_db=INFO', 'oslo_policy=INFO'] # Decorators for actions args = cmd_common.args +action_description = cmd_common.action_description def param2id(object_id): @@ -1397,6 +1398,49 @@ class CellV2Commands(object): cell_mapping=cell_mapping) host_mapping.create() + @action_description( + _("Add a new cell to nova API database. " + "DB and MQ urls can be provided directly " + "or can be taken from config. The result is cell uuid.")) + @args('--name', metavar='', help=_('The name of the cell')) + @args('--database_connection', metavar='', + dest='database_connection', + help=_('The database url for the cell database')) + @args('--transport-url', metavar='', dest='transport_url', + help=_('The transport url for the cell message queue')) + @args('--verbose', action='store_true', + help=_('Output the uuid of the created cell')) + def create_cell(self, name=None, database_connection=None, + transport_url=None, verbose=False): + ctxt = context.get_context() + transport_url = transport_url or CONF.transport_url + if not transport_url: + print(_('Must specify --transport-url if [DEFAULT]/transport_url ' + 'is not set in the configuration file.')) + return 1 + database_connection = database_connection or CONF.database.connection + if not database_connection: + print(_('Must specify --database_connection ' + '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')) + return 2 + cell_mapping_uuid = uuidutils.generate_uuid() + cell_mapping = objects.CellMapping( + ctxt, + uuid=cell_mapping_uuid, name=name, + transport_url=transport_url, + database_connection=database_connection) + cell_mapping.create() + if verbose: + print(cell_mapping_uuid) + return 0 + CATEGORIES = { 'account': AccountCommands, diff --git a/nova/tests/unit/test_nova_manage.py b/nova/tests/unit/test_nova_manage.py index 512a2db3a1ee..1f6de461704c 100644 --- a/nova/tests/unit/test_nova_manage.py +++ b/nova/tests/unit/test_nova_manage.py @@ -1370,6 +1370,62 @@ class CellV2CommandsTestCase(test.NoDBTestCase): self.assertEqual(from_cli, self.commands._validate_transport_url(from_cli)) + def test_create_cell_use_params(self): + ctxt = context.get_context() + kwargs = dict( + name='fake-name', + transport_url='fake-transport-url', + database_connection='fake-db-connection') + status = self.commands.create_cell(verbose=True, **kwargs) + self.assertEqual(0, status) + cell2_uuid = self.output.getvalue().strip() + self.commands.create_cell(**kwargs) + cell2 = objects.CellMapping.get_by_uuid(ctxt, cell2_uuid) + self.assertEqual(kwargs['name'], cell2.name) + self.assertEqual(kwargs['database_connection'], + cell2.database_connection) + self.assertEqual(kwargs['transport_url'], cell2.transport_url) + + def test_create_cell_use_config_values(self): + settings = dict( + transport_url='fake-conf-transport-url', + database_connection='fake-conf-db-connection') + self.flags(connection=settings['database_connection'], + group='database') + self.flags(transport_url=settings['transport_url']) + ctxt = context.get_context() + + status = self.commands.create_cell(verbose=True) + self.assertEqual(0, status) + cell1_uuid = self.output.getvalue().strip() + cell1 = objects.CellMapping.get_by_uuid(ctxt, cell1_uuid) + self.assertIsNone(cell1.name) + self.assertEqual(settings['database_connection'], + cell1.database_connection) + self.assertEqual(settings['transport_url'], cell1.transport_url) + + def test_create_cell_failed_if_non_unique(self): + kwargs = dict( + name='fake-name', + transport_url='fake-transport-url', + database_connection='fake-db-connection') + status1 = self.commands.create_cell(verbose=True, **kwargs) + status2 = self.commands.create_cell(verbose=True, **kwargs) + self.assertEqual(0, status1) + self.assertEqual(2, status2) + self.assertIn('exists', self.output.getvalue()) + + def test_create_cell_failed_if_no_transport_url(self): + status = self.commands.create_cell() + self.assertEqual(1, status) + self.assertIn('--transport-url', self.output.getvalue()) + + def test_create_cell_failed_if_no_database_connection(self): + self.flags(connection=None, group='database') + status = self.commands.create_cell(transport_url='fake-transport-url') + self.assertEqual(1, status) + self.assertIn('--database_connection', self.output.getvalue()) + class TestNovaManageMain(test.NoDBTestCase): """Tests the nova-manage:main() setup code."""