Skip to content

Commit f5f83c6

Browse files
committed
Add use_dynamic_reseller_names param to keystoneauth
If your using auth version 3 and want to have an account based of the name of the project, then you can enable ``use_dynamic_reseller_name`` in conjuction with ``use_dynamic_reseller`` to do so. The form used for the account would be:: <reseller_prefix><project_domain_name>_<project_name> Given a reseller_preix of 'AUTH_' as project_domain_name of 'Domain' and a project name of 'Demo', this would generate:: AUTH_Domain_Demo NOTE: however, that if you ever change the domain or project name then users accounts will change, loosing access to their old data, and a large serverside copy would need to happen. This feature however is really useful for federated environments however. Change-Id: Ifad4526d09a4d29389594562fd7ca994125cdc37
1 parent 2d25fc4 commit f5f83c6

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

Diff for: swift/common/middleware/keystoneauth.py

+32-3
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,23 @@ class KeystoneAuth(object):
188188
189189
use_dynamic_reseller = true
190190
191+
If your using auth version 3 and want to have an account based of the
192+
name of the project, then you can enable ``use_dynamic_reseller_name``
193+
in conjuction with ``use_dynamic_reseller`` to do so. The form used
194+
for the account would be::
195+
196+
<reseller_prefix><project_domain_name>_<project_name>
197+
198+
Given a reseller_preix of 'AUTH_' as project_domain_name of 'Domain' and
199+
a project name of 'Demo', this would generate::
200+
201+
AUTH_Domain_Demo
202+
203+
NOTE: however, that if you ever change the domain or project name then
204+
users accounts will change, loosing access to their old data, and
205+
a large serverside copy would need to happen.
206+
This feature however is really useful for federated environments however.
207+
191208
:param app: The next WSGI app in the pipeline
192209
:param conf: The dict of configuration values
193210
"""
@@ -215,6 +232,8 @@ def __init__(self, app, conf):
215232
conf.get('allow_names_in_acls', 'true'))
216233
self.use_dynamic_reseller = swift_utils.config_true_value(
217234
conf.get('use_dynamic_reseller', 'false'))
235+
self.use_dynamic_reseller_names = swift_utils.config_true_value(
236+
conf.get('use_dynamic_reseller_names', 'false'))
218237

219238
def __call__(self, environ, start_response):
220239
env_identity = self._keystone_identity(environ)
@@ -292,16 +311,26 @@ def _keystone_identity(self, environ):
292311
identity['auth_version'] = auth_version
293312
return identity
294313

295-
def _set_dynamic_name(self, environ, env_identity):
314+
def _set_dynamic_name(self, environ, identity):
296315
try:
297316
part = Request(environ).split_path(2, 4, True)
298317
version, account, container, obj = part
299318
except ValueError:
300319
return
301320

302321
if account and account in self.reseller_prefixes:
303-
path = "/%s/%s%s" % (version, account,
304-
env_identity['tenant'][0])
322+
if self.use_dynamic_reseller_names and \
323+
identity['auth_version'] == 3:
324+
account = "%s%s_%s" % (account, identity['project_domain'][1],
325+
identity['tenant'][1])
326+
elif self.use_dynamic_reseller_names:
327+
self.logger.error('use_dynamic_reseller_names only available '
328+
'when using auth v3.')
329+
return
330+
else:
331+
account = "%s%s" % (account, identity['tenant'][0])
332+
333+
path = "/%s/%s" % (version, account)
305334
if container:
306335
path = "%s/%s" % (path, container)
307336
if obj:

Diff for: test/unit/common/middleware/test_keystoneauth.py

+37
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,43 @@ def test(path, expected_path):
364364
for params in tests:
365365
test(**params)
366366

367+
def test_use_dynamic_reseller_name(self):
368+
reseller_prefix = self.test_auth.reseller_prefixes[0]
369+
self.test_auth.use_dynamic_reseller = True
370+
self.test_auth.use_dynamic_reseller_names = True
371+
headers = get_identity_headers()
372+
373+
374+
def test(path, expected_path, env):
375+
self.test_auth.logger = FakeLogger()
376+
req = self._make_request(path=path, headers=headers, environ=env)
377+
resp = req.get_response(self.test_auth)
378+
self.assertEqual(resp.request.path, expected_path)
379+
if path == expected_path:
380+
errors = self.test_auth.logger.get_lines_for_level('error')
381+
self.assertIn(('use_dynamic_reseller_names only available '
382+
'when using auth v3.'), errors)
383+
384+
# first run with auth_version 0 (ie no keystone.token_info)
385+
test(path='/v1/%s/c/o' % reseller_prefix,
386+
expected_path='/v1/%s/c/o' % reseller_prefix,
387+
env=None)
388+
389+
# Next run with auth_version 2
390+
environ = {'keystone.token_info': _fake_token_info(version='2')}
391+
test(path='/v1/%s/c/o' % reseller_prefix,
392+
expected_path='/v1/%s/c/o' % reseller_prefix,
393+
env=environ)
394+
395+
# Next run with auth_version 3 - this should succeed
396+
import pudb; pudb.set_trace()
397+
environ = {'keystone.token_info': _fake_token_info(version='3')}
398+
test(path='/v1/%s/c/o' % reseller_prefix,
399+
expected_path='/v1/%s%s_%s/c/o' % (
400+
reseller_prefix, headers['X_PROJECT_DOMAIN_NAME'],
401+
headers['X_TENANT_NAME']),
402+
env=environ)
403+
367404

368405
class SwiftAuthMultiple(SwiftAuth):
369406
"""Runs same tests as SwiftAuth with multiple reseller prefixes

0 commit comments

Comments
 (0)