Implement force parameter

This change adds the force parameter to the secret delete
method. By default, a secret cannot be deleted if it
contains consumers.

This code cannot be merged without a corresponding release and
bump of version for the barbicanclient.

Co-Authored-By: Mauricio Harley <mharley@redhat.com>
Change-Id: I84fd870b1cd19975a5bb832ed6fd6d18ec56eb5a
This commit is contained in:
Grzegorz Grasza 2023-01-20 10:45:58 +01:00
parent bc6d87b969
commit 96027e9cff
5 changed files with 42 additions and 7 deletions

View File

@ -619,19 +619,23 @@ class BarbicanKeyManager(key_manager.KeyManager):
else:
raise exception.KeyManagerError(reason=e)
def delete(self, context, managed_object_id):
def delete(self, context, managed_object_id, force=False):
"""Deletes the specified managed object.
:param context: contains information of the user and the environment
for the request (castellan/context.py)
:param managed_object_id: the UUID of the object to delete
:param force: specifies if the secret must be deleted even when they
have consumers.
:raises ValueError: if the secret has consumers but no force parameter
is provided or if force equals False.
:raises KeyManagerError: if object deletion fails
:raises ManagedObjectNotFoundError: if the object could not be found
"""
barbican_client = self._get_barbican_client(context)
try:
secret_ref = self._create_secret_ref(managed_object_id)
barbican_client.secrets.delete(secret_ref)
barbican_client.secrets.delete(secret_ref, force)
except (barbican_exceptions.HTTPAuthError,
barbican_exceptions.HTTPClientError,
barbican_exceptions.HTTPServerError) as e:

View File

@ -106,7 +106,7 @@ class KeyManager(object, metaclass=abc.ABCMeta):
pass
@abc.abstractmethod
def delete(self, context, managed_object_id):
def delete(self, context, managed_object_id, force=False):
"""Deletes the specified managed object.
Implementations should verify that the caller has permission to delete
@ -119,6 +119,10 @@ class KeyManager(object, metaclass=abc.ABCMeta):
UUIDs of objects that belong to other users by repeatedly calling this
method. That is, objects that belong to other users should be
considered "non-existent" and completely invisible.
Implementations that block the deletion of secrets with consumers
without making the "force" parameter equals True should raise
an exception.
"""
pass

View File

@ -48,7 +48,7 @@ class NotImplementedKeyManager(key_manager.KeyManager):
def list(self, context, object_type=None):
raise NotImplementedError()
def delete(self, context, managed_object_id):
def delete(self, context, managed_object_id, force=False):
raise NotImplementedError()
def add_consumer(self, context, managed_object_id, consumer_data):

View File

@ -343,8 +343,12 @@ class VaultKeyManager(key_manager.KeyManager):
record['created'],
key_id)
def delete(self, context, key_id):
"""Represents deleting the key."""
def delete(self, context, key_id, force=False):
"""Represents deleting the key.
The 'force' parameter is not used whatsoever and only kept to allow
consistency with the Barbican implementation.
"""
if not key_id:
raise exception.KeyManagerError('key identifier not provided')

View File

@ -383,7 +383,30 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase):
def test_delete_key(self):
self.key_mgr.delete(self.ctxt, self.key_id)
self.delete.assert_called_once_with(self.secret_ref)
self.delete.assert_called_once_with(self.secret_ref, False)
def test_delete_secret_with_consumers_no_force_parameter(self):
self.mock_barbican.secrets.delete = mock.Mock(
side_effect=exception.KeyManagerError(
"Secret has consumers! Use the 'force' parameter."))
self.assertRaises(exception.KeyManagerError,
self.key_mgr.delete, self.ctxt, self.key_id)
self.mock_barbican.secrets.delete.assert_called_once_with(
self.secret_ref, False)
def test_delete_secret_with_consumers_force_parameter_false(self):
self.mock_barbican.secrets.delete = mock.Mock(
side_effect=barbican_exceptions.HTTPClientError(
"Secret has consumers! Use the 'force' parameter."))
self.assertRaises(exception.KeyManagerError,
self.key_mgr.delete, self.ctxt, self.key_id,
force=False)
self.mock_barbican.secrets.delete.assert_called_once_with(
self.secret_ref, False)
def test_delete_secret_with_consumers_force_parameter_true(self):
self.key_mgr.delete(self.ctxt, self.key_id, force=True)
self.delete.assert_called_once_with(self.secret_ref, True)
def test_delete_unknown_key(self):
self.assertRaises(exception.KeyManagerError,