Notification with volume and snapshot metadata
Now notify message to ceilometer do not contain volume metadata/glance_metadata and snapshot metadata, which are useful to bill and enrich resource information in ceilometer. This feature will add the metadata/glance_metadata of volume and metadata of snapshot to notification usage info. Change-Id: I04097be9f2da1d6bc45a2d5770bcd543a3f41887 Implements: blueprint notification-with-volume-and-snapshot-metadata
This commit is contained in:
parent
b6681fb3fb
commit
7d63c25c70
|
@ -525,6 +525,7 @@ class VolumeTestCase(BaseVolumeTestCase):
|
|||
'replication_status': 'disabled',
|
||||
'replication_extended_status': None,
|
||||
'replication_driver_data': None,
|
||||
'metadata': [],
|
||||
}
|
||||
self.assertDictMatch(expected, msg['payload'])
|
||||
msg = fake_notifier.NOTIFICATIONS[1]
|
||||
|
@ -2823,7 +2824,8 @@ class VolumeTestCase(BaseVolumeTestCase):
|
|||
'user_id': 'fake',
|
||||
'volume_id': volume['id'],
|
||||
'volume_size': 1,
|
||||
'availability_zone': 'nova'
|
||||
'availability_zone': 'nova',
|
||||
'metadata': '',
|
||||
}
|
||||
self.assertDictMatch(expected, msg['payload'])
|
||||
msg = fake_notifier.NOTIFICATIONS[3]
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
|
||||
"""Tests For miscellaneous util methods used with volume."""
|
||||
|
||||
|
||||
import datetime
|
||||
import mock
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
@ -42,7 +45,8 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
mock.sentinel.volume,
|
||||
'test_suffix')
|
||||
self.assertIsNone(output)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.volume)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.context,
|
||||
mock.sentinel.volume)
|
||||
mock_rpc.get_notifier.assert_called_once_with('volume', 'host1')
|
||||
mock_rpc.get_notifier.return_value.info.assert_called_once_with(
|
||||
mock.sentinel.context,
|
||||
|
@ -62,7 +66,8 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
extra_usage_info={'a': 'b', 'c': 'd'},
|
||||
host='host2')
|
||||
self.assertIsNone(output)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.volume, a='b', c='d')
|
||||
mock_usage.assert_called_once_with(mock.sentinel.context,
|
||||
mock.sentinel.volume, a='b', c='d')
|
||||
mock_rpc.get_notifier.assert_called_once_with('volume', 'host2')
|
||||
mock_rpc.get_notifier.return_value.info.assert_called_once_with(
|
||||
mock.sentinel.context,
|
||||
|
@ -80,7 +85,8 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
mock.sentinel.volume,
|
||||
'test_suffix')
|
||||
self.assertIsNone(output)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.volume)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.context,
|
||||
mock.sentinel.volume)
|
||||
mock_rpc.get_notifier.assert_called_once_with('replication', 'host1')
|
||||
mock_rpc.get_notifier.return_value.info.assert_called_once_with(
|
||||
mock.sentinel.context,
|
||||
|
@ -100,7 +106,8 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
extra_usage_info={'a': 'b', 'c': 'd'},
|
||||
host='host2')
|
||||
self.assertIsNone(output)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.volume,
|
||||
mock_usage.assert_called_once_with(mock.sentinel.context,
|
||||
mock.sentinel.volume,
|
||||
a='b', c='d')
|
||||
mock_rpc.get_notifier.assert_called_once_with('replication', 'host2')
|
||||
mock_rpc.get_notifier.return_value.info.assert_called_once_with(
|
||||
|
@ -119,7 +126,8 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
mock.sentinel.volume,
|
||||
'test_suffix')
|
||||
self.assertIsNone(output)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.volume)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.context,
|
||||
mock.sentinel.volume)
|
||||
mock_rpc.get_notifier.assert_called_once_with('replication', 'host1')
|
||||
mock_rpc.get_notifier.return_value.error.assert_called_once_with(
|
||||
mock.sentinel.context,
|
||||
|
@ -139,7 +147,8 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
extra_error_info={'a': 'b', 'c': 'd'},
|
||||
host='host2')
|
||||
self.assertIsNone(output)
|
||||
mock_usage.assert_called_once_with(mock.sentinel.volume,
|
||||
mock_usage.assert_called_once_with(mock.sentinel.context,
|
||||
mock.sentinel.volume,
|
||||
a='b', c='d')
|
||||
mock_rpc.get_notifier.assert_called_once_with('replication', 'host2')
|
||||
mock_rpc.get_notifier.return_value.error.assert_called_once_with(
|
||||
|
@ -198,6 +207,7 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
'created_at': '2014-12-11T10:10:00',
|
||||
'status': 'pause',
|
||||
'deleted': '',
|
||||
'metadata': {'fake_snap_meta_key': 'fake_snap_meta_value'},
|
||||
}
|
||||
usage_info = volume_utils._usage_from_snapshot(raw_snapshot)
|
||||
expected_snapshot = {
|
||||
|
@ -211,9 +221,55 @@ class NotifyUsageTestCase(test.TestCase):
|
|||
'created_at': '2014-12-11T10:10:00',
|
||||
'status': 'pause',
|
||||
'deleted': '',
|
||||
'metadata': "{'fake_snap_meta_key': 'fake_snap_meta_value'}",
|
||||
}
|
||||
self.assertEqual(expected_snapshot, usage_info)
|
||||
|
||||
@mock.patch('cinder.db.volume_glance_metadata_get')
|
||||
def test_usage_from_volume(self, mock_image_metadata):
|
||||
mock_image_metadata.return_value = {'image_id': 'fake_image_id'}
|
||||
raw_volume = {
|
||||
'project_id': '12b0330ec2584a',
|
||||
'user_id': '158cba1b8c2bb6008e',
|
||||
'host': 'fake_host',
|
||||
'availability_zone': 'nova',
|
||||
'volume_type_id': 'fake_volume_type_id',
|
||||
'id': 'fake_volume_id',
|
||||
'size': 1,
|
||||
'display_name': 'test_volume',
|
||||
'created_at': datetime.datetime(2015, 1, 1, 1, 1, 1),
|
||||
'launched_at': datetime.datetime(2015, 1, 1, 1, 1, 1),
|
||||
'snapshot_id': None,
|
||||
'replication_status': None,
|
||||
'replication_extended_status': None,
|
||||
'replication_driver_data': None,
|
||||
'status': 'available',
|
||||
'volume_metadata': {'fake_metadata_key': 'fake_metadata_value'},
|
||||
}
|
||||
usage_info = volume_utils._usage_from_volume(
|
||||
mock.sentinel.context,
|
||||
raw_volume)
|
||||
expected_volume = {
|
||||
'tenant_id': '12b0330ec2584a',
|
||||
'user_id': '158cba1b8c2bb6008e',
|
||||
'host': 'fake_host',
|
||||
'availability_zone': 'nova',
|
||||
'volume_type': 'fake_volume_type_id',
|
||||
'volume_id': 'fake_volume_id',
|
||||
'size': 1,
|
||||
'display_name': 'test_volume',
|
||||
'created_at': '2015-01-01T01:01:01',
|
||||
'launched_at': '2015-01-01T01:01:01',
|
||||
'snapshot_id': None,
|
||||
'replication_status': None,
|
||||
'replication_extended_status': None,
|
||||
'replication_driver_data': None,
|
||||
'status': 'available',
|
||||
'metadata': {'fake_metadata_key': 'fake_metadata_value'},
|
||||
'glance_metadata': {'image_id': 'fake_image_id'},
|
||||
}
|
||||
self.assertEqual(expected_volume, usage_info)
|
||||
|
||||
@mock.patch('cinder.volume.utils._usage_from_consistencygroup')
|
||||
@mock.patch('cinder.volume.utils.CONF')
|
||||
@mock.patch('cinder.volume.utils.rpc')
|
||||
|
|
|
@ -26,6 +26,7 @@ from oslo_utils import timeutils
|
|||
from oslo_utils import units
|
||||
|
||||
from cinder.brick.local_dev import lvm as brick_lvm
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
from cinder.i18n import _LI, _LW
|
||||
from cinder import rpc
|
||||
|
@ -42,7 +43,7 @@ def null_safe_str(s):
|
|||
return str(s) if s else ''
|
||||
|
||||
|
||||
def _usage_from_volume(volume_ref, **kw):
|
||||
def _usage_from_volume(context, volume_ref, **kw):
|
||||
now = timeutils.utcnow()
|
||||
launched_at = volume_ref['launched_at'] or now
|
||||
created_at = volume_ref['created_at'] or now
|
||||
|
@ -61,9 +62,18 @@ def _usage_from_volume(volume_ref, **kw):
|
|||
size=volume_ref['size'],
|
||||
replication_status=volume_ref['replication_status'],
|
||||
replication_extended_status=volume_ref['replication_extended_status'],
|
||||
replication_driver_data=volume_ref['replication_driver_data'],)
|
||||
replication_driver_data=volume_ref['replication_driver_data'],
|
||||
metadata=volume_ref.get('volume_metadata'),)
|
||||
|
||||
usage_info.update(kw)
|
||||
try:
|
||||
glance_meta = db.volume_glance_metadata_get(context, volume_ref['id'])
|
||||
if glance_meta:
|
||||
usage_info['glance_metadata'] = glance_meta
|
||||
except exception.GlanceMetadataNotFound:
|
||||
pass
|
||||
except exception.VolumeNotFound:
|
||||
LOG.debug("Can not find volume %s at notify usage", volume_ref['id'])
|
||||
return usage_info
|
||||
|
||||
|
||||
|
@ -94,7 +104,7 @@ def notify_about_volume_usage(context, volume, event_suffix,
|
|||
if not extra_usage_info:
|
||||
extra_usage_info = {}
|
||||
|
||||
usage_info = _usage_from_volume(volume, **extra_usage_info)
|
||||
usage_info = _usage_from_volume(context, volume, **extra_usage_info)
|
||||
|
||||
rpc.get_notifier("volume", host).info(context, 'volume.%s' % event_suffix,
|
||||
usage_info)
|
||||
|
@ -126,7 +136,8 @@ def _usage_from_snapshot(snapshot_ref, **extra_usage_info):
|
|||
'display_name': snapshot_ref['display_name'],
|
||||
'created_at': str(snapshot_ref['created_at']),
|
||||
'status': snapshot_ref['status'],
|
||||
'deleted': null_safe_str(snapshot_ref['deleted'])
|
||||
'deleted': null_safe_str(snapshot_ref['deleted']),
|
||||
'metadata': null_safe_str(snapshot_ref.get('metadata')),
|
||||
}
|
||||
|
||||
usage_info.update(extra_usage_info)
|
||||
|
@ -156,7 +167,7 @@ def notify_about_replication_usage(context, volume, suffix,
|
|||
if not extra_usage_info:
|
||||
extra_usage_info = {}
|
||||
|
||||
usage_info = _usage_from_volume(volume,
|
||||
usage_info = _usage_from_volume(context, volume,
|
||||
**extra_usage_info)
|
||||
|
||||
rpc.get_notifier('replication', host).info(context,
|
||||
|
@ -172,7 +183,7 @@ def notify_about_replication_error(context, volume, suffix,
|
|||
if not extra_error_info:
|
||||
extra_error_info = {}
|
||||
|
||||
usage_info = _usage_from_volume(volume,
|
||||
usage_info = _usage_from_volume(context, volume,
|
||||
**extra_error_info)
|
||||
|
||||
rpc.get_notifier('replication', host).error(context,
|
||||
|
|
Loading…
Reference in New Issue