summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Lynn <xjunlin@cn.ibm.com>2014-11-12 14:01:19 +0800
committerRakesh H S <rh-s@hp.com>2015-08-18 12:42:02 +0000
commit46bef7ae3bbff3abcfc36a173e86636791d218ed (patch)
tree76690c18e1fc1bbf55adfb7e2a899e18cf999804
parent70fb2e8d05e8a9c9a08e6b81c38567bd33c5bba2 (diff)
downloadheat-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.py16
-rw-r--r--heat/engine/service.py8
-rw-r--r--heat/tests/test_engine_service.py11
-rw-r--r--heat/tests/test_heatclient.py5
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(