diff options
| author | Craig Vyvial <cp16net@gmail.com> | 2012-05-07 14:03:04 -0500 |
|---|---|---|
| committer | Craig Vyvial <cp16net@gmail.com> | 2012-05-14 16:34:08 -0500 |
| commit | fbae8d09fdb9ad370fa827aab0f9bfe0c0c7041f (patch) | |
| tree | b84449522d27586243a9994e704ab6bc06d3d0cf /nova/volume | |
| parent | b3e2bae38177583201dd7dcdd2d9c16929724573 (diff) | |
Adding notifications for volumes
Added notifications for volumes have been added with tests.
This includes create/delete/exists events for volumes.
blueprint nova-notifications
Change-Id: I21b74974fac22c3621ccf7564dc5c0d339f8751a
Diffstat (limited to 'nova/volume')
| -rw-r--r-- | nova/volume/manager.py | 11 | ||||
| -rw-r--r-- | nova/volume/utils.py | 83 |
2 files changed, 94 insertions, 0 deletions
diff --git a/nova/volume/manager.py b/nova/volume/manager.py index 828451f7c..a471ea372 100644 --- a/nova/volume/manager.py +++ b/nova/volume/manager.py @@ -49,6 +49,7 @@ from nova.openstack.common import importutils from nova import rpc from nova import utils from nova.volume import volume_types +from nova.volume import utils as volume_utils LOG = logging.getLogger(__name__) @@ -106,6 +107,7 @@ class VolumeManager(manager.SchedulerDependentManager): """Creates and exports the volume.""" context = context.elevated() volume_ref = self.db.volume_get(context, volume_id) + self._notify_about_volume_usage(context, volume_ref, "create.start") LOG.info(_("volume %s: creating"), volume_ref['name']) self.db.volume_update(context, @@ -145,6 +147,7 @@ class VolumeManager(manager.SchedulerDependentManager): 'launched_at': now}) LOG.debug(_("volume %s: created successfully"), volume_ref['name']) self._reset_stats() + self._notify_about_volume_usage(context, volume_ref, "create.end") return volume_id def delete_volume(self, context, volume_id): @@ -157,6 +160,7 @@ class VolumeManager(manager.SchedulerDependentManager): msg = _("Volume is not local to this node") raise exception.NovaException(msg) + self._notify_about_volume_usage(context, volume_ref, "delete.start") self._reset_stats() try: LOG.debug(_("volume %s: removing export"), volume_ref['name']) @@ -177,6 +181,7 @@ class VolumeManager(manager.SchedulerDependentManager): self.db.volume_destroy(context, volume_id) LOG.debug(_("volume %s: deleted successfully"), volume_ref['name']) + self._notify_about_volume_usage(context, volume_ref, "delete.end") return True def create_snapshot(self, context, volume_id, snapshot_id): @@ -337,3 +342,9 @@ class VolumeManager(manager.SchedulerDependentManager): def notification(self, context, event): LOG.info(_("Notification {%s} received"), event) self._reset_stats() + + def _notify_about_volume_usage(self, context, volume, event_suffix, + extra_usage_info=None): + volume_utils.notify_about_volume_usage( + context, volume, event_suffix, + extra_usage_info=extra_usage_info, host=self.host) diff --git a/nova/volume/utils.py b/nova/volume/utils.py new file mode 100644 index 000000000..94f719bf3 --- /dev/null +++ b/nova/volume/utils.py @@ -0,0 +1,83 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2012 OpenStack, LLC. +# +# 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. + +"""Volume-related Utilities and helpers.""" + +from nova import flags +from nova import log as logging +from nova import utils +from nova.notifier import api as notifier_api + + +FLAGS = flags.FLAGS +LOG = logging.getLogger(__name__) + + +def notify_usage_exists(context, volume_ref, current_period=False): + """ Generates 'exists' notification for a volume for usage auditing + purposes. + + Generates usage for last completed period, unless 'current_period' + is True.""" + begin, end = utils.last_completed_audit_period() + if current_period: + audit_start = end + audit_end = utils.utcnow() + else: + audit_start = begin + audit_end = end + + extra_usage_info = dict(audit_period_beginning=str(audit_start), + audit_period_ending=str(audit_end)) + + notify_about_volume_usage( + context, volume_ref, 'exists', extra_usage_info=extra_usage_info) + + +def _usage_from_volume(context, volume_ref, **kw): + def null_safe_str(s): + return str(s) if s else '' + + usage_info = dict( + tenant_id=volume_ref['project_id'], + user_id=volume_ref['user_id'], + volume_id=volume_ref['id'], + volume_type=volume_ref['volume_type'], + display_name=volume_ref['display_name'], + launched_at=null_safe_str(volume_ref['launched_at']), + created_at=null_safe_str(volume_ref['created_at']), + status=volume_ref['status'], + snapshot_id=volume_ref['snapshot_id'], + size=volume_ref['size']) + + usage_info.update(kw) + return usage_info + + +def notify_about_volume_usage(context, volume, event_suffix, + extra_usage_info=None, host=None): + if not host: + host = FLAGS.host + + if not extra_usage_info: + extra_usage_info = {} + + usage_info = _usage_from_volume( + context, volume, **extra_usage_info) + + notifier_api.notify(context, 'volume.%s' % host, + 'volume.%s' % event_suffix, + notifier_api.INFO, usage_info) |
