Implemented metering for Cinder's snapshots
Cinder already publishes the required notifications, but Ceilometer wasn't recording them. This patch fixes that. Closes-Bug: #1316670 Change-Id: I53532d1833db2f22a803bf77e548f5d3b095a30f
This commit is contained in:
parent
21774ae8cb
commit
b27ac819fb
@ -45,7 +45,6 @@ NOTIFICATION_VOLUME_EXISTS = {
|
|||||||
u'priority': u'INFO'
|
u'priority': u'INFO'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NOTIFICATION_VOLUME_DELETE = {
|
NOTIFICATION_VOLUME_DELETE = {
|
||||||
u'_context_roles': [u'Member', u'admin'],
|
u'_context_roles': [u'Member', u'admin'],
|
||||||
u'_context_request_id': u'req-6ba8ccb4-1093-4a39-b029-adfaa3fc7ceb',
|
u'_context_request_id': u'req-6ba8ccb4-1093-4a39-b029-adfaa3fc7ceb',
|
||||||
@ -102,9 +101,39 @@ NOTIFICATION_VOLUME_RESIZE = {
|
|||||||
u'priority': u'INFO'}
|
u'priority': u'INFO'}
|
||||||
|
|
||||||
|
|
||||||
|
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'}
|
||||||
|
|
||||||
|
|
||||||
class TestNotifications(test.BaseTestCase):
|
class TestNotifications(test.BaseTestCase):
|
||||||
|
|
||||||
def _verify_common_sample(self, s, name, notification):
|
def _verify_common_sample_volume(self, s, name, notification):
|
||||||
self.assertIsNotNone(s)
|
self.assertIsNotNone(s)
|
||||||
self.assertEqual(s.name, name)
|
self.assertEqual(s.name, name)
|
||||||
self.assertEqual(notification['payload']['volume_id'], s.resource_id)
|
self.assertEqual(notification['payload']['volume_id'], s.resource_id)
|
||||||
@ -117,7 +146,8 @@ class TestNotifications(test.BaseTestCase):
|
|||||||
samples = list(v.process_notification(NOTIFICATION_VOLUME_EXISTS))
|
samples = list(v.process_notification(NOTIFICATION_VOLUME_EXISTS))
|
||||||
self.assertEqual(1, len(samples))
|
self.assertEqual(1, len(samples))
|
||||||
s = samples[0]
|
s = samples[0]
|
||||||
self._verify_common_sample(s, 'volume', NOTIFICATION_VOLUME_EXISTS)
|
self._verify_common_sample_volume(
|
||||||
|
s, 'volume', NOTIFICATION_VOLUME_EXISTS)
|
||||||
self.assertEqual(1, s.volume)
|
self.assertEqual(1, s.volume)
|
||||||
|
|
||||||
def test_volume_size_exists(self):
|
def test_volume_size_exists(self):
|
||||||
@ -125,8 +155,8 @@ class TestNotifications(test.BaseTestCase):
|
|||||||
samples = list(v.process_notification(NOTIFICATION_VOLUME_EXISTS))
|
samples = list(v.process_notification(NOTIFICATION_VOLUME_EXISTS))
|
||||||
self.assertEqual(1, len(samples))
|
self.assertEqual(1, len(samples))
|
||||||
s = samples[0]
|
s = samples[0]
|
||||||
self._verify_common_sample(s, 'volume.size',
|
self._verify_common_sample_volume(s, 'volume.size',
|
||||||
NOTIFICATION_VOLUME_EXISTS)
|
NOTIFICATION_VOLUME_EXISTS)
|
||||||
self.assertEqual(NOTIFICATION_VOLUME_EXISTS['payload']['size'],
|
self.assertEqual(NOTIFICATION_VOLUME_EXISTS['payload']['size'],
|
||||||
s.volume)
|
s.volume)
|
||||||
|
|
||||||
@ -135,7 +165,8 @@ class TestNotifications(test.BaseTestCase):
|
|||||||
samples = list(v.process_notification(NOTIFICATION_VOLUME_DELETE))
|
samples = list(v.process_notification(NOTIFICATION_VOLUME_DELETE))
|
||||||
self.assertEqual(1, len(samples))
|
self.assertEqual(1, len(samples))
|
||||||
s = samples[0]
|
s = samples[0]
|
||||||
self._verify_common_sample(s, 'volume', NOTIFICATION_VOLUME_DELETE)
|
self._verify_common_sample_volume(
|
||||||
|
s, 'volume', NOTIFICATION_VOLUME_DELETE)
|
||||||
self.assertEqual(1, s.volume)
|
self.assertEqual(1, s.volume)
|
||||||
|
|
||||||
def test_volume_size_delete(self):
|
def test_volume_size_delete(self):
|
||||||
@ -143,8 +174,8 @@ class TestNotifications(test.BaseTestCase):
|
|||||||
samples = list(v.process_notification(NOTIFICATION_VOLUME_DELETE))
|
samples = list(v.process_notification(NOTIFICATION_VOLUME_DELETE))
|
||||||
self.assertEqual(1, len(samples))
|
self.assertEqual(1, len(samples))
|
||||||
s = samples[0]
|
s = samples[0]
|
||||||
self._verify_common_sample(s, 'volume.size',
|
self._verify_common_sample_volume(s, 'volume.size',
|
||||||
NOTIFICATION_VOLUME_DELETE)
|
NOTIFICATION_VOLUME_DELETE)
|
||||||
self.assertEqual(NOTIFICATION_VOLUME_DELETE['payload']['size'],
|
self.assertEqual(NOTIFICATION_VOLUME_DELETE['payload']['size'],
|
||||||
s.volume)
|
s.volume)
|
||||||
|
|
||||||
@ -153,7 +184,8 @@ class TestNotifications(test.BaseTestCase):
|
|||||||
samples = list(v.process_notification(NOTIFICATION_VOLUME_RESIZE))
|
samples = list(v.process_notification(NOTIFICATION_VOLUME_RESIZE))
|
||||||
self.assertEqual(1, len(samples))
|
self.assertEqual(1, len(samples))
|
||||||
s = samples[0]
|
s = samples[0]
|
||||||
self._verify_common_sample(s, 'volume', NOTIFICATION_VOLUME_RESIZE)
|
self._verify_common_sample_volume(
|
||||||
|
s, 'volume', NOTIFICATION_VOLUME_RESIZE)
|
||||||
self.assertEqual(1, s.volume)
|
self.assertEqual(1, s.volume)
|
||||||
|
|
||||||
def test_volume_size_resize(self):
|
def test_volume_size_resize(self):
|
||||||
@ -161,7 +193,34 @@ class TestNotifications(test.BaseTestCase):
|
|||||||
samples = list(v.process_notification(NOTIFICATION_VOLUME_RESIZE))
|
samples = list(v.process_notification(NOTIFICATION_VOLUME_RESIZE))
|
||||||
self.assertEqual(1, len(samples))
|
self.assertEqual(1, len(samples))
|
||||||
s = samples[0]
|
s = samples[0]
|
||||||
self._verify_common_sample(s, 'volume.size',
|
self._verify_common_sample_volume(s, 'volume.size',
|
||||||
NOTIFICATION_VOLUME_RESIZE)
|
NOTIFICATION_VOLUME_RESIZE)
|
||||||
self.assertEqual(NOTIFICATION_VOLUME_RESIZE['payload']['size'],
|
self.assertEqual(NOTIFICATION_VOLUME_RESIZE['payload']['size'],
|
||||||
s.volume)
|
s.volume)
|
||||||
|
|
||||||
|
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 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)
|
||||||
|
@ -37,14 +37,7 @@ cfg.CONF.register_opts(OPTS)
|
|||||||
|
|
||||||
|
|
||||||
class _Base(plugin.NotificationBase):
|
class _Base(plugin.NotificationBase):
|
||||||
"""Convert volume notifications into Counters."""
|
"""Convert volume/snapshot notification into Counters."""
|
||||||
|
|
||||||
event_types = [
|
|
||||||
'volume.exists',
|
|
||||||
'volume.create.*',
|
|
||||||
'volume.delete.*',
|
|
||||||
'volume.resize.*',
|
|
||||||
]
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_targets(conf):
|
def get_targets(conf):
|
||||||
@ -56,7 +49,18 @@ class _Base(plugin.NotificationBase):
|
|||||||
for topic in conf.notification_topics]
|
for topic in conf.notification_topics]
|
||||||
|
|
||||||
|
|
||||||
class Volume(_Base):
|
class _VolumeBase(_Base):
|
||||||
|
"""Convert volume notifications into Counters."""
|
||||||
|
|
||||||
|
event_types = [
|
||||||
|
'volume.exists',
|
||||||
|
'volume.create.*',
|
||||||
|
'volume.delete.*',
|
||||||
|
'volume.resize.*',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Volume(_VolumeBase):
|
||||||
def process_notification(self, message):
|
def process_notification(self, message):
|
||||||
yield sample.Sample.from_notification(
|
yield sample.Sample.from_notification(
|
||||||
name='volume',
|
name='volume',
|
||||||
@ -69,7 +73,7 @@ class Volume(_Base):
|
|||||||
message=message)
|
message=message)
|
||||||
|
|
||||||
|
|
||||||
class VolumeSize(_Base):
|
class VolumeSize(_VolumeBase):
|
||||||
def process_notification(self, message):
|
def process_notification(self, message):
|
||||||
yield sample.Sample.from_notification(
|
yield sample.Sample.from_notification(
|
||||||
name='volume.size',
|
name='volume.size',
|
||||||
@ -80,3 +84,40 @@ class VolumeSize(_Base):
|
|||||||
project_id=message['payload']['tenant_id'],
|
project_id=message['payload']['tenant_id'],
|
||||||
resource_id=message['payload']['volume_id'],
|
resource_id=message['payload']['volume_id'],
|
||||||
message=message)
|
message=message)
|
||||||
|
|
||||||
|
|
||||||
|
class _SnapshotBase(_Base):
|
||||||
|
"""Convert snapshot notifications into Counters."""
|
||||||
|
|
||||||
|
event_types = [
|
||||||
|
'snapshot.exists',
|
||||||
|
'snapshot.create.*',
|
||||||
|
'snapshot.delete.*',
|
||||||
|
'snapshot.resize.*',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Snapshot(_SnapshotBase):
|
||||||
|
def process_notification(self, message):
|
||||||
|
yield sample.Sample.from_notification(
|
||||||
|
name='snapshot',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
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 SnapshotSize(_SnapshotBase):
|
||||||
|
def process_notification(self, message):
|
||||||
|
yield sample.Sample.from_notification(
|
||||||
|
name='snapshot.size',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
unit='GB',
|
||||||
|
volume=message['payload']['volume_size'],
|
||||||
|
user_id=message['payload']['user_id'],
|
||||||
|
project_id=message['payload']['tenant_id'],
|
||||||
|
resource_id=message['payload']['snapshot_id'],
|
||||||
|
message=message)
|
||||||
|
@ -176,12 +176,14 @@ image.serve Delta B image ID notification Image is
|
|||||||
Volume (Cinder)
|
Volume (Cinder)
|
||||||
===============
|
===============
|
||||||
|
|
||||||
======================== ========== ======= ======== ============ =======================================================
|
======================== ========== ======== ======== ============ =======================================================
|
||||||
Name Type Unit Resource Origin Note
|
Name Type Unit Resource Origin Note
|
||||||
======================== ========== ======= ======== ============ =======================================================
|
======================== ========== ======== ======== ============ =======================================================
|
||||||
volume Gauge volume vol ID notification Existence of volume
|
volume Gauge volume vol ID notification Existence of volume
|
||||||
volume.size Gauge GB vol ID notification Size of volume
|
volume.size Gauge GB vol ID notification Size of volume
|
||||||
======================== ========== ======= ======== ============ =======================================================
|
snapshot Gauge snapshot snap ID notification Existence of snapshot
|
||||||
|
snapshot.size Gauge GB snap ID notification Size of snapshot's volume
|
||||||
|
======================== ========== ======== ======== ============ =======================================================
|
||||||
|
|
||||||
Make sure Cinder is properly configured first: see :ref:`installing_manually`.
|
Make sure Cinder is properly configured first: see :ref:`installing_manually`.
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ ceilometer.notification =
|
|||||||
cpu_percent = ceilometer.compute.notifications.cpu:CpuPercent
|
cpu_percent = ceilometer.compute.notifications.cpu:CpuPercent
|
||||||
volume = ceilometer.volume.notifications:Volume
|
volume = ceilometer.volume.notifications:Volume
|
||||||
volume_size = ceilometer.volume.notifications:VolumeSize
|
volume_size = ceilometer.volume.notifications:VolumeSize
|
||||||
|
snapshot = ceilometer.volume.notifications:Snapshot
|
||||||
|
snapshot_size = ceilometer.volume.notifications:SnapshotSize
|
||||||
image_crud = ceilometer.image.notifications:ImageCRUD
|
image_crud = ceilometer.image.notifications:ImageCRUD
|
||||||
image = ceilometer.image.notifications:Image
|
image = ceilometer.image.notifications:Image
|
||||||
image_size = ceilometer.image.notifications:ImageSize
|
image_size = ceilometer.image.notifications:ImageSize
|
||||||
|
Loading…
Reference in New Issue
Block a user