From d876680b8362e127ae6e1573ce7da40929e33752 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Mon, 8 Aug 2016 15:49:59 +0530 Subject: [PATCH] Add prefix to user message event ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the 'VOLUME_' prefix to all message event ids. This will prevent collisions and confusion when other projects add user messages and create their own event ids. Also fix issue where request_id column is nullable in sqlalchemy model but not properly set in the db migration. Implements blueprint summarymessage Co-Authored-By: Sheel Rana Co-Authored-By: MichaƂ Dulko Change-Id: Ic23f898281870ad81c5a123302ddca50905952ea --- cinder/cmd/manage.py | 3 +- cinder/db/api.py | 13 +++ cinder/db/sqlalchemy/api.py | 18 ++++ .../087_allow_null_request_id_in_message.py | 21 +++++ cinder/message/defined_messages.py | 36 +++++--- cinder/scheduler/flows/create_volume.py | 2 +- cinder/tests/unit/api/v3/fakes.py | 2 +- cinder/tests/unit/api/v3/stubs.py | 42 +++++++++ cinder/tests/unit/message/test_api.py | 46 +++++----- .../unit/message/test_defined_messages.py | 46 ++++++++++ cinder/tests/unit/scheduler/test_scheduler.py | 2 +- cinder/tests/unit/test_db_api.py | 87 +++++++++++++++++++ cinder/tests/unit/test_migrations.py | 13 +++ cinder/tests/unit/test_volume.py | 5 +- cinder/volume/manager.py | 5 +- doc/source/devref/user_messages.rst | 2 +- 16 files changed, 299 insertions(+), 44 deletions(-) create mode 100644 cinder/db/sqlalchemy/migrate_repo/versions/087_allow_null_request_id_in_message.py create mode 100644 cinder/tests/unit/api/v3/stubs.py create mode 100644 cinder/tests/unit/message/test_defined_messages.py diff --git a/cinder/cmd/manage.py b/cinder/cmd/manage.py index 94b2d42e609..3804da9475b 100644 --- a/cinder/cmd/manage.py +++ b/cinder/cmd/manage.py @@ -207,7 +207,8 @@ class HostCommands(object): class DbCommands(object): """Class for managing the database.""" - online_migrations = (db.migrate_consistencygroups_to_groups,) + online_migrations = (db.migrate_consistencygroups_to_groups, + db.migrate_add_message_prefix) def __init__(self): pass diff --git a/cinder/db/api.py b/cinder/db/api.py index 291031be31e..46ee08c95c0 100644 --- a/cinder/db/api.py +++ b/cinder/db/api.py @@ -1325,6 +1325,19 @@ def consistencygroup_include_in_cluster(context, cluster, partial_rename=True, **filters) +def migrate_add_message_prefix(context, max_count, force=False): + """Change Message event ids to start with the VOLUME_ prefix. + + :param max_count: The maximum number of messages to consider in + this run. + :param force: Ignored in this migration + :returns: number of messages needing migration, number of + messages migrated (both will always be less than + max_count). + """ + return IMPL.migrate_add_message_prefix(context, max_count, force) + + ################### diff --git a/cinder/db/sqlalchemy/api.py b/cinder/db/sqlalchemy/api.py index 48fbdf94843..00771cf5462 100644 --- a/cinder/db/sqlalchemy/api.py +++ b/cinder/db/sqlalchemy/api.py @@ -5397,6 +5397,24 @@ def consistencygroup_include_in_cluster(context, cluster, partial_rename, filters) +@require_admin_context +def migrate_add_message_prefix(context, max_count, force=False): + prefix = "VOLUME_" + session = get_session() + with session.begin(): + messages = (model_query(context, models.Message.id, session=session). + filter(~models.Message.event_id.like(prefix + '%')). + limit(max_count)) + + count_all = messages.count() + count_hit = (model_query(context, models.Message, session=session). + filter(models.Message.id.in_(messages.as_scalar())). + update({'event_id': prefix + models.Message.event_id}, + synchronize_session=False)) + + return count_all, count_hit + + ############################### diff --git a/cinder/db/sqlalchemy/migrate_repo/versions/087_allow_null_request_id_in_message.py b/cinder/db/sqlalchemy/migrate_repo/versions/087_allow_null_request_id_in_message.py new file mode 100644 index 00000000000..d855f11f181 --- /dev/null +++ b/cinder/db/sqlalchemy/migrate_repo/versions/087_allow_null_request_id_in_message.py @@ -0,0 +1,21 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import MetaData, Table + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + messages = Table('messages', meta, autoload=True) + messages.c.request_id.alter(nullable=True) diff --git a/cinder/message/defined_messages.py b/cinder/message/defined_messages.py index 9fac0b6c578..dac75ec7229 100644 --- a/cinder/message/defined_messages.py +++ b/cinder/message/defined_messages.py @@ -21,24 +21,32 @@ specific. from cinder.i18n import _ -UNKNOWN_ERROR = '000001' -UNABLE_TO_ALLOCATE = '000002' -ATTACH_READONLY_VOLUME = '000003' -IMAGE_FROM_VOLUME_OVER_QUOTA = '000004' + +class EventIds(object): + UNKNOWN_ERROR = 'VOLUME_000001' + UNABLE_TO_ALLOCATE = 'VOLUME_000002' + ATTACH_READONLY_VOLUME = 'VOLUME_000003' + IMAGE_FROM_VOLUME_OVER_QUOTA = 'VOLUME_000004' + event_id_message_map = { - UNKNOWN_ERROR: _("An unknown error occurred."), - UNABLE_TO_ALLOCATE: _("No storage could be allocated for this volume " - "request. You may be able to try another size or" - " volume type."), - ATTACH_READONLY_VOLUME: _("A readonly volume must be attached as " - "readonly."), - IMAGE_FROM_VOLUME_OVER_QUOTA: _("Failed to copy volume to image as image " - "quota has been met. Please delete images" - " or have your limit increased, then try " - "again."), + EventIds.UNKNOWN_ERROR: _("An unknown error occurred."), + EventIds.UNABLE_TO_ALLOCATE: _( + "No storage could be allocated for this volume " + "request. You may be able to try another size or" + " volume type."), + EventIds.ATTACH_READONLY_VOLUME: _( + "A readonly volume must be attached as readonly."), + EventIds.IMAGE_FROM_VOLUME_OVER_QUOTA: _( + "Failed to copy volume to image as image quota has been met. Please " + "delete images or have your limit increased, then try again."), } def get_message_text(event_id): + # FIXME(ameade): In the Ocata release, this check can be removed as + # there should no longer be any event ids that do not start with the prefix + if not event_id.startswith("VOLUME_"): + event_id = "VOLUME_" + event_id + return event_id_message_map[event_id] diff --git a/cinder/scheduler/flows/create_volume.py b/cinder/scheduler/flows/create_volume.py index ae255bbf144..eeb048f535f 100644 --- a/cinder/scheduler/flows/create_volume.py +++ b/cinder/scheduler/flows/create_volume.py @@ -131,7 +131,7 @@ class ScheduleCreateVolumeTask(flow_utils.CinderTask): if isinstance(e, exception.NoValidBackend): self.message_api.create( context, - defined_messages.UNABLE_TO_ALLOCATE, + defined_messages.EventIds.UNABLE_TO_ALLOCATE, context.project_id, resource_type=resource_types.VOLUME, resource_uuid=request_spec['volume_id']) diff --git a/cinder/tests/unit/api/v3/fakes.py b/cinder/tests/unit/api/v3/fakes.py index 5b0c129e738..1d9a21a0aee 100644 --- a/cinder/tests/unit/api/v3/fakes.py +++ b/cinder/tests/unit/api/v3/fakes.py @@ -31,7 +31,7 @@ DEFAULT_AZ = "fakeaz" def fake_message(id, **kwargs): message = { 'id': id, - 'event_id': defined_messages.UNABLE_TO_ALLOCATE, + 'event_id': defined_messages.EventIds.UNABLE_TO_ALLOCATE, 'message_level': "ERROR", 'request_id': FAKE_UUID, 'updated_at': datetime.datetime(1900, 1, 1, 1, 1, 1, diff --git a/cinder/tests/unit/api/v3/stubs.py b/cinder/tests/unit/api/v3/stubs.py new file mode 100644 index 00000000000..1e77be3e8a3 --- /dev/null +++ b/cinder/tests/unit/api/v3/stubs.py @@ -0,0 +1,42 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import datetime +import iso8601 + +from cinder.message import defined_messages +from cinder.tests.unit import fake_constants as fake + + +FAKE_UUID = fake.OBJECT_ID + + +def stub_message(id, **kwargs): + message = { + 'id': id, + 'event_id': defined_messages.EventIds.UNABLE_TO_ALLOCATE, + 'message_level': "ERROR", + 'request_id': FAKE_UUID, + 'updated_at': datetime.datetime(1900, 1, 1, 1, 1, 1, + tzinfo=iso8601.iso8601.Utc()), + 'created_at': datetime.datetime(1900, 1, 1, 1, 1, 1, + tzinfo=iso8601.iso8601.Utc()), + 'expires_at': datetime.datetime(1900, 1, 1, 1, 1, 1, + tzinfo=iso8601.iso8601.Utc()), + } + + message.update(kwargs) + return message + + +def stub_message_get(self, context, message_id): + return stub_message(message_id) diff --git a/cinder/tests/unit/message/test_api.py b/cinder/tests/unit/message/test_api.py index ef7c134808f..ed13af259a6 100644 --- a/cinder/tests/unit/message/test_api.py +++ b/cinder/tests/unit/message/test_api.py @@ -53,12 +53,12 @@ class MessageApiTest(test.TestCase): 'request_id': 'fakerequestid', 'resource_type': 'fake_resource_type', 'resource_uuid': None, - 'event_id': defined_messages.UNABLE_TO_ALLOCATE, + 'event_id': defined_messages.EventIds.UNABLE_TO_ALLOCATE, 'message_level': 'ERROR', 'expires_at': expected_expires_at, } self.message_api.create(self.ctxt, - defined_messages.UNABLE_TO_ALLOCATE, + defined_messages.EventIds.UNABLE_TO_ALLOCATE, "fakeproject", resource_type="fake_resource_type") @@ -70,7 +70,7 @@ class MessageApiTest(test.TestCase): self.mock_object(self.message_api.db, 'create', mock.Mock(side_effect=Exception())) self.message_api.create(self.ctxt, - defined_messages.UNABLE_TO_ALLOCATE, + defined_messages.EventIds.UNABLE_TO_ALLOCATE, "fakeproject", "fake_resource") @@ -110,18 +110,20 @@ class MessageApiTest(test.TestCase): def create_message_for_tests(self): """Create messages to test pagination functionality""" utils.create_message( - self.ctxt, event_id=defined_messages.UNKNOWN_ERROR) + self.ctxt, event_id=defined_messages.EventIds.UNKNOWN_ERROR) utils.create_message( - self.ctxt, event_id=defined_messages.UNABLE_TO_ALLOCATE) + self.ctxt, event_id=defined_messages.EventIds.UNABLE_TO_ALLOCATE) utils.create_message( - self.ctxt, event_id=defined_messages.ATTACH_READONLY_VOLUME) + self.ctxt, + event_id=defined_messages.EventIds.ATTACH_READONLY_VOLUME) utils.create_message( - self.ctxt, event_id=defined_messages.IMAGE_FROM_VOLUME_OVER_QUOTA) + self.ctxt, + event_id=defined_messages.EventIds.IMAGE_FROM_VOLUME_OVER_QUOTA) def test_get_all_messages_with_limit(self): self.create_message_for_tests() - url = ('/v3/messages?limit=1') + url = '/v3/messages?limit=1' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -132,7 +134,7 @@ class MessageApiTest(test.TestCase): res = self.controller.index(req) self.assertEqual(1, len(res['messages'])) - url = ('/v3/messages?limit=3') + url = '/v3/messages?limit=3' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -146,7 +148,7 @@ class MessageApiTest(test.TestCase): def test_get_all_messages_with_limit_wrong_version(self): self.create_message_for_tests() - url = ('/v3/messages?limit=1') + url = '/v3/messages?limit=1' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -160,7 +162,7 @@ class MessageApiTest(test.TestCase): def test_get_all_messages_with_offset(self): self.create_message_for_tests() - url = ('/v3/messages?offset=1') + url = '/v3/messages?offset=1' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -174,7 +176,7 @@ class MessageApiTest(test.TestCase): def test_get_all_messages_with_limit_and_offset(self): self.create_message_for_tests() - url = ('/v3/messages?limit=2&offset=1') + url = '/v3/messages?limit=2&offset=1' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -188,8 +190,8 @@ class MessageApiTest(test.TestCase): def test_get_all_messages_with_filter(self): self.create_message_for_tests() - url = ('/v3/messages?' - 'event_id=%s') % defined_messages.UNKNOWN_ERROR + url = '/v3/messages?event_id=%s' % ( + defined_messages.EventIds.UNKNOWN_ERROR) req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -203,7 +205,7 @@ class MessageApiTest(test.TestCase): def test_get_all_messages_with_sort(self): self.create_message_for_tests() - url = ('/v3/messages?sort=event_id:asc') + url = '/v3/messages?sort=event_id:asc' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -213,10 +215,12 @@ class MessageApiTest(test.TestCase): res = self.controller.index(req) - expect_result = [defined_messages.UNKNOWN_ERROR, - defined_messages.UNABLE_TO_ALLOCATE, - defined_messages.IMAGE_FROM_VOLUME_OVER_QUOTA, - defined_messages.ATTACH_READONLY_VOLUME] + expect_result = [ + defined_messages.EventIds.UNKNOWN_ERROR, + defined_messages.EventIds.UNABLE_TO_ALLOCATE, + defined_messages.EventIds.IMAGE_FROM_VOLUME_OVER_QUOTA, + defined_messages.EventIds.ATTACH_READONLY_VOLUME + ] expect_result.sort() self.assertEqual(4, len(res['messages'])) @@ -233,7 +237,7 @@ class MessageApiTest(test.TestCase): self.create_message_for_tests() # first request of this test - url = ('/v3/fake/messages?limit=2') + url = '/v3/fake/messages?limit=2' req = fakes.HTTPRequest.blank(url) req.method = 'GET' req.content_type = 'application/json' @@ -253,7 +257,7 @@ class MessageApiTest(test.TestCase): # Second request in this test # Test for second page using marker (res['messages][0]['id']) # values fetched in first request with limit 2 in this test - url = ('/v3/fake/messages?limit=1&marker=%s') % ( + url = '/v3/fake/messages?limit=1&marker=%s' % ( res['messages'][0]['id']) req = fakes.HTTPRequest.blank(url) req.method = 'GET' diff --git a/cinder/tests/unit/message/test_defined_messages.py b/cinder/tests/unit/message/test_defined_messages.py new file mode 100644 index 00000000000..6d089cfd5dd --- /dev/null +++ b/cinder/tests/unit/message/test_defined_messages.py @@ -0,0 +1,46 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from oslo_config import cfg + +from cinder.message import defined_messages +from cinder import test + +CONF = cfg.CONF + + +class DefinedMessagesTest(test.TestCase): + def test_event_id_formats(self): + """Assert all cinder event ids start with VOLUME_.""" + for attr_name in dir(defined_messages.EventIds): + if not attr_name.startswith('_'): + value = getattr(defined_messages.EventIds, attr_name) + self.assertTrue(value.startswith('VOLUME_')) + + def test_unique_event_ids(self): + """Assert that no event_id is duplicated.""" + event_ids = [] + for attr_name in dir(defined_messages.EventIds): + if not attr_name.startswith('_'): + value = getattr(defined_messages.EventIds, attr_name) + event_ids.append(value) + + self.assertEqual(len(event_ids), len(set(event_ids))) + + def test_event_id_has_message(self): + for attr_name in dir(defined_messages.EventIds): + if not attr_name.startswith('_'): + value = getattr(defined_messages.EventIds, attr_name) + self.assertTrue(defined_messages.event_id_message_map.get( + value)) + + def test_event_id_missing_prefix(self): + self.assertTrue(defined_messages.get_message_text('000001')) diff --git a/cinder/tests/unit/scheduler/test_scheduler.py b/cinder/tests/unit/scheduler/test_scheduler.py index 12f86823995..058706ea0a1 100644 --- a/cinder/tests/unit/scheduler/test_scheduler.py +++ b/cinder/tests/unit/scheduler/test_scheduler.py @@ -146,7 +146,7 @@ class SchedulerManagerTestCase(test.TestCase): request_spec_obj, {}) _mock_message_create.assert_called_once_with( - self.context, defined_messages.UNABLE_TO_ALLOCATE, + self.context, defined_messages.EventIds.UNABLE_TO_ALLOCATE, self.context.project_id, resource_type='VOLUME', resource_uuid=volume.id) diff --git a/cinder/tests/unit/test_db_api.py b/cinder/tests/unit/test_db_api.py index 6fccb2d1216..b7a57048310 100644 --- a/cinder/tests/unit/test_db_api.py +++ b/cinder/tests/unit/test_db_api.py @@ -1988,6 +1988,93 @@ class DBAPIMigrateCGstoGroupsTestCase(BaseTest): self._assert_migrated(migrated, ()) +class DBAPIMigrateMessagePrefixTestCase(BaseTest): + """Tests for cinder.db.api.migrate_add_message_prefix.""" + + def setUp(self): + super(DBAPIMigrateMessagePrefixTestCase, self).setUp() + message_values = { + "project_id": "fake_project", + "event_id": "test_id", + "message_level": "ERROR", + "id": '1', + } + + db.message_create(self.ctxt, message_values) + + message_2_values = { + "project_id": "fake_project", + "event_id": "test_id", + "message_level": "ERROR", + "id": '2', + } + + db.message_create(self.ctxt, message_2_values) + + message_3_values = { + "project_id": "fake_project", + "event_id": "VOLUME_test_id", + "message_level": "ERROR", + "id": '3', + } + + db.message_create(self.ctxt, message_3_values) + + def tearDown(self): + super(DBAPIMigrateMessagePrefixTestCase, self).tearDown() + + db.message_destroy(self.ctxt, {'id': '1'}) + db.message_destroy(self.ctxt, {'id': '2'}) + db.message_destroy(self.ctxt, {'id': '3'}) + + def _assert_migrated(self, migrated, not_migrated): + for message_id in migrated: + message = db.message_get(self.ctxt, message_id) + self.assertEqual('VOLUME_test_id', message['event_id']) + + for message_id in not_migrated: + message = db.message_get(self.ctxt, message_id) + self.assertEqual('test_id', message['event_id']) + + def test_migrate(self): + + self._assert_migrated(['3'], ['1', '2']) + + # Run migration + count_all, count_hit = db.migrate_add_message_prefix(self.ctxt, 50) + # Check counted entries + self.assertEqual(2, count_all) + self.assertEqual(2, count_hit) + + self._assert_migrated(['1', '2', '3'], []) + + def test_migrate_limit_force(self): + # Run first migration + count_all, count_hit = db.migrate_add_message_prefix(self.ctxt, 1, + True) + # Check counted entries + self.assertEqual(1, count_all) + self.assertEqual(1, count_hit) + + self._assert_migrated(['1', '3'], ['2']) + + # Run second migration + count_all, count_hit = db.migrate_add_message_prefix(self.ctxt, 2, + True) + # Check counted entries + self.assertEqual(1, count_all) + self.assertEqual(1, count_hit) + + self._assert_migrated(['1', '2', '3'], []) + + # Run final migration + count_all, count_hit = db.migrate_add_message_prefix(self.ctxt, 2, + True) + # Check counted entries + self.assertEqual(0, count_all) + self.assertEqual(0, count_hit) + + class DBAPICgsnapshotTestCase(BaseTest): """Tests for cinder.db.api.cgsnapshot_*.""" diff --git a/cinder/tests/unit/test_migrations.py b/cinder/tests/unit/test_migrations.py index c6ad01da635..0ff23872327 100644 --- a/cinder/tests/unit/test_migrations.py +++ b/cinder/tests/unit/test_migrations.py @@ -114,6 +114,9 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin): # NOTE(dulek): 73 drops tables and columns we've stopped using a # release ago. 73, + # NOTE(ameade): 87 sets messages.request_id to nullable. This + # should be safe for the same reason as migration 66. + 87, ] # NOTE(dulek): We only started requiring things be additive in @@ -1063,6 +1066,16 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin): self.assertIsNotNone(specs) self.assertEqual(' True', specs.value) + def _check_087(self, engine, data): + """Test request_id column in messages is nullable.""" + self.assertTrue(engine.dialect.has_table(engine.connect(), + "messages")) + messages = db_utils.get_table(engine, 'messages') + + self.assertIsInstance(messages.c.request_id.type, + self.VARCHAR_TYPE) + self.assertTrue(messages.c.request_id.nullable) + def test_walk_versions(self): self.walk_versions(False, False) diff --git a/cinder/tests/unit/test_volume.py b/cinder/tests/unit/test_volume.py index 87e3c6c740d..a10a148fadc 100644 --- a/cinder/tests/unit/test_volume.py +++ b/cinder/tests/unit/test_volume.py @@ -2930,7 +2930,7 @@ class VolumeTestCase(base.BaseVolumeTestCase): # Assert a user message was created self.volume.message_api.create.assert_called_once_with( - self.context, defined_messages.ATTACH_READONLY_VOLUME, + self.context, defined_messages.EventIds.ATTACH_READONLY_VOLUME, self.context.project_id, resource_type=resource_types.VOLUME, resource_uuid=volume['id']) @@ -5813,7 +5813,8 @@ class CopyVolumeToImageTestCase(base.BaseVolumeTestCase): self.image_meta) # Assert a user message was created self.volume.message_api.create.assert_called_once_with( - self.context, defined_messages.IMAGE_FROM_VOLUME_OVER_QUOTA, + self.context, + defined_messages.EventIds.IMAGE_FROM_VOLUME_OVER_QUOTA, self.context.project_id, resource_type=resource_types.VOLUME, resource_uuid=volume['id']) diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index 5764bc40e5e..d385adebfd4 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -1023,7 +1023,7 @@ class VolumeManager(manager.CleanableManager, fields.VolumeAttachStatus.ERROR_ATTACHING) attachment.save() self.message_api.create( - context, defined_messages.ATTACH_READONLY_VOLUME, + context, defined_messages.EventIds.ATTACH_READONLY_VOLUME, context.project_id, resource_type=resource_types.VOLUME, resource_uuid=volume.id) raise exception.InvalidVolumeAttachMode(mode=mode, @@ -1344,7 +1344,8 @@ class VolumeManager(manager.CleanableManager, payload['message'] = six.text_type(error) if isinstance(error, exception.ImageLimitExceeded): self.message_api.create( - context, defined_messages.IMAGE_FROM_VOLUME_OVER_QUOTA, + context, + defined_messages.EventIds.IMAGE_FROM_VOLUME_OVER_QUOTA, context.project_id, resource_type=resource_types.VOLUME, resource_uuid=volume_id) diff --git a/doc/source/devref/user_messages.rst b/doc/source/devref/user_messages.rst index 044972818ff..b5da9227a1e 100644 --- a/doc/source/devref/user_messages.rst +++ b/doc/source/devref/user_messages.rst @@ -23,7 +23,7 @@ Example message generation:: self.message_api.create( context, - defined_messages.UNABLE_TO_ALLOCATE, + defined_messages.EventIds.UNABLE_TO_ALLOCATE, project_id, resource_type=resource_types.VOLUME, resource_uuid=volume_id)