diff options
author | Ethan Lynn <xjunlin@cn.ibm.com> | 2014-11-12 14:01:19 +0800 |
---|---|---|
committer | Rakesh H S <rh-s@hp.com> | 2015-08-18 12:42:02 +0000 |
commit | 46bef7ae3bbff3abcfc36a173e86636791d218ed (patch) | |
tree | 76690c18e1fc1bbf55adfb7e2a899e18cf999804 | |
parent | 70fb2e8d05e8a9c9a08e6b81c38567bd33c5bba2 (diff) | |
download | heat-46bef7ae3bbff3abcfc36a173e86636791d218ed.tar.gz |
Catch v3 keystone unauthorized error when creating stack
If v3 keystone unauthorized error raise during creating stack,
then this stack will remaid in status of create_in_progress. This
patch modify heat keystoneclient to catch unauthorized error and
set stack status to failed.
Closes-Bug: #1376213
Closes-Bug: #1450923
Change-Id: I9a34c20fc6ac3ce235aaba4eac25a6d5ceb43f5f
(cherry picked from commit dca8e37e651c32aca7224fda208e1241efbf23f2)
-rw-r--r-- | heat/common/heat_keystoneclient.py | 16 | ||||
-rw-r--r-- | heat/engine/service.py | 8 | ||||
-rw-r--r-- | heat/tests/test_engine_service.py | 11 | ||||
-rw-r--r-- | heat/tests/test_heatclient.py | 5 |
4 files changed, 32 insertions, 8 deletions
diff --git a/heat/common/heat_keystoneclient.py b/heat/common/heat_keystoneclient.py index 50888ea75..6d477fcef 100644 --- a/heat/common/heat_keystoneclient.py +++ b/heat/common/heat_keystoneclient.py @@ -127,9 +127,10 @@ class KeystoneClientV3(object): admin_creds = self._service_admin_creds() admin_creds.update(self._ssl_options()) c = kc_v3.Client(**admin_creds) - if c.authenticate(): + try: + c.authenticate() self._admin_client = c - else: + except kc_exception.Unauthorized: LOG.error(_LE("Admin client authentication failed")) raise exception.AuthorizationFailure() return self._admin_client @@ -147,9 +148,10 @@ class KeystoneClientV3(object): auth_kwargs = {'domain_id': self.stack_domain} else: auth_kwargs = {'domain_name': self.stack_domain} - if c.authenticate(**auth_kwargs): + try: + c.authenticate(**auth_kwargs) self._domain_admin_client = c - else: + except kc_exception.Unauthorized: LOG.error(_LE("Domain admin client authentication failed")) raise exception.AuthorizationFailure() return self._domain_admin_client @@ -200,7 +202,11 @@ class KeystoneClientV3(object): # If auth_ref has already be specified via auth_token_info, don't # authenticate as we want to reuse, rather than request a new token if 'auth_ref' not in kwargs: - client.authenticate() + try: + client.authenticate() + except kc_exception.Unauthorized: + LOG.error(_LE("Keystone client authentication failed")) + raise exception.AuthorizationFailure() # If we are authenticating with a trust set the context auth_token # with the trust scoped token diff --git a/heat/engine/service.py b/heat/engine/service.py index a36a08c39..c6bd59070 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -618,7 +618,11 @@ class EngineService(service.Service): def _stack_create(stack): if not stack.stack_user_project_id: - stack.create_stack_user_project_id() + try: + stack.create_stack_user_project_id() + except exception.AuthorizationFailure as ex: + stack.state_set(stack.action, stack.FAILED, + six.text_type(ex)) # Create/Adopt a stack, and create the periodic task if successful if stack.adopt_stack_data: @@ -626,7 +630,7 @@ class EngineService(service.Service): raise exception.NotSupported(feature='Stack Adopt') stack.adopt() - else: + elif stack.status != stack.FAILED: stack.create() if (stack.action in (stack.CREATE, stack.ADOPT) diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index 47491cde7..931504928 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -597,6 +597,17 @@ class StackServiceCreateUpdateDeleteTest(HeatTestCase): self.ctx, stack_name, stack.t.t, {}, None, {}) + def test_stack_create_AuthorizationFailure(self): + stack_name = 'service_create_test_stack_AuthorizationFailure' + stack = get_wordpress_stack(stack_name, self.ctx) + self.m.StubOutWithMock(parser.Stack, 'create_stack_user_project_id') + parser.Stack.create_stack_user_project_id().AndRaise( + exception.AuthorizationFailure) + self.assertRaises(dispatcher.ExpectedException, + self.man.create_stack, + self.ctx, stack_name, + stack.t.t, {}, None, {}) + def test_stack_create_no_credentials(self): stack_name = 'test_stack_create_no_credentials' params = {'foo': 'bar'} diff --git a/heat/tests/test_heatclient.py b/heat/tests/test_heatclient.py index ade82f115..7ede9d45d 100644 --- a/heat/tests/test_heatclient.py +++ b/heat/tests/test_heatclient.py @@ -74,10 +74,13 @@ class KeystoneClientTest(HeatTestCase): project_name='service', username='heat').AndReturn(self.mock_admin_client) self.mock_admin_client.domains = self.mock_ks_v3_client_domain_mngr - self.mock_admin_client.authenticate().AndReturn(auth_ok) if auth_ok: + self.mock_admin_client.authenticate().AndReturn(auth_ok) self.mock_admin_client.auth_ref = self.m.CreateMockAnything() self.mock_admin_client.auth_ref.user_id = '1234' + else: + self.mock_admin_client.authenticate().AndRaise( + kc_exception.Unauthorized) def _stub_domain_admin_client(self, auth_ok=True): kc_v3.Client( |