From caf1d7515c37c829603748d9e5d45fa22594f87e Mon Sep 17 00:00:00 2001 From: lisali Date: Wed, 16 Mar 2016 07:27:05 +0000 Subject: [PATCH] Check volume_id consistent when creating backup When creating backup from snapshot, users specify both volume id and snapshot id, this patch is to make sure volume id is consistent with snapshot.volume_id. Change-Id: I1bdaf00299ac6f9f45128b754b79be6700f44304 Closes-bug: #1557922 --- cinder/backup/api.py | 6 ++++ cinder/tests/unit/api/contrib/test_backups.py | 36 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/cinder/backup/api.py b/cinder/backup/api.py index c447859ef..4397e40ae 100644 --- a/cinder/backup/api.py +++ b/cinder/backup/api.py @@ -243,6 +243,12 @@ class API(base.Base): if snapshot_id: snapshot = self.volume_api.get_snapshot(context, snapshot_id) + if volume_id != snapshot.volume_id: + msg = (_('Volume %(vol1)s does not match with ' + 'snapshot.volume_id %(vol2)s.') + % {'vol1': volume_id, + 'vol2': snapshot.volume_id}) + raise exception.InvalidVolume(reason=msg) if volume['status'] not in ["available", "in-use"]: msg = (_('Volume to be backed up must be available ' 'or in-use, but the current status is "%s".') diff --git a/cinder/tests/unit/api/contrib/test_backups.py b/cinder/tests/unit/api/contrib/test_backups.py index 38b2ad485..cab8dbf9e 100644 --- a/cinder/tests/unit/api/contrib/test_backups.py +++ b/cinder/tests/unit/api/contrib/test_backups.py @@ -699,6 +699,42 @@ class BackupsAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id) + def test_create_backup_snapshot_with_inconsistent_volume(self): + volume_id = utils.create_volume(self.context, size=5, + status='available')['id'] + volume_id2 = utils.create_volume(self.context, size=5, + status='available')['id'] + snapshot_id = utils.create_snapshot(self.context, + volume_id, + status='available')['id'] + + self.addCleanup(db.volume_destroy, + self.context.elevated(), + volume_id) + self.addCleanup(db.volume_destroy, + self.context.elevated(), + volume_id2) + self.addCleanup(db.snapshot_destroy, + self.context.elevated(), + snapshot_id) + body = {"backup": {"display_name": "nightly001", + "display_description": + "Nightly Backup 03-Sep-2012", + "volume_id": volume_id2, + "snapshot_id": snapshot_id, + "container": "nightlybackups", + } + } + req = webob.Request.blank('/v2/fake/backups') + req.method = 'POST' + req.headers['Content-Type'] = 'application/json' + req.body = jsonutils.dump_as_bytes(body) + res = req.get_response(fakes.wsgi_app()) + + res_dict = jsonutils.loads(res.body) + self.assertEqual(400, res.status_int) + self.assertIsNotNone(res_dict['badRequest']['message']) + @mock.patch('cinder.db.service_get_all_by_topic') @mock.patch( 'cinder.api.openstack.wsgi.Controller.validate_name_and_description') -- 2.45.2