engine.clients always use keystoneclient auth_token

Always get the token from keystoneclient, even if there is one in
the request context, as if the context contains a username and
password, there is the possibility the keystoneclient auth_token
may be a reissued token which should be preferred to the one in
the context which may have expired.

Change-Id: Icbce9ae7a8ff7cad5eadec3de4f69b977949c265
Partial-Bug: #1306294
This commit is contained in:
Steven Hardy 2014-06-17 16:43:13 +01:00
parent f9d9fae233
commit e39f80d25d
4 changed files with 29 additions and 8 deletions

View File

@ -58,9 +58,11 @@ class OpenStackClients(object):
@property
def auth_token(self):
# if there is no auth token in the context
# attempt to get one using the context username and password
return self.context.auth_token or self.keystone().auth_token
# Always use the auth_token from the keystone() client, as
# this may be refreshed if the context contains credentials
# which allow reissuing of a new token before the context
# auth_token expiry (e.g trust_id or username/password)
return self.keystone().auth_token
def keystone(self):
if self._keystone:

View File

@ -114,4 +114,6 @@ class HeatTestCase(testscenarios.WithScenarios,
def stub_keystoneclient(self, **kwargs):
client = self.patchobject(clients.OpenStackClients, "keystone")
client.return_value = fakes.FakeKeystoneClient(**kwargs)
fkc = fakes.FakeKeystoneClient(**kwargs)
client.return_value = fkc
return fkc

View File

@ -78,7 +78,7 @@ class FakeClient(object):
class FakeKeystoneClient(object):
def __init__(self, username='test_user', password='apassword',
user_id='1234', access='4567', secret='8901',
credential_id='abcdxyz'):
credential_id='abcdxyz', auth_token='abcd1234'):
self.username = username
self.password = password
self.user_id = user_id
@ -92,7 +92,7 @@ class FakeKeystoneClient(object):
secret = self.secret
self.creds = FakeCred()
self.auth_token = 'abcd1234'
self.auth_token = auth_token
def create_stack_user(self, username, password=''):
self.username = username

View File

@ -14,7 +14,6 @@
import mock
from heatclient import client as heatclient
from keystoneclient import exceptions as keystone_exceptions
from heat.engine import clients
from heat.tests.common import HeatTestCase
@ -43,6 +42,7 @@ class ClientsTest(HeatTestCase):
@mock.patch.object(heatclient, 'Client')
def test_clients_heat(self, mock_call):
self.stub_keystoneclient()
con = mock.Mock()
con.auth_url = "http://auth.example.com:5000/v2.0"
con.tenant_id = "b363706f891f48019483f8bd6503c54b"
@ -61,6 +61,7 @@ class ClientsTest(HeatTestCase):
@mock.patch.object(heatclient, 'Client')
def test_clients_heat_no_auth_token(self, mock_call):
self.stub_keystoneclient(auth_token='anewtoken')
con = mock.Mock()
con.auth_url = "http://auth.example.com:5000/v2.0"
con.tenant_id = "b363706f891f48019483f8bd6503c54b"
@ -70,10 +71,12 @@ class ClientsTest(HeatTestCase):
obj._get_heat_url.return_value = None
obj.url_for = mock.Mock(name="url_for")
obj.url_for.return_value = "url_from_keystone"
self.assertRaises(keystone_exceptions.AuthorizationFailure, obj.heat)
self.assertIsNotNone(obj.heat())
self.assertEqual('anewtoken', obj.keystone().auth_token)
@mock.patch.object(heatclient, 'Client')
def test_clients_heat_cached(self, mock_call):
self.stub_keystoneclient()
con = mock.Mock()
con.auth_url = "http://auth.example.com:5000/v2.0"
con.tenant_id = "b363706f891f48019483f8bd6503c54b"
@ -87,3 +90,17 @@ class ClientsTest(HeatTestCase):
heat = obj.heat()
heat_cached = obj.heat()
self.assertEqual(heat, heat_cached)
def test_clients_auth_token_update(self):
fkc = self.stub_keystoneclient(auth_token='token1')
con = mock.Mock()
con.auth_url = "http://auth.example.com:5000/v2.0"
con.trust_id = "b363706f891f48019483f8bd6503c54b"
con.username = 'heat'
con.password = 'verysecret'
con.auth_token = None
obj = clients.Clients(con)
self.assertIsNotNone(obj.heat())
self.assertEqual('token1', obj.auth_token)
fkc.auth_token = 'token2'
self.assertEqual('token2', obj.auth_token)