Fix swift auth issue by specifying version in url

Swift client does not always handle unversioned identity URL
properly. Leading to authorization failure because keystone cannot
handle incorrect path, returning 404.

To work around the issue, congress swift driver
specifies the version in url if none is already provided.

Partial-Bug: 1677380

Change-Id: I8df7dac60e4f7cb3c2ec792e13f687d5844c8409
This commit is contained in:
Eric K 2018-02-06 19:23:53 -08:00
parent a52cfbdbad
commit c2df009018
3 changed files with 95 additions and 2 deletions

View File

@ -18,6 +18,7 @@ from __future__ import division
from __future__ import absolute_import
from oslo_log import log as logging
from six.moves.urllib.parse import urlparse
import swiftclient.service
from congress.datasources import constants
@ -27,6 +28,32 @@ from congress.datasources import datasource_utils as ds_utils
LOG = logging.getLogger(__name__)
def _append_path_to_url(url, version_str):
if len(url) == 0 or url[-1] != '/':
return url + '/' + version_str
else:
return url + version_str
def _auth_url_specifies_version(url):
url = str(url)
parsed_url = urlparse(url)
path_parts = parsed_url.path.split('/')
last_path_part = None
# find the last non-empty path part
for i in range(1, len(path_parts)):
if len(path_parts[-i]) > 0:
last_path_part = path_parts[-i]
break
if last_path_part is None:
return False
if last_path_part in ['v2.0', 'v2', 'v3']:
return True
return False
class SwiftDriver(datasource_driver.PollingDataSourceDriver,
datasource_driver.ExecutionDriver):
@ -64,8 +91,6 @@ class SwiftDriver(datasource_driver.PollingDataSourceDriver,
super(SwiftDriver, self).__init__(name, args=args)
datasource_driver.ExecutionDriver.__init__(self)
options = self.get_swift_credentials_v1(args)
# TODO(ramineni): Enable v3 support
options['os_auth_url'] = options['os_auth_url'].replace('v3', 'v2.0')
self.swift_service = swiftclient.service.SwiftService(options)
self.add_executable_client_methods(self.swift_service,
'swiftclient.service')
@ -94,6 +119,15 @@ class SwiftDriver(datasource_driver.PollingDataSourceDriver,
options['os_password'] = creds['password']
options['os_tenant_name'] = creds['tenant_name']
options['os_auth_url'] = creds['auth_url']
# Note(ekcs: swift does not always handle unversioned URL correctly,
# as a work-around, this driver appends 'v3' if no version provided
if (not _auth_url_specifies_version(url=options['os_auth_url']) and
len(options['os_auth_url']) != 0):
options['os_auth_url'] = _append_path_to_url(
options['os_auth_url'], 'v3')
options['auth_version'] = '3'
return options
def initialize_update_methods(self):

View File

@ -112,3 +112,54 @@ class TestSwiftDriver(base.TestCase):
self.driver.execute('updateObject', api_args)
self.assertEqual(expected_ans, swift_client.testkey)
def test_auth_url_specifies_version(self):
# False
self.assertEqual(
swift_driver._auth_url_specifies_version(''),
False)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/'),
False)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def'),
False)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/v1/'),
False)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/abc/'),
False)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/abc'),
False)
# True
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/v2/'),
True)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/v3'),
True)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/v2.0/'),
True)
self.assertEqual(
swift_driver._auth_url_specifies_version('http://abc.def/v2.0/'),
True)
def test_append_path_to_url(self):
# no ending slash
self.assertEqual(
swift_driver._append_path_to_url('http://abc.def/abc', 'v321'),
'http://abc.def/abc/v321')
# ending slash
self.assertEqual(
swift_driver._append_path_to_url('http://abc.def/abc/', 'v321'),
'http://abc.def/abc/v321')
# multiple ending slashes
self.assertEqual(
swift_driver._append_path_to_url('http://abc.def/abc///', 'v321'),
'http://abc.def/abc///v321')

View File

@ -0,0 +1,8 @@
---
prelude: >
fixes:
- Workaround added for an issue where Swift client,
and the Congress Swift driver using Swift client,
do not always handle unversioned auth URL correctly.
The workaround adds /v3 to the end of an unversioned
auth URL.