From 2891d168f81a83eef31f768f7a6e7603acff2ea4 Mon Sep 17 00:00:00 2001 From: Lena Novokshonova Date: Mon, 27 Oct 2014 16:40:57 +0400 Subject: [PATCH] Add new notifications types for volumes/snapshots This change allows to collect and view notifications of different types - volume/snapshot.(create | delete | update).(start | end) and volume.(resize | attach | detach).(start | end). Implements: blueprint add-new-notifications-types-for-volumes-and-snapshots Change-Id: I592605bcea483d06f219a4d02d3a70a9fc0e27a3 --- ceilometer/tests/volume/test_notifications.py | 619 ++++++++++-------- ceilometer/volume/notifications.py | 46 +- setup.cfg | 2 + 3 files changed, 372 insertions(+), 295 deletions(-) diff --git a/ceilometer/tests/volume/test_notifications.py b/ceilometer/tests/volume/test_notifications.py index 7c4c91d6..4f29ec84 100644 --- a/ceilometer/tests/volume/test_notifications.py +++ b/ceilometer/tests/volume/test_notifications.py @@ -1,320 +1,369 @@ -# 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 +# 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 +# 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. +# 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 mock from oslotest import base +from ceilometer import sample from ceilometer.volume import notifications + +def fake_uuid(x): + return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12) + + +NOW = datetime.datetime.isoformat(datetime.datetime.utcnow()) + +VOLUME_META = {u'status': u'exists', + u'instance_uuid': None, + u'user_id': u'bcb7746c7a41472d88a1ffac89ba6a9b', + u'availability_zone': u'nova', + u'tenant_id': u'7ffe17a15c724e2aa79fc839540aec15', + u'created_at': u'2014-10-28 09:31:20', + u'volume_id': fake_uuid('c'), + u'volume_type': u'3a9a398b-7e3b-40da-b09e-2115ad8cd68b', + u'replication_extended_status': None, + u'host': u'volumes.example.com', + u'snapshot_id': None, + u'replication_status': u'disabled', + u'size': 1, + u'display_name': u'2'} + NOTIFICATION_VOLUME_EXISTS = { - u'_context_roles': [u'admin'], - u'_context_request_id': u'req-7ef29a5d-adeb-48a8-b104-59c05361aa27', - u'_context_quota_class': None, - u'event_type': u'volume.exists', - u'timestamp': u'2012-09-21 09:29:10.620731', - u'message_id': u'e0e6a5ad-2fc9-453c-b3fb-03fe504538dc', - u'_context_auth_token': None, - u'_context_is_admin': True, - u'_context_project_id': None, - u'_context_timestamp': u'2012-09-21T09:29:10.266928', - u'_context_read_deleted': u'no', - u'_context_user_id': None, - u'_context_remote_address': None, - u'publisher_id': u'volume.ubuntu-VirtualBox', - u'payload': {u'status': u'available', - u'audit_period_beginning': u'2012-09-20 00:00:00', - u'display_name': u'volume1', - u'tenant_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'created_at': u'2012-09-20 15:05:16', - u'snapshot_id': None, - u'volume_type': None, - u'volume_id': u'84c363b9-9854-48dc-b949-fe04263f4cf0', - u'audit_period_ending': u'2012-09-21 00:00:00', - u'user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'launched_at': u'2012-09-20 15:05:23', - u'size': 2}, - u'priority': u'INFO' -} + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.exists", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} -NOTIFICATION_VOLUME_DELETE = { - u'_context_roles': [u'Member', u'admin'], - u'_context_request_id': u'req-6ba8ccb4-1093-4a39-b029-adfaa3fc7ceb', - u'_context_quota_class': None, - u'event_type': u'volume.delete.start', - u'timestamp': u'2012-09-21 10:24:13.168630', - u'message_id': u'f6e6bc1f-fcd5-41e1-9a86-da7d024f03d9', - u'_context_auth_token': u'277c6899de8a4b3d999f3e2e4c0915ff', - u'_context_is_admin': True, - u'_context_project_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'_context_timestamp': u'2012-09-21T10:23:54.741228', - u'_context_read_deleted': u'no', - u'_context_user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'_context_remote_address': u'192.168.22.101', - u'publisher_id': u'volume.ubuntu-VirtualBox', - u'payload': {u'status': u'deleting', - u'volume_type_id': None, - u'display_name': u'abc', - u'tenant_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'created_at': u'2012-09-21 10:10:47', - u'snapshot_id': None, - u'volume_id': u'3b761164-84b4-4eb3-8fcb-1974c641d6ef', - u'user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'launched_at': u'2012-09-21 10:10:50', - u'size': 3}, - u'priority': u'INFO'} +NOTIFICATION_VOLUME_CREATE_START = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.create.start", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} +NOTIFICATION_VOLUME_CREATE_END = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.create.end", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} -NOTIFICATION_VOLUME_ATTACH = { - u'_context_roles': [u'Member', u'admin'], - u'_context_request_id': u'req-6ba8ccb4-1093-4a39-b029-adfaa3fc7ceb', - u'_context_quota_class': None, - u'event_type': u'volume.attach.end', - u'timestamp': u'2012-09-21 10:24:13.168630', - u'message_id': u'c994ae8d-d068-4101-bd06-1048877c844a', - u'_context_auth_token': u'277c6899de8a4b3d999f3e2e4c0915ff', - u'_context_is_admin': True, - u'_context_project_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'_context_timestamp': u'2012-09-21T10:02:27.134211', - u'_context_read_deleted': u'no', - u'_context_user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'_context_remote_address': u'192.168.22.101', - u'publisher_id': u'volume.ubuntu-VirtualBox', - u'payload': {u'status': u'in-use', - u'volume_type_id': None, - u'display_name': u'abc', - u'tenant_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'created_at': u'2012-09-21 10:10:47', - u'snapshot_id': None, - u'volume_id': u'3b761164-84b4-4eb3-8fcb-1974c641d6ef', - u'user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'launched_at': u'2012-09-21 10:10:50', - u'size': 3}, - u'priority': u'INFO'} +NOTIFICATION_VOLUME_DELETE_START = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.delete.start", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} +NOTIFICATION_VOLUME_DELETE_END = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.delete.end", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} -NOTIFICATION_VOLUME_DETACH = { - u'_context_roles': [u'Member', u'admin'], - u'_context_request_id': u'req-6ba8ccb4-1093-4a39-b029-adfaa3fc7ceb', - u'_context_quota_class': None, - u'event_type': u'volume.detach.end', - u'timestamp': u'2012-09-21 10:24:13.168630', - u'message_id': u'c994ae8d-d068-4101-bd06-1048877c844a', - u'_context_auth_token': u'277c6899de8a4b3d999f3e2e4c0915ff', - u'_context_is_admin': True, - u'_context_project_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'_context_timestamp': u'2012-09-21T10:02:27.134211', - u'_context_read_deleted': u'no', - u'_context_user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'_context_remote_address': u'192.168.22.101', - u'publisher_id': u'volume.ubuntu-VirtualBox', - u'payload': {u'status': u'available', - u'volume_type_id': None, - u'display_name': u'abc', - u'tenant_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'created_at': u'2012-09-21 10:10:47', - u'snapshot_id': None, - u'volume_id': u'3b761164-84b4-4eb3-8fcb-1974c641d6ef', - u'user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'launched_at': u'2012-09-21 10:10:50', - u'size': 3}, - u'priority': u'INFO'} +NOTIFICATION_VOLUME_RESIZE_START = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.resize.start", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} +NOTIFICATION_VOLUME_RESIZE_END = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.resize.end", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} -NOTIFICATION_VOLUME_RESIZE = { - u'_context_roles': [u'Member', u'admin'], - u'_context_request_id': u'req-6ba8ccb4-1093-4a39-b029-adfaa3fc7ceb', - u'_context_quota_class': None, - u'event_type': u'volume.resize.end', - u'timestamp': u'2012-09-21 10:24:13.168630', - u'message_id': u'b5814258-3425-4eb7-b6b7-bf4811203e58', - u'_context_auth_token': u'277c6899de8a4b3d999f3e2e4c0915ff', - u'_context_is_admin': True, - u'_context_project_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'_context_timestamp': u'2012-09-21T10:02:27.134211', - u'_context_read_deleted': u'no', - u'_context_user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'_context_remote_address': u'192.168.22.101', - u'publisher_id': u'volume.ubuntu-VirtualBox', - u'payload': {u'status': u'extending', - u'volume_type_id': None, - u'display_name': u'abc', - u'tenant_id': u'6c97f1ecf17047eab696786d56a0bff5', - u'created_at': u'2012-09-21 10:10:47', - u'snapshot_id': None, - u'volume_id': u'3b761164-84b4-4eb3-8fcb-1974c641d6ef', - u'user_id': u'4d2fa4b76a4a4ecab8c468c8dea42f89', - u'launched_at': u'2012-09-21 10:10:50', - u'size': 3}, - u'priority': u'INFO'} +NOTIFICATION_VOLUME_ATTACH_START = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.attach.start", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} +NOTIFICATION_VOLUME_ATTACH_END = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.attach.end", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} + +NOTIFICATION_VOLUME_DETACH_START = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.detach.start", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} + +NOTIFICATION_VOLUME_DETACH_END = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.detach.end", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} + +NOTIFICATION_VOLUME_UPDATE_START = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.update.start", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} + +NOTIFICATION_VOLUME_UPDATE_END = { + "message_id": "0c65cb9c-018c-11e2-bc91-5453ed1bbb5f", + "publisher_id": "volumes.example.com", + "event_type": "volume.update.end", + "priority": "info", + "payload": VOLUME_META, + "timestamp": NOW} + +SNAPSHOT_META = {u'status': u'creating', + u'user_id': u'bcb7746c7a41472d88a1ffac89ba6a9b', + u'availability_zone': u'nova', + u'deleted': u'', + u'tenant_id': u'7ffe17a15c724e2aa79fc839540aec15', + u'created_at': u'2014-10-28 09:49:07', + u'snapshot_id': fake_uuid('c'), + u'volume_size': 1, + u'volume_id': u'2925bb3b-2b51-496a-bb6e-01a20e950e07', + u'display_name': u'11'} NOTIFICATION_SNAPSHOT_EXISTS = { - u'_context_roles': [u'admin'], - u'_context_request_id': u'req-7ef29a5d-adeb-48a8-b104-59c05361aa27', - u'_context_quota_class': None, - u'event_type': u'snapshot.exists', - u'timestamp': u'2012-09-21 09:29:10.620731', - u'message_id': u'e0e6a5ad-2fc9-453c-b3fb-03fe504538dc', - u'_context_auth_token': None, - u'_context_is_admin': True, - u'_context_project_id': None, - u'_context_timestamp': u'2012-09-21T09:29:10.266928', - u'_context_read_deleted': u'no', - u'_context_user_id': None, - u'_context_remote_address': None, - u'publisher_id': u'volume.ubuntu-VirtualBox', - u"payload": {u"audit_period_beginning": u"2014-05-06 11:00:00", - u"audit_period_ending": u"2014-05-06 12:00:00", - u"availability_zone": u"left", - u"created_at": u"2014-05-06 09:33:43", - u"deleted": u"", - u"display_name": "lil snapshot", - u"snapshot_id": u"dd163129-9476-4cf5-9311-dd425324d8d8", - u"status": u"available", - u"tenant_id": u"compliance", - u"user_id": u"e0271f64847b49429bb304c775c7427a", - u"volume_id": u"b96e026e-c9bf-4418-8d6f-4ba493bbb7d6", - u"volume_size": 3}, - u'priority': u'INFO'} + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.exists", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} + +NOTIFICATION_SNAPSHOT_CREATE_START = { + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.create.start", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} + +NOTIFICATION_SNAPSHOT_CREATE_END = { + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.create.end", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} + +NOTIFICATION_SNAPSHOT_DELETE_START = { + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.delete.start", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} + +NOTIFICATION_SNAPSHOT_DELETE_END = { + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.delete.end", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} + +NOTIFICATION_SNAPSHOT_UPDATE_START = { + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.update.start", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} + +NOTIFICATION_SNAPSHOT_UPDATE_END = { + "message_id": "1d2944f9-f8e9-4b2b-8df1-465f759a63e8", + "publisher_id": "snapshots.example.com", + "event_type": "snapshot.update.end", + "priority": "info", + "payload": SNAPSHOT_META, + "timestamp": NOW} class TestNotifications(base.BaseTestCase): - def _verify_common_sample_volume(self, s, name, notification): - self.assertIsNotNone(s) - self.assertEqual(s.name, name) - self.assertEqual(notification['payload']['volume_id'], s.resource_id) - self.assertEqual(notification['timestamp'], s.timestamp) - metadata = s.resource_metadata - self.assertEqual(notification['publisher_id'], metadata.get('host')) + def setUp(self): + super(TestNotifications, self).setUp() + self.host = None + self.handler_crud = None + self.handler = None + self.handler_size = None + self.name = None + self.name_size = None + self.size = None - def test_volume_exists(self): - v = notifications.Volume(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_EXISTS)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume( - s, 'volume', NOTIFICATION_VOLUME_EXISTS) - self.assertEqual(1, s.volume) + def _verify_common_counter(self, c, name, volume): + self.assertIsNotNone(c) + self.assertEqual(name, c.name) + self.assertEqual(fake_uuid('c'), c.resource_id) + self.assertEqual(NOW, c.timestamp) + self.assertEqual(volume, c.volume) + metadata = c.resource_metadata + self.assertEqual(self.host, metadata.get('host')) - def test_volume_size_exists(self): - v = notifications.VolumeSize(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_EXISTS)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume(s, 'volume.size', - NOTIFICATION_VOLUME_EXISTS) - self.assertEqual(NOTIFICATION_VOLUME_EXISTS['payload']['size'], - s.volume) + def _check_crud(self, notification_type, notification_name): + counters = list(self.handler_crud.process_notification( + notification_type)) + self.assertEqual(1, len(counters)) + notification = counters[0] + self._verify_common_counter( + notification, notification_name, 1) + self.assertEqual(sample.TYPE_DELTA, notification.type) - def test_volume_delete(self): - v = notifications.Volume(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_DELETE)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume( - s, 'volume', NOTIFICATION_VOLUME_DELETE) - self.assertEqual(1, s.volume) + def _check(self, notification_type): + counters = list(self.handler.process_notification(notification_type)) + self.assertEqual(1, len(counters)) + notification = counters[0] + self._verify_common_counter(notification, self.name, 1) + self.assertEqual(sample.TYPE_GAUGE, notification.type) - def test_volume_size_delete(self): - v = notifications.VolumeSize(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_DELETE)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume(s, 'volume.size', - NOTIFICATION_VOLUME_DELETE) - self.assertEqual(NOTIFICATION_VOLUME_DELETE['payload']['size'], - s.volume) + def _check_size(self, notification_type): + counters = list(self.handler_size.process_notification( + notification_type)) + self.assertEqual(1, len(counters)) + notification = counters[0] + self._verify_common_counter( + notification, self.name_size, self.size) + self.assertEqual(sample.TYPE_GAUGE, notification.type) - def test_volume_attach(self): - v = notifications.Volume(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_ATTACH)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume( - s, 'volume', NOTIFICATION_VOLUME_ATTACH) - self.assertEqual(1, s.volume) - def test_volume_size_attach(self): - v = notifications.VolumeSize(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_ATTACH)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume(s, 'volume.size', - NOTIFICATION_VOLUME_ATTACH) - self.assertEqual(NOTIFICATION_VOLUME_ATTACH['payload']['size'], - s.volume) +class TestVolumeNotifications(TestNotifications): - def test_volume_detach(self): - v = notifications.Volume(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_DETACH)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume( - s, 'volume', NOTIFICATION_VOLUME_ATTACH) - self.assertEqual(1, s.volume) + def setUp(self): + super(TestVolumeNotifications, self).setUp() + self.host = 'volumes.example.com' + self.handler_crud = notifications.VolumeCRUD(mock.Mock()) + self.handler = notifications.Volume(mock.Mock()) + self.handler_size = notifications.VolumeSize(mock.Mock()) + self.name = 'volume' + self.name_size = 'volume.size' + self.size = VOLUME_META['size'] - def test_volume_size_detach(self): - v = notifications.VolumeSize(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_DETACH)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume(s, 'volume.size', - NOTIFICATION_VOLUME_DETACH) - self.assertEqual(NOTIFICATION_VOLUME_DETACH['payload']['size'], - s.volume) + def test_volume_notifications(self): + self._check_crud( + NOTIFICATION_VOLUME_EXISTS, 'volume.exists') + self._check_crud( + NOTIFICATION_VOLUME_CREATE_START, 'volume.create.start') + self._check_crud( + NOTIFICATION_VOLUME_CREATE_END, 'volume.create.end') + self._check_crud( + NOTIFICATION_VOLUME_DELETE_START, 'volume.delete.start') + self._check_crud( + NOTIFICATION_VOLUME_DELETE_END, 'volume.delete.end') + self._check_crud( + NOTIFICATION_VOLUME_RESIZE_START, 'volume.resize.start') + self._check_crud( + NOTIFICATION_VOLUME_RESIZE_END, 'volume.resize.end') + self._check_crud( + NOTIFICATION_VOLUME_ATTACH_START, 'volume.attach.start') + self._check_crud( + NOTIFICATION_VOLUME_ATTACH_END, 'volume.attach.end') + self._check_crud( + NOTIFICATION_VOLUME_DETACH_START, 'volume.detach.start') + self._check_crud( + NOTIFICATION_VOLUME_DETACH_END, 'volume.detach.end') + self._check_crud( + NOTIFICATION_VOLUME_UPDATE_START, 'volume.update.start') + self._check_crud( + NOTIFICATION_VOLUME_UPDATE_END, 'volume.update.end') + self._check(NOTIFICATION_VOLUME_EXISTS) + self._check(NOTIFICATION_VOLUME_CREATE_START) + self._check(NOTIFICATION_VOLUME_CREATE_END) + self._check(NOTIFICATION_VOLUME_DELETE_START) + self._check(NOTIFICATION_VOLUME_DELETE_END) + self._check(NOTIFICATION_VOLUME_RESIZE_START) + self._check(NOTIFICATION_VOLUME_RESIZE_END) + self._check(NOTIFICATION_VOLUME_ATTACH_START) + self._check(NOTIFICATION_VOLUME_ATTACH_END) + self._check(NOTIFICATION_VOLUME_DETACH_START) + self._check(NOTIFICATION_VOLUME_DETACH_END) + self._check(NOTIFICATION_VOLUME_UPDATE_START) + self._check(NOTIFICATION_VOLUME_UPDATE_END) + self._check_size(NOTIFICATION_VOLUME_EXISTS) + self._check_size(NOTIFICATION_VOLUME_CREATE_START) + self._check_size(NOTIFICATION_VOLUME_CREATE_END) + self._check_size(NOTIFICATION_VOLUME_DELETE_START) + self._check_size(NOTIFICATION_VOLUME_DELETE_END) + self._check_size(NOTIFICATION_VOLUME_RESIZE_START) + self._check_size(NOTIFICATION_VOLUME_RESIZE_END) + self._check_size(NOTIFICATION_VOLUME_ATTACH_START) + self._check_size(NOTIFICATION_VOLUME_ATTACH_END) + self._check_size(NOTIFICATION_VOLUME_DETACH_START) + self._check_size(NOTIFICATION_VOLUME_DETACH_END) + self._check_size(NOTIFICATION_VOLUME_UPDATE_START) + self._check_size(NOTIFICATION_VOLUME_UPDATE_END) - def test_volume_resize(self): - v = notifications.Volume(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_RESIZE)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume( - s, 'volume', NOTIFICATION_VOLUME_RESIZE) - self.assertEqual(1, s.volume) - def test_volume_size_resize(self): - v = notifications.VolumeSize(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_VOLUME_RESIZE)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_volume(s, 'volume.size', - NOTIFICATION_VOLUME_RESIZE) - self.assertEqual(NOTIFICATION_VOLUME_RESIZE['payload']['size'], - s.volume) +class TestSnapshotNotifications(TestNotifications): - def _verify_common_sample_snapshot(self, s, name, notification): - self.assertIsNotNone(s) - self.assertEqual(name, s.name) - self.assertEqual(notification['payload']['snapshot_id'], s.resource_id) - self.assertEqual(notification['timestamp'], s.timestamp) - metadata = s.resource_metadata - self.assertEqual(notification['publisher_id'], metadata.get('host')) + def setUp(self): + super(TestSnapshotNotifications, self).setUp() + self.host = 'snapshots.example.com' + self.handler_crud = notifications.SnapshotCRUD(mock.Mock()) + self.handler = notifications.Snapshot(mock.Mock()) + self.handler_size = notifications.SnapshotSize(mock.Mock()) + self.name = 'snapshot' + self.name_size = 'snapshot.size' + self.size = SNAPSHOT_META['volume_size'] - def test_snapshot_exists(self): - v = notifications.Snapshot(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_SNAPSHOT_EXISTS)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_snapshot(s, 'snapshot', - NOTIFICATION_SNAPSHOT_EXISTS) - self.assertEqual(1, s.volume) - - def test_snapshot_size_exists(self): - v = notifications.SnapshotSize(mock.Mock()) - samples = list(v.process_notification(NOTIFICATION_SNAPSHOT_EXISTS)) - self.assertEqual(1, len(samples)) - s = samples[0] - self._verify_common_sample_snapshot(s, 'snapshot.size', - NOTIFICATION_SNAPSHOT_EXISTS) - volume_size = NOTIFICATION_SNAPSHOT_EXISTS['payload']['volume_size'] - self.assertEqual(volume_size, s.volume) + def test_snapshot_notifications(self): + self._check_crud( + NOTIFICATION_SNAPSHOT_EXISTS, 'snapshot.exists') + self._check_crud( + NOTIFICATION_SNAPSHOT_CREATE_START, 'snapshot.create.start') + self._check_crud( + NOTIFICATION_SNAPSHOT_CREATE_END, 'snapshot.create.end') + self._check_crud( + NOTIFICATION_SNAPSHOT_DELETE_START, 'snapshot.delete.start') + self._check_crud( + NOTIFICATION_SNAPSHOT_DELETE_END, 'snapshot.delete.end') + self._check_crud( + NOTIFICATION_SNAPSHOT_UPDATE_START, 'snapshot.update.start') + self._check_crud( + NOTIFICATION_SNAPSHOT_UPDATE_END, 'snapshot.update.end') + self._check(NOTIFICATION_SNAPSHOT_EXISTS) + self._check(NOTIFICATION_SNAPSHOT_CREATE_START) + self._check(NOTIFICATION_SNAPSHOT_CREATE_END) + self._check(NOTIFICATION_SNAPSHOT_DELETE_START) + self._check(NOTIFICATION_SNAPSHOT_DELETE_END) + self._check(NOTIFICATION_SNAPSHOT_UPDATE_START) + self._check(NOTIFICATION_SNAPSHOT_UPDATE_END) + self._check_size(NOTIFICATION_SNAPSHOT_EXISTS) + self._check_size(NOTIFICATION_SNAPSHOT_CREATE_START) + self._check_size(NOTIFICATION_SNAPSHOT_CREATE_END) + self._check_size(NOTIFICATION_SNAPSHOT_DELETE_START) + self._check_size(NOTIFICATION_SNAPSHOT_DELETE_END) + self._check_size(NOTIFICATION_SNAPSHOT_UPDATE_START) + self._check_size(NOTIFICATION_SNAPSHOT_UPDATE_END) \ No newline at end of file diff --git a/ceilometer/volume/notifications.py b/ceilometer/volume/notifications.py index baee3e23..e9106bcb 100644 --- a/ceilometer/volume/notifications.py +++ b/ceilometer/volume/notifications.py @@ -24,7 +24,6 @@ import oslo.messaging from ceilometer import plugin from ceilometer import sample - OPTS = [ cfg.StrOpt('cinder_control_exchange', default='cinder', @@ -35,7 +34,7 @@ OPTS = [ cfg.CONF.register_opts(OPTS) -class _Base(plugin.NotificationBase): +class VolumeBase(plugin.NotificationBase): """Convert volume/snapshot notification into Counters.""" @staticmethod @@ -50,7 +49,7 @@ class _Base(plugin.NotificationBase): for topic in conf.notification_topics] -class _VolumeBase(_Base): +class VolumeCRUDBase(VolumeBase): """Convert volume notifications into Counters.""" event_types = [ @@ -60,10 +59,24 @@ class _VolumeBase(_Base): 'volume.resize.*', 'volume.attach.*', 'volume.detach.*', + 'volume.update.*' ] -class Volume(_VolumeBase): +class VolumeCRUD(VolumeCRUDBase): + def process_notification(self, message): + yield sample.Sample.from_notification( + name=message['event_type'], + type=sample.TYPE_DELTA, + unit='volume', + volume=1, + user_id=message['payload']['user_id'], + project_id=message['payload']['tenant_id'], + resource_id=message['payload']['volume_id'], + message=message) + + +class Volume(VolumeCRUDBase): def process_notification(self, message): yield sample.Sample.from_notification( name='volume', @@ -76,7 +89,7 @@ class Volume(_VolumeBase): message=message) -class VolumeSize(_VolumeBase): +class VolumeSize(VolumeCRUDBase): def process_notification(self, message): yield sample.Sample.from_notification( name='volume.size', @@ -89,18 +102,31 @@ class VolumeSize(_VolumeBase): message=message) -class _SnapshotBase(_Base): +class SnapshotCRUDBase(VolumeBase): """Convert snapshot notifications into Counters.""" event_types = [ 'snapshot.exists', 'snapshot.create.*', 'snapshot.delete.*', - 'snapshot.resize.*', + 'snapshot.update.*' ] -class Snapshot(_SnapshotBase): +class SnapshotCRUD(SnapshotCRUDBase): + def process_notification(self, message): + yield sample.Sample.from_notification( + name=message['event_type'], + type=sample.TYPE_DELTA, + unit='snapshot', + volume=1, + user_id=message['payload']['user_id'], + project_id=message['payload']['tenant_id'], + resource_id=message['payload']['snapshot_id'], + message=message) + + +class Snapshot(SnapshotCRUDBase): def process_notification(self, message): yield sample.Sample.from_notification( name='snapshot', @@ -113,7 +139,7 @@ class Snapshot(_SnapshotBase): message=message) -class SnapshotSize(_SnapshotBase): +class SnapshotSize(SnapshotCRUDBase): def process_notification(self, message): yield sample.Sample.from_notification( name='snapshot.size', @@ -123,4 +149,4 @@ class SnapshotSize(_SnapshotBase): user_id=message['payload']['user_id'], project_id=message['payload']['tenant_id'], resource_id=message['payload']['snapshot_id'], - message=message) + message=message) \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index aa68151a..7eeb085e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -49,8 +49,10 @@ ceilometer.notification = cpu_percent = ceilometer.compute.notifications.cpu:CpuPercent volume = ceilometer.volume.notifications:Volume volume_size = ceilometer.volume.notifications:VolumeSize + volume_crud = ceilometer.volume.notifications:VolumeCRUD snapshot = ceilometer.volume.notifications:Snapshot snapshot_size = ceilometer.volume.notifications:SnapshotSize + snapshot_crud = ceilometer.volume.notifications:SnapshotCRUD authenticate = ceilometer.identity.notifications:Authenticate user = ceilometer.identity.notifications:User group = ceilometer.identity.notifications:Group