Notify the transfer volume action in cinder
Now when we transfer a volume, there is not corresponding action notification that is sent to ceilometer. Include the actions of create, accept and delete. The bp that this patch implements, proposes adding those action to enrich the notification in cinder. Notify is added in Create, Accept, and Delete actions. Change-Id: I9d71c55d103cc501f60585b64902d364af21d4d9 Implements: blueprint notify-the-transfer-volume-action-in-cinder
This commit is contained in:
parent
2cd5904eb8
commit
8446f245b5
@ -15,6 +15,7 @@
|
||||
|
||||
import datetime
|
||||
|
||||
import mock
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder import context
|
||||
@ -36,7 +37,8 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
project_id='project_id')
|
||||
self.updated_at = datetime.datetime(1, 1, 1, 1, 1, 1)
|
||||
|
||||
def test_transfer_volume_create_delete(self):
|
||||
@mock.patch('cinder.volume.utils.notify_about_volume_usage')
|
||||
def test_transfer_volume_create_delete(self, mock_notify):
|
||||
tx_api = transfer_api.API()
|
||||
utils.create_volume(self.ctxt, id='1',
|
||||
updated_at=self.updated_at)
|
||||
@ -44,10 +46,18 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
volume = db.volume_get(self.ctxt, '1')
|
||||
self.assertEqual('awaiting-transfer', volume['status'],
|
||||
'Unexpected state')
|
||||
calls = [mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
|
||||
mock.call(self.ctxt, mock.ANY, "transfer.create.end")]
|
||||
mock_notify.assert_has_calls(calls)
|
||||
self.assertEqual(2, mock_notify.call_count)
|
||||
|
||||
tx_api.delete(self.ctxt, response['id'])
|
||||
volume = db.volume_get(self.ctxt, '1')
|
||||
self.assertEqual('available', volume['status'], 'Unexpected state')
|
||||
calls = [mock.call(self.ctxt, mock.ANY, "transfer.delete.start"),
|
||||
mock.call(self.ctxt, mock.ANY, "transfer.delete.end")]
|
||||
mock_notify.assert_has_calls(calls)
|
||||
self.assertEqual(4, mock_notify.call_count)
|
||||
|
||||
def test_transfer_invalid_volume(self):
|
||||
tx_api = transfer_api.API()
|
||||
@ -59,7 +69,8 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
volume = db.volume_get(self.ctxt, '1')
|
||||
self.assertEqual('in-use', volume['status'], 'Unexpected state')
|
||||
|
||||
def test_transfer_accept(self):
|
||||
@mock.patch('cinder.volume.utils.notify_about_volume_usage')
|
||||
def test_transfer_accept(self, mock_notify):
|
||||
svc = self.start_service('volume', host='test_host')
|
||||
tx_api = transfer_api.API()
|
||||
utils.create_volume(self.ctxt, id='1',
|
||||
@ -77,12 +88,23 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
tx_api.accept,
|
||||
self.ctxt, transfer['id'], 'wrong')
|
||||
|
||||
calls = [mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
|
||||
mock.call(self.ctxt, mock.ANY, "transfer.create.end")]
|
||||
mock_notify.assert_has_calls(calls)
|
||||
self.assertEqual(2, mock_notify.call_count)
|
||||
|
||||
db.volume_update(self.ctxt, '1', {'status': 'wrong'})
|
||||
self.assertRaises(exception.InvalidVolume,
|
||||
tx_api.accept,
|
||||
self.ctxt, transfer['id'], transfer['auth_key'])
|
||||
db.volume_update(self.ctxt, '1', {'status': 'awaiting-transfer'})
|
||||
|
||||
# Because the InvalidVolume exception is raised in tx_api, so there is
|
||||
# only transfer.accept.start called and missing transfer.accept.end.
|
||||
calls = [mock.call(self.ctxt, mock.ANY, "transfer.accept.start")]
|
||||
mock_notify.assert_has_calls(calls)
|
||||
self.assertEqual(3, mock_notify.call_count)
|
||||
|
||||
self.ctxt.user_id = 'new_user_id'
|
||||
self.ctxt.project_id = 'new_project_id'
|
||||
response = tx_api.accept(self.ctxt,
|
||||
@ -99,6 +121,11 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
self.assertEqual(transfer['id'], response['id'],
|
||||
'Unexpected transfer id in response.')
|
||||
|
||||
calls = [mock.call(self.ctxt, mock.ANY, "transfer.accept.start"),
|
||||
mock.call(self.ctxt, mock.ANY, "transfer.accept.end")]
|
||||
mock_notify.assert_has_calls(calls)
|
||||
self.assertEqual(5, mock_notify.call_count)
|
||||
|
||||
svc.stop()
|
||||
|
||||
def test_transfer_get(self):
|
||||
@ -123,7 +150,8 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
ts = tx_api.get_all(nctxt)
|
||||
self.assertEqual(len(ts), 0, 'Unexpected transfers listed.')
|
||||
|
||||
def test_delete_transfer_with_deleted_volume(self):
|
||||
@mock.patch('cinder.volume.utils.notify_about_volume_usage')
|
||||
def test_delete_transfer_with_deleted_volume(self, mock_notify):
|
||||
# create a volume
|
||||
volume = utils.create_volume(self.ctxt, id='1',
|
||||
updated_at=self.updated_at)
|
||||
@ -132,6 +160,11 @@ class VolumeTransferTestCase(test.TestCase):
|
||||
transfer = tx_api.create(self.ctxt, volume['id'], 'Description')
|
||||
t = tx_api.get(self.ctxt, transfer['id'])
|
||||
self.assertEqual(t['id'], transfer['id'], 'Unexpected transfer id')
|
||||
|
||||
calls = [mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
|
||||
mock.call(self.ctxt, mock.ANY, "transfer.create.end")]
|
||||
mock_notify.assert_has_calls(calls)
|
||||
self.assertEqual(2, mock_notify.call_count)
|
||||
# force delete volume
|
||||
db.volume_destroy(context.get_admin_context(), volume['id'])
|
||||
# Make sure transfer has been deleted.
|
||||
|
@ -31,6 +31,7 @@ from cinder import exception
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder import quota
|
||||
from cinder.volume import api as volume_api
|
||||
from cinder.volume import utils as volume_utils
|
||||
|
||||
|
||||
volume_transfer_opts = [
|
||||
@ -64,9 +65,13 @@ class API(base.Base):
|
||||
transfer = self.db.transfer_get(context, transfer_id)
|
||||
|
||||
volume_ref = self.db.volume_get(context, transfer.volume_id)
|
||||
volume_utils.notify_about_volume_usage(context, volume_ref,
|
||||
"transfer.delete.start")
|
||||
if volume_ref['status'] != 'awaiting-transfer':
|
||||
LOG.error(_LE("Volume in unexpected state"))
|
||||
self.db.transfer_destroy(context, transfer_id)
|
||||
volume_utils.notify_about_volume_usage(context, volume_ref,
|
||||
"transfer.delete.end")
|
||||
|
||||
def get_all(self, context, filters=None):
|
||||
filters = filters or {}
|
||||
@ -105,6 +110,8 @@ class API(base.Base):
|
||||
if volume_ref['status'] != "available":
|
||||
raise exception.InvalidVolume(reason=_("status must be available"))
|
||||
|
||||
volume_utils.notify_about_volume_usage(context, volume_ref,
|
||||
"transfer.create.start")
|
||||
# The salt is just a short random string.
|
||||
salt = self._get_random_string(CONF.volume_transfer_salt_length)
|
||||
auth_key = self._get_random_string(CONF.volume_transfer_key_length)
|
||||
@ -123,6 +130,8 @@ class API(base.Base):
|
||||
LOG.error(_LE("Failed to create transfer record "
|
||||
"for %s"), volume_id)
|
||||
raise
|
||||
volume_utils.notify_about_volume_usage(context, volume_ref,
|
||||
"transfer.create.end")
|
||||
return {'id': transfer['id'],
|
||||
'volume_id': transfer['volume_id'],
|
||||
'display_name': transfer['display_name'],
|
||||
@ -145,6 +154,8 @@ class API(base.Base):
|
||||
|
||||
volume_id = transfer['volume_id']
|
||||
vol_ref = self.db.volume_get(context.elevated(), volume_id)
|
||||
volume_utils.notify_about_volume_usage(context, vol_ref,
|
||||
"transfer.accept.start")
|
||||
|
||||
try:
|
||||
reservations = QUOTAS.reserve(context, volumes=1,
|
||||
@ -210,6 +221,8 @@ class API(base.Base):
|
||||
project_id=donor_id)
|
||||
|
||||
vol_ref = self.db.volume_get(context, volume_id)
|
||||
volume_utils.notify_about_volume_usage(context, vol_ref,
|
||||
"transfer.accept.end")
|
||||
return {'id': transfer_id,
|
||||
'display_name': transfer['display_name'],
|
||||
'volume_id': vol_ref['id']}
|
||||
|
Loading…
Reference in New Issue
Block a user