Revise trust middleware
This patch revises the trust middleware to use the engine RPC interface instead of the DB APIs. Change-Id: I7838b68ef87ad5d470727586f4cf2b1edb7069ed
This commit is contained in:
parent
043b53735b
commit
2b9f9141c7
|
@ -13,30 +13,31 @@
|
|||
from senlin.api.common import wsgi
|
||||
from senlin.common import context
|
||||
from senlin.common import exception
|
||||
from senlin.db import api as db_api
|
||||
from senlin.drivers import base as driver_base
|
||||
from senlin.rpc import client as rpc
|
||||
|
||||
|
||||
class TrustMiddleware(wsgi.Middleware):
|
||||
'''Extract trust info from request.
|
||||
"""Extract trust info from request.
|
||||
|
||||
The extracted information is filled into the request context.
|
||||
Senlin engine will use this information for access control.
|
||||
'''
|
||||
"""
|
||||
def _get_trust(self, ctx):
|
||||
'''List trusts with current user as the trustor.'''
|
||||
"""List trusts with current user as the trustor.
|
||||
|
||||
:param ctx: The requesting context.
|
||||
:return: ID of the trust or exception of InternalError.
|
||||
"""
|
||||
rpcc = rpc.EngineClient()
|
||||
|
||||
# DB table is used as a cache for the trusts.
|
||||
cred_exists = False
|
||||
res = db_api.cred_get(ctx, ctx.user, ctx.project)
|
||||
if res is not None:
|
||||
try:
|
||||
trust_id = res.cred['openstack']['trust']
|
||||
res = rpcc.credential_get(ctx)
|
||||
if res:
|
||||
trust_id = res.get('trust', None)
|
||||
if trust_id:
|
||||
return trust_id
|
||||
except KeyError:
|
||||
# Garbage in the store, ignore it
|
||||
cred_exists = True
|
||||
pass
|
||||
cred_exists = True
|
||||
|
||||
params = {
|
||||
'auth_url': ctx.auth_url,
|
||||
|
@ -60,15 +61,9 @@ class TrustMiddleware(wsgi.Middleware):
|
|||
|
||||
# update cache
|
||||
if cred_exists:
|
||||
db_api.cred_update(ctx.user, ctx.project,
|
||||
{'cred': {'openstack': {'trust': trust.id}}})
|
||||
rpcc.credential_update(ctx, trust.id)
|
||||
else:
|
||||
values = {
|
||||
'user': ctx.user,
|
||||
'project': ctx.project,
|
||||
'cred': {'openstack': {'trust': trust.id}}
|
||||
}
|
||||
db_api.cred_create(ctx, values)
|
||||
rpcc.credential_create(ctx, trust.id)
|
||||
|
||||
return trust.id
|
||||
|
||||
|
|
|
@ -11,12 +11,11 @@
|
|||
# under the License.
|
||||
|
||||
import mock
|
||||
import six
|
||||
|
||||
from senlin.api.middleware import trust
|
||||
from senlin.common import context
|
||||
from senlin.common import exception
|
||||
from senlin.db import api as db_api
|
||||
from senlin.drivers import base as driver_base
|
||||
from senlin.tests.unit.common import base
|
||||
from senlin.tests.unit.common import utils
|
||||
|
||||
|
@ -28,40 +27,177 @@ class TestTrustMiddleware(base.SenlinTestCase):
|
|||
self.context = utils.dummy_context()
|
||||
self.middleware = trust.TrustMiddleware(None)
|
||||
|
||||
@mock.patch('senlin.db.api')
|
||||
def test_get_trust_already_exists(self, mock_db_api):
|
||||
res = mock.MagicMock()
|
||||
res.cred = {}
|
||||
res.cred['openstack'] = {}
|
||||
res.cred['openstack']['trust'] = 'FAKE_TRUST_ID'
|
||||
db_api.cred_get = mock.MagicMock(return_value=res)
|
||||
trust_id = self.middleware._get_trust(self.context)
|
||||
self.assertEqual(res.cred['openstack']['trust'], trust_id)
|
||||
self.assertTrue(db_api.cred_get.called)
|
||||
@mock.patch("senlin.rpc.client.EngineClient")
|
||||
def test__get_trust_already_exists(self, mock_rpc):
|
||||
x_cred = {'trust': 'FAKE_TRUST_ID'}
|
||||
x_rpc = mock.Mock()
|
||||
x_rpc.credential_get.return_value = x_cred
|
||||
mock_rpc.return_value = x_rpc
|
||||
|
||||
@mock.patch.object(context, 'get_service_context')
|
||||
@mock.patch.object(db_api, 'cred_get')
|
||||
@mock.patch.object(db_api, 'cred_create')
|
||||
@mock.patch.object(driver_base, 'SenlinDriver')
|
||||
def test_get_trust_not_exists(self, mock_senlindriver, mock_cred_create,
|
||||
mock_cred_get, mock_get_service_context):
|
||||
mock_cred_get.return_value = None
|
||||
mock_get_service_context.return_value = {'k1': 'v1', 'k2': 'v2'}
|
||||
sd = mock.Mock()
|
||||
kc = mock.Mock()
|
||||
sd.identity.return_value = kc
|
||||
mock_senlindriver.return_value = sd
|
||||
kc.get_user_id.return_value = 'FAKE_ADMIN_ID'
|
||||
kc.trust_get_by_trustor.side_effect = exception.InternalError(
|
||||
code=400, message='Bad request')
|
||||
trust = mock.Mock()
|
||||
kc.trust_create.return_value = trust
|
||||
trust.id = 'FAKE_TRUST_ID'
|
||||
result = self.middleware._get_trust(self.context)
|
||||
|
||||
trust_id = self.middleware._get_trust(self.context)
|
||||
self.assertEqual(trust_id, 'FAKE_TRUST_ID')
|
||||
self.assertTrue(db_api.cred_get.called)
|
||||
self.assertTrue(kc.get_user_id.called)
|
||||
self.assertTrue(kc.trust_get_by_trustor.called)
|
||||
self.assertTrue(kc.trust_create.called)
|
||||
self.assertTrue(db_api.cred_create.called)
|
||||
self.assertEqual('FAKE_TRUST_ID', result)
|
||||
mock_rpc.assert_called_once_with()
|
||||
x_rpc.credential_get.assert_called_once_with(self.context)
|
||||
|
||||
@mock.patch.object(context, "get_service_context")
|
||||
@mock.patch("senlin.drivers.base.SenlinDriver")
|
||||
@mock.patch("senlin.rpc.client.EngineClient")
|
||||
def test__get_trust_bad(self, mock_rpc, mock_driver, mock_context):
|
||||
x_cred = {'foo': 'bar'}
|
||||
x_rpc = mock.Mock()
|
||||
x_rpc.credential_get.return_value = x_cred
|
||||
mock_rpc.return_value = x_rpc
|
||||
|
||||
x_svc_cred = {'uid': 'FAKE_ID', 'passwd': 'FAKE_PASS'}
|
||||
mock_context.return_value = x_svc_cred
|
||||
x_admin_id = 'FAKE_ADMIN_ID'
|
||||
x_trust = mock.Mock(id='FAKE_TRUST_ID')
|
||||
mock_keystone = mock.Mock()
|
||||
mock_keystone.get_user_id.return_value = x_admin_id
|
||||
mock_keystone.trust_get_by_trustor.return_value = x_trust
|
||||
x_driver = mock.Mock()
|
||||
x_driver.identity.return_value = mock_keystone
|
||||
mock_driver.return_value = x_driver
|
||||
|
||||
result = self.middleware._get_trust(self.context)
|
||||
|
||||
self.assertEqual('FAKE_TRUST_ID', result)
|
||||
mock_rpc.assert_called_once_with()
|
||||
x_rpc.credential_get.assert_called_once_with(self.context)
|
||||
mock_driver.assert_called_once_with()
|
||||
x_driver.identity.assert_called_once_with({
|
||||
'auth_url': self.context.auth_url,
|
||||
'project_id': self.context.project,
|
||||
'user_id': self.context.user,
|
||||
'token': self.context.auth_token,
|
||||
})
|
||||
mock_context.assert_called_once_with()
|
||||
mock_keystone.get_user_id.assert_called_once_with(
|
||||
uid='FAKE_ID', passwd='FAKE_PASS')
|
||||
mock_keystone.trust_get_by_trustor.assert_called_once_with(
|
||||
self.context.user, 'FAKE_ADMIN_ID', self.context.project)
|
||||
x_rpc.credential_update.assert_called_once_with(
|
||||
self.context, 'FAKE_TRUST_ID')
|
||||
|
||||
@mock.patch.object(context, "get_service_context")
|
||||
@mock.patch("senlin.drivers.base.SenlinDriver")
|
||||
@mock.patch("senlin.rpc.client.EngineClient")
|
||||
def test__get_trust_not_found(self, mock_rpc, mock_driver, mock_context):
|
||||
x_rpc = mock.Mock()
|
||||
x_rpc.credential_get.return_value = None
|
||||
mock_rpc.return_value = x_rpc
|
||||
|
||||
x_svc_cred = {'uid': 'FAKE_ID', 'passwd': 'FAKE_PASS'}
|
||||
mock_context.return_value = x_svc_cred
|
||||
x_admin_id = 'FAKE_ADMIN_ID'
|
||||
x_trust = mock.Mock(id='FAKE_TRUST_ID')
|
||||
mock_keystone = mock.Mock()
|
||||
mock_keystone.get_user_id.return_value = x_admin_id
|
||||
mock_keystone.trust_get_by_trustor.return_value = x_trust
|
||||
x_driver = mock.Mock()
|
||||
x_driver.identity.return_value = mock_keystone
|
||||
mock_driver.return_value = x_driver
|
||||
|
||||
result = self.middleware._get_trust(self.context)
|
||||
|
||||
self.assertEqual('FAKE_TRUST_ID', result)
|
||||
mock_rpc.assert_called_once_with()
|
||||
x_rpc.credential_get.assert_called_once_with(self.context)
|
||||
mock_driver.assert_called_once_with()
|
||||
x_driver.identity.assert_called_once_with({
|
||||
'auth_url': self.context.auth_url,
|
||||
'project_id': self.context.project,
|
||||
'user_id': self.context.user,
|
||||
'token': self.context.auth_token,
|
||||
})
|
||||
mock_context.assert_called_once_with()
|
||||
mock_keystone.get_user_id.assert_called_once_with(
|
||||
uid='FAKE_ID', passwd='FAKE_PASS')
|
||||
mock_keystone.trust_get_by_trustor.assert_called_once_with(
|
||||
self.context.user, 'FAKE_ADMIN_ID', self.context.project)
|
||||
x_rpc.credential_create.assert_called_once_with(
|
||||
self.context, 'FAKE_TRUST_ID')
|
||||
|
||||
@mock.patch.object(context, "get_service_context")
|
||||
@mock.patch("senlin.drivers.base.SenlinDriver")
|
||||
@mock.patch("senlin.rpc.client.EngineClient")
|
||||
def test__get_trust_do_create(self, mock_rpc, mock_driver, mock_context):
|
||||
x_rpc = mock.Mock()
|
||||
x_rpc.credential_get.return_value = None
|
||||
mock_rpc.return_value = x_rpc
|
||||
|
||||
x_svc_cred = {'uid': 'FAKE_ID', 'passwd': 'FAKE_PASS'}
|
||||
mock_context.return_value = x_svc_cred
|
||||
x_admin_id = 'FAKE_ADMIN_ID'
|
||||
mock_keystone = mock.Mock()
|
||||
mock_keystone.get_user_id.return_value = x_admin_id
|
||||
x_trust = mock.Mock(id='FAKE_TRUST_ID')
|
||||
mock_keystone.trust_create.return_value = x_trust
|
||||
err = exception.InternalError(code=400, message='Boom')
|
||||
mock_keystone.trust_get_by_trustor.side_effect = err
|
||||
x_driver = mock.Mock()
|
||||
x_driver.identity.return_value = mock_keystone
|
||||
mock_driver.return_value = x_driver
|
||||
|
||||
result = self.middleware._get_trust(self.context)
|
||||
|
||||
self.assertEqual('FAKE_TRUST_ID', result)
|
||||
mock_rpc.assert_called_once_with()
|
||||
x_rpc.credential_get.assert_called_once_with(self.context)
|
||||
mock_driver.assert_called_once_with()
|
||||
x_driver.identity.assert_called_once_with({
|
||||
'auth_url': self.context.auth_url,
|
||||
'project_id': self.context.project,
|
||||
'user_id': self.context.user,
|
||||
'token': self.context.auth_token,
|
||||
})
|
||||
mock_context.assert_called_once_with()
|
||||
mock_keystone.get_user_id.assert_called_once_with(
|
||||
uid='FAKE_ID', passwd='FAKE_PASS')
|
||||
mock_keystone.trust_get_by_trustor.assert_called_once_with(
|
||||
self.context.user, 'FAKE_ADMIN_ID', self.context.project)
|
||||
mock_keystone.trust_create.assert_called_once_with(
|
||||
self.context.user, 'FAKE_ADMIN_ID', self.context.project,
|
||||
self.context.roles)
|
||||
x_rpc.credential_create.assert_called_once_with(
|
||||
self.context, 'FAKE_TRUST_ID')
|
||||
|
||||
@mock.patch.object(context, "get_service_context")
|
||||
@mock.patch("senlin.drivers.base.SenlinDriver")
|
||||
@mock.patch("senlin.rpc.client.EngineClient")
|
||||
def test__get_trust_fatal(self, mock_rpc, mock_driver, mock_context):
|
||||
x_rpc = mock.Mock()
|
||||
x_rpc.credential_get.return_value = None
|
||||
mock_rpc.return_value = x_rpc
|
||||
|
||||
x_svc_cred = {'uid': 'FAKE_ID', 'passwd': 'FAKE_PASS'}
|
||||
mock_context.return_value = x_svc_cred
|
||||
x_admin_id = 'FAKE_ADMIN_ID'
|
||||
mock_keystone = mock.Mock()
|
||||
mock_keystone.get_user_id.return_value = x_admin_id
|
||||
err = exception.InternalError(code=500, message='Boom')
|
||||
mock_keystone.trust_get_by_trustor.side_effect = err
|
||||
x_driver = mock.Mock()
|
||||
x_driver.identity.return_value = mock_keystone
|
||||
mock_driver.return_value = x_driver
|
||||
|
||||
ex = self.assertRaises(exception.InternalError,
|
||||
self.middleware._get_trust,
|
||||
self.context)
|
||||
|
||||
self.assertEqual('Boom', six.text_type(ex))
|
||||
mock_rpc.assert_called_once_with()
|
||||
x_rpc.credential_get.assert_called_once_with(self.context)
|
||||
mock_driver.assert_called_once_with()
|
||||
x_driver.identity.assert_called_once_with({
|
||||
'auth_url': self.context.auth_url,
|
||||
'project_id': self.context.project,
|
||||
'user_id': self.context.user,
|
||||
'token': self.context.auth_token,
|
||||
})
|
||||
mock_context.assert_called_once_with()
|
||||
mock_keystone.get_user_id.assert_called_once_with(
|
||||
uid='FAKE_ID', passwd='FAKE_PASS')
|
||||
mock_keystone.trust_get_by_trustor.assert_called_once_with(
|
||||
self.context.user, 'FAKE_ADMIN_ID', self.context.project)
|
||||
|
|
Loading…
Reference in New Issue