diff options
-rw-r--r-- | heat/engine/parser.py | 12 | ||||
-rw-r--r-- | heat/tests/test_parser.py | 30 |
2 files changed, 40 insertions, 2 deletions
diff --git a/heat/engine/parser.py b/heat/engine/parser.py index 6943f352d..ba97e72c2 100644 --- a/heat/engine/parser.py +++ b/heat/engine/parser.py @@ -558,14 +558,22 @@ class Stack(object): stack_status = self.FAILED reason = '%s timed out' % action.title() - self.state_set(action, stack_status, reason) if stack_status != self.FAILED: # If we created a trust, delete it stack = db_api.stack_get(self.context, self.id) user_creds = db_api.user_creds_get(stack.user_creds_id) trust_id = user_creds.get('trust_id') if trust_id: - self.clients.keystone().delete_trust(trust_id) + try: + self.clients.keystone().delete_trust(trust_id) + except Exception as ex: + logger.exception(ex) + stack_status = self.FAILED + reason = "Error deleting trust: %s" % str(ex) + + self.state_set(action, stack_status, reason) + + if stack_status != self.FAILED: # delete the stack db_api.stack_delete(self.context, self.id) self.id = None diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index e7c2b79b2..8f15df975 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -15,6 +15,8 @@ import json import time +from keystoneclient import exceptions as kc_exceptions + from oslo.config import cfg from heat.engine import environment @@ -819,6 +821,34 @@ class StackTest(HeatTestCase): (parser.Stack.DELETE, parser.Stack.COMPLETE)) @utils.stack_delete_after + def test_delete_trust_fail(self): + cfg.CONF.set_override('deferred_auth_method', 'trusts') + + class FakeKeystoneClientFail(FakeKeystoneClient): + def delete_trust(self, trust_id): + raise kc_exceptions.Forbidden("Denied!") + + self.m.StubOutWithMock(clients.OpenStackClients, 'keystone') + clients.OpenStackClients.keystone().MultipleTimes().AndReturn( + FakeKeystoneClientFail()) + self.m.ReplayAll() + + self.stack = parser.Stack( + self.ctx, 'delete_trust', template.Template({})) + stack_id = self.stack.store() + + db_s = db_api.stack_get(self.ctx, stack_id) + self.assertIsNotNone(db_s) + + self.stack.delete() + + db_s = db_api.stack_get(self.ctx, stack_id) + self.assertIsNotNone(db_s) + self.assertEqual(self.stack.state, + (parser.Stack.DELETE, parser.Stack.FAILED)) + self.assertIn('Error deleting trust', self.stack.status_reason) + + @utils.stack_delete_after def test_suspend_resume(self): self.m.ReplayAll() tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType'}}} |