From 1e0e7042acd9bfb9f61d6f341785b7fa0404db45 Mon Sep 17 00:00:00 2001 From: Brian Rosmaita Date: Tue, 14 Apr 2020 07:50:47 -0400 Subject: [PATCH] Add tests for volume type encryption type policies Before dealing with the policy target deprecation from commit ebc9a12a19bff61bd6101def5cc997513d329bc2, make sure we have tests in place to detect any regression in the default policy configuration. Closes-bug: #1872985 Change-Id: I1b51e5e85aa2a928c28e29c54283b6316a56da2a --- cinder/tests/unit/fake_constants.py | 1 + .../tests/unit/policies/test_volume_type.py | 171 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 cinder/tests/unit/policies/test_volume_type.py diff --git a/cinder/tests/unit/fake_constants.py b/cinder/tests/unit/fake_constants.py index 80689caa650..e9a8888d6cb 100644 --- a/cinder/tests/unit/fake_constants.py +++ b/cinder/tests/unit/fake_constants.py @@ -30,6 +30,7 @@ CONSISTENCY_GROUP_ID = 'f18abf73-79ee-4f2b-8d4f-1c044148f117' CONSISTENCY_GROUP2_ID = '8afc8952-9dce-4228-9f8a-706c5cb5fc82' ENCRYPTION_KEY_ID = 'e8387001-745d-45d0-9e4e-0473815ef09a' ENCRYPTION_KEY2_ID = 'fa0dc8ce-79a4-4162-846f-c731b99f3113' +ENCRYPTION_TYPE_ID = 'af2ae9b8-f40a-4cbc-9f51-b54eb5469405' IMAGE_ID = 'e79161cd-5f9d-4007-8823-81a807a64332' INSTANCE_ID = 'fa617131-cdbc-45dc-afff-f21f17ae054e' IN_USE_ID = '8ee42073-4ac2-4099-8c7a-d416630e6aee' diff --git a/cinder/tests/unit/policies/test_volume_type.py b/cinder/tests/unit/policies/test_volume_type.py new file mode 100644 index 00000000000..785bd0b9529 --- /dev/null +++ b/cinder/tests/unit/policies/test_volume_type.py @@ -0,0 +1,171 @@ +# +# 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. + +import http.client +from unittest import mock + +from cinder.api.contrib import volume_type_encryption as vol_type_enc +from cinder import db +from cinder.tests.unit import fake_constants +from cinder.tests.unit.policies import test_base + + +class VolumeTypePolicyTests(test_base.CinderPolicyTests): + """Verify default policy settings for the types API""" + + # TODO: add some tests! + pass + + +class VolumeTypeEncryptionTypePolicyTests(test_base.CinderPolicyTests): + """Verify default policy settings for encryption types in the types API""" + def setUp(self): + super(VolumeTypeEncryptionTypePolicyTests, self).setUp() + self.volume_type = self._create_fake_type(self.admin_context) + + def test_admin_can_create_volume_type_encryption_type(self): + admin_context = self.admin_context + path = '/v3/%(project_id)s/types/%(type_id)s/encryption' % { + 'project_id': admin_context.project_id, + 'type_id': self.volume_type.id + } + body = {"encryption": {"key_size": 128, + "provider": "luks", + "control_location": "front-end", + "cipher": "aes-xts-plain64"}} + response = self._get_request_response(admin_context, path, 'POST', + body=body) + self.assertEqual(http.client.OK, response.status_int) + + def test_nonadmin_cannot_create_volume_type_encryption_type(self): + self.assertTrue(self.volume_type.is_public) + path = '/v3/%(project_id)s/types/%(type_id)s/encryption' % { + 'project_id': self.user_context.project_id, + 'type_id': self.volume_type.id + } + body = {"encryption": {"key_size": 128, + "provider": "luks", + "control_location": "front-end", + "cipher": "aes-xts-plain64"}} + response = self._get_request_response(self.user_context, path, 'POST', + body=body) + self.assertEqual(http.client.FORBIDDEN, response.status_int) + + @mock.patch.object(vol_type_enc.VolumeTypeEncryptionController, + '_get_volume_type_encryption') + def test_admin_can_show_volume_type_encryption_type(self, mock_get_enc): + mock_get_enc.return_value = { + 'cipher': 'aes-xts-plain64', + 'control_location': 'front-end', + 'encryption_id': fake_constants.ENCRYPTION_TYPE_ID, + 'key_size': 128, + 'provider': 'luks', + 'volume_type_id': self.volume_type.id} + admin_context = self.admin_context + path = '/v3/%(project_id)s/types/%(type_id)s/encryption' % { + 'project_id': admin_context.project_id, + 'type_id': self.volume_type.id + } + response = self._get_request_response(admin_context, path, 'GET') + self.assertEqual(http.client.OK, response.status_int) + + def test_nonadmin_cannot_show_volume_type_encryption_type(self): + self.assertTrue(self.volume_type.is_public) + path = '/v3/%(project_id)s/types/%(type_id)s/encryption' % { + 'project_id': self.user_context.project_id, + 'type_id': self.volume_type.id + } + response = self._get_request_response(self.user_context, path, 'GET') + self.assertEqual(http.client.FORBIDDEN, response.status_int) + + @mock.patch.object(vol_type_enc.VolumeTypeEncryptionController, + '_get_volume_type_encryption') + def test_admin_can_show_volume_type_encryption_spec_item( + self, mock_get_enc): + enc_specs = { + 'cipher': 'aes-xts-plain64', + 'control_location': 'front-end', + 'encryption_id': fake_constants.ENCRYPTION_TYPE_ID, + 'key_size': 128, + 'provider': 'foobar', + 'volume_type_id': self.volume_type.id} + mock_get_enc.return_value = enc_specs + admin_context = self.admin_context + path = '/v3/%(project_id)s/types/%(type_id)s/encryption/%(item)s' % { + 'project_id': admin_context.project_id, + 'type_id': self.volume_type.id, + 'item': 'provider' + } + response = self._get_request_response(admin_context, path, 'GET') + self.assertEqual(http.client.OK, response.status_int) + + def test_nonadmin_cannot_show_volume_type_encryption_spec_item(self): + self.assertTrue(self.volume_type.is_public) + path = '/v3/%(project_id)s/types/%(type_id)s/encryption/%(item)s' % { + 'project_id': self.user_context.project_id, + 'type_id': self.volume_type.id, + 'item': 'control_location' + } + response = self._get_request_response(self.user_context, path, 'GET') + self.assertEqual(http.client.FORBIDDEN, response.status_int) + + @mock.patch.object(db, 'volume_type_encryption_delete', return_value=None) + def test_admin_can_delete_volume_type_encryption_type( + self, mock_db_delete): + admin_context = self.admin_context + path = '/v3/%(project_id)s/types/%(type_id)s/encryption/%(enc_id)s' % { + 'project_id': admin_context.project_id, + 'type_id': self.volume_type.id, + 'enc_id': fake_constants.ENCRYPTION_TYPE_ID + } + response = self._get_request_response(admin_context, path, 'DELETE') + self.assertEqual(http.client.ACCEPTED, response.status_int) + + def test_nonadmin_cannot_delete_volume_type_encryption_type(self): + self.assertTrue(self.volume_type.is_public) + path = '/v3/%(project_id)s/types/%(type_id)s/encryption/%(enc_id)s' % { + 'project_id': self.user_context.project_id, + 'type_id': self.volume_type.id, + 'enc_id': fake_constants.ENCRYPTION_TYPE_ID + } + response = self._get_request_response(self.user_context, path, + 'DELETE') + self.assertEqual(http.client.FORBIDDEN, response.status_int) + + @mock.patch.object(db, 'volume_type_encryption_update', return_value=None) + def test_admin_can_update_volume_type_encryption_type( + self, mock_db_update): + admin_context = self.admin_context + req_body = {"encryption": {"key_size": 64, + "control_location": "back-end"}} + path = '/v3/%(project_id)s/types/%(type_id)s/encryption/%(enc_id)s' % { + 'project_id': admin_context.project_id, + 'type_id': self.volume_type.id, + 'enc_id': fake_constants.ENCRYPTION_TYPE_ID + } + response = self._get_request_response(admin_context, path, 'PUT', + body=req_body) + self.assertEqual(http.client.OK, response.status_int) + + def test_nonadmin_cannot_update_volume_type_encryption_type(self): + self.assertTrue(self.volume_type.is_public) + req_body = {"encryption": {"key_size": 64, + "control_location": "back-end"}} + path = '/v3/%(project_id)s/types/%(type_id)s/encryption/%(enc_id)s' % { + 'project_id': self.user_context.project_id, + 'type_id': self.volume_type.id, + 'enc_id': fake_constants.ENCRYPTION_TYPE_ID + } + response = self._get_request_response(self.user_context, path, 'PUT', + body=req_body) + self.assertEqual(http.client.FORBIDDEN, response.status_int)