Add Keystone v3 domain information to context

Keystone v3 requires domain info to be supplied when
making calls to Keystone.  Not providing this means
that Cinder can't work with deployments that only
support Keystone v3.

(Specifically, this fails when trying to communicate
with Keystone/Barbican from Cinder.)

The domain information is retrieved from HTTP headers
provided by Keystone and stored in our context object.

This includes both "<x>_domain" and "<x>_domain_id"
in our context object, since castellan depends on
project_domain_id, but oslo.context has deprecated
project_domain and user_domain.

Closes-Bug: #1765766
Change-Id: If389788f06a3cee75b30485e90e05745d559e2ed
This commit is contained in:
Eric Harney 2018-04-20 11:36:12 -04:00
parent 8efee51cae
commit 6ddd7d8b75
3 changed files with 49 additions and 2 deletions

View File

@ -110,6 +110,18 @@ class CinderKeystoneContext(base_wsgi.Middleware):
LOG.debug("Neither X_USER_ID nor X_USER found in request")
return webob.exc.HTTPUnauthorized()
if req.environ.get('X_PROJECT_DOMAIN_ID'):
ctx.project_domain = req.environ['X_PROJECT_DOMAIN_ID']
if req.environ.get('X_PROJECT_DOMAIN_NAME'):
ctx.project_domain_name = req.environ['X_PROJECT_DOMAIN_NAME']
if req.environ.get('X_USER_DOMAIN_ID'):
ctx.user_domain = req.environ['X_USER_DOMAIN_ID']
if req.environ.get('X_USER_DOMAIN_NAME'):
ctx.user_domain_name = req.environ['X_USER_DOMAIN_NAME']
req.environ['cinder.context'] = ctx
return self.application

View File

@ -180,8 +180,11 @@ class RequestContext(context.RequestContext):
is_admin=values.get('is_admin'),
roles=values.get('roles'),
auth_token=values.get('auth_token'),
user_domain_id=values.get('user_domain_id'),
project_domain_id=values.get('project_domain_id'))
user_domain_id=values.get('user_domain'),
project_domain_id=values.get('project_domain'),
user_domain=values.get('user_domain'),
project_domain=values.get('project_domain'),
)
def authorize(self, action, target=None, target_obj=None, fatal=True):
"""Verifies that the given action is valid on the target in this context.

View File

@ -75,3 +75,35 @@ class TestCinderKeystoneContextMiddleware(test.TestCase):
self.request.environ[request_id.ENV_REQUEST_ID] = req_id
self.request.get_response(self.middleware)
self.assertEqual(req_id, self.context.request_id)
def test_request_project_domain_id(self):
self.request.headers['X_USER_ID'] = 'testuserid'
self.request.headers['X_PROJECT_DOMAIN_ID'] = 'domain1'
self.request.get_response(self.middleware)
self.assertEqual('domain1', self.context.project_domain)
def test_request_project_domain_name(self):
self.request.headers['X_USER_ID'] = 'testuserid'
self.request.headers['X_PROJECT_DOMAIN_NAME'] = 'mydomain'
self.request.get_response(self.middleware)
self.assertEqual('mydomain', self.context.project_domain_name)
def test_request_user_domain_id(self):
self.request.headers['X_USER_ID'] = 'testuserid'
self.request.headers['X_USER_DOMAIN_ID'] = 'domain2'
self.request.get_response(self.middleware)
self.assertEqual('domain2', self.context.user_domain)
def test_request_user_domain_name(self):
self.request.headers['X_USER_ID'] = 'testuserid'
self.request.headers['X_USER_DOMAIN_NAME'] = 'mydomain2'
self.request.get_response(self.middleware)
self.assertEqual('mydomain2', self.context.user_domain_name)