Don't block stack deletion if user creds fail
In some deployments, user passwords are generated by other authentication infrastructures where the length of the Base64 encoded credentials is longer than the DB limit. When this incorrect behavior happens silently, the user credential can not be retrieved. In this case, stack deletion will abort due to uncaught exception. This patch enables a stack deletion to handle this error so that stack can be properly deleted. Change-Id: Iaf80b18a83c7752465621c232335dcf32afbcbf3 Closes-Bug: 1386213
This commit is contained in:
parent
c16f539c53
commit
9698da6804
|
@ -868,13 +868,25 @@ class Stack(collections.Mapping):
|
|||
|
||||
stack.delete(backup=True)
|
||||
|
||||
def _try_get_user_creds(self, user_creds_id):
|
||||
# There are cases where the user_creds cannot be returned
|
||||
# due to credentials truncated when being saved to DB.
|
||||
# Ignore this error instead of blocking stack deletion.
|
||||
user_creds = None
|
||||
try:
|
||||
user_creds = db_api.user_creds_get(self.user_creds_id)
|
||||
except exception.Error as err:
|
||||
LOG.exception(err)
|
||||
pass
|
||||
return user_creds
|
||||
|
||||
def _delete_credentials(self, stack_status, reason, abandon):
|
||||
# Cleanup stored user_creds so they aren't accessible via
|
||||
# the soft-deleted stack which remains in the DB
|
||||
# The stack_status and reason passed in are current values, which
|
||||
# may get rewritten and returned from this method
|
||||
if self.user_creds_id:
|
||||
user_creds = db_api.user_creds_get(self.user_creds_id)
|
||||
user_creds = self._try_get_user_creds(self.user_creds_id)
|
||||
# If we created a trust, delete it
|
||||
if user_creds is not None:
|
||||
trust_id = user_creds.get('trust_id')
|
||||
|
|
|
@ -1399,10 +1399,12 @@ class StackTest(common.HeatTestCase):
|
|||
self.stack.state)
|
||||
|
||||
def test_delete_user_creds_gone_missing(self):
|
||||
'''It may happen that user_creds were deleted when a delete
|
||||
operation was stopped. We should be resilient to this and still
|
||||
complete the delete operation.
|
||||
'''
|
||||
'''Do not block stack deletion if user_creds is missing.
|
||||
|
||||
It may happen that user_creds were deleted when a delete operation was
|
||||
stopped. We should be resilient to this and still complete the delete
|
||||
operation.
|
||||
'''
|
||||
self.stack = parser.Stack(self.ctx, 'delete_test',
|
||||
self.tmpl)
|
||||
stack_id = self.stack.store()
|
||||
|
@ -1427,6 +1429,29 @@ class StackTest(common.HeatTestCase):
|
|||
self.assertEqual((parser.Stack.DELETE, parser.Stack.COMPLETE),
|
||||
self.stack.state)
|
||||
|
||||
def test_delete_user_creds_fail(self):
|
||||
'''Do not stop deleting stacks even failed deleting user_creds.
|
||||
|
||||
It may happen that user_creds were incorrectly saved (truncated) and
|
||||
thus cannot be correctly retrieved (and decrypted). In this case,
|
||||
stack delete should not be stopped.
|
||||
'''
|
||||
self.stack = parser.Stack(self.ctx, 'delete_test', self.tmpl)
|
||||
stack_id = self.stack.store()
|
||||
|
||||
db_s = db_api.stack_get(self.ctx, stack_id)
|
||||
self.assertIsNotNone(db_s)
|
||||
self.assertIsNotNone(db_s.user_creds_id)
|
||||
exc = exception.Error('Cannot get user credentials')
|
||||
self.patchobject(db_api, 'user_creds_get').side_effect = exc
|
||||
|
||||
self.stack.delete()
|
||||
|
||||
db_s = db_api.stack_get(self.ctx, stack_id)
|
||||
self.assertIsNone(db_s)
|
||||
self.assertEqual((parser.Stack.DELETE, parser.Stack.COMPLETE),
|
||||
self.stack.state)
|
||||
|
||||
def test_delete_trust(self):
|
||||
cfg.CONF.set_override('deferred_auth_method', 'trusts')
|
||||
self.stub_keystoneclient()
|
||||
|
|
Loading…
Reference in New Issue