Fix Keystone url version suffix when webpath is present

There was a false assumption within utils.fix_auth_url_version()
routine that everything that goes after hostname:port part of Keystone
auth_url is could be only version suffix. Once '/identity' webpath was
enabled in Keystone Apache configuration in Devstack by default, the
falsehood was exposed and broken all integration tests. This is fixed.

While debugging fix_auth_url_version() I noticed another side-effect
of the fix: Horizon no longer needs to specify version suffix inside
OPENSTACK_KEYSTONE_URL setting, the fixed function works perfectly
without it. This will be mentioned in release notes for the dependent
Horizon patch.

Partial-Bug: #1585682
Needed-By: Icebfc291ec2b06ed84934c75cfd8c9d91cb2a895
Change-Id: Iea9b8e8378e6c5fb4c60df0073968d8caf7fbc5e
This commit is contained in:
Timur Sufiev 2016-05-26 19:07:36 +03:00
parent 086fc270fa
commit 405cb08207
2 changed files with 22 additions and 6 deletions

View File

@ -1139,6 +1139,10 @@ class UtilsTestCase(test.TestCase):
("http://a:8080/", "http://a:8080/v2.0"),
("http://a/v2.0", "http://a/v2.0"),
("http://a/v2.0/", "http://a/v2.0/"),
("http://a/identity", "http://a/identity/v2.0"),
("http://a/identity/", "http://a/identity/v2.0"),
("http://a:5000/identity/v2.0", "http://a:5000/identity/v2.0"),
("http://a/identity/v2.0/", "http://a/identity/v2.0/")
]
for src, expected in test_urls:
self.assertEqual(expected, utils.fix_auth_url_version(src))
@ -1153,6 +1157,10 @@ class UtilsTestCase(test.TestCase):
("http://a/v3/", "http://a/v3/"),
("http://a/v2.0/", "http://a/v3/"),
("http://a/v2.0", "http://a/v3"),
("http://a/identity", "http://a/identity/v3"),
("http://a:5000/identity/", "http://a:5000/identity/v3"),
("http://a/identity/v3", "http://a/identity/v3"),
("http://a/identity/v3/", "http://a/identity/v3/")
]
for src, expected in test_urls:
self.assertEqual(expected, utils.fix_auth_url_version(src))

View File

@ -262,14 +262,22 @@ def fix_auth_url_version(auth_url):
missing entirely. This should be smarter and use discovery.
"""
# Check for empty path component in endpoint URL and add keystone version
# to endpoint: as of Kilo, the identity URLs returned by Keystone might no
# longer contain API versions, leaving the version choice up to the user.
if urlparse.urlparse(auth_url).path.rstrip('/') == '':
# Check if path component already contains version suffix and if it does
# not, append version suffix to the end of path, not erasing the previous
# path contents, since keystone web endpoint (like /identity) could be
# there. Keystone version needs to be added to endpoint because as of Kilo,
# the identity URLs returned by Keystone might no longer contain API
# versions, leaving the version choice up to the user.
url_path = urlparse.urlparse(auth_url).path
if not re.search('/(v3|v2\.0)', url_path):
# Conditional delimiter to prevent leading double // in path section,
# which would overwrite hostname:port section when passed into urljoin
delimiter = '' if url_path.endswith('/') else '/'
if get_keystone_version() >= 3:
auth_url = urlparse.urljoin(auth_url, 'v3')
url_path += delimiter + 'v3'
else:
auth_url = urlparse.urljoin(auth_url, 'v2.0')
url_path += delimiter + 'v2.0'
auth_url = urlparse.urljoin(auth_url, url_path)
if get_keystone_version() >= 3:
if has_in_url_path(auth_url, "/v2.0"):