From f1804c443b1c8f825e1cf1d01a72de34cde63841 Mon Sep 17 00:00:00 2001 From: John Bresnahan Date: Thu, 21 Mar 2013 15:28:46 -1000 Subject: [PATCH] Remove internal store references from migration 017 Migration 017 was accessing a object internal to the swift store driver and changing its behavior in order to do the migration. This worked but it made the assumption that the driver logic would not change without also changing the migration code. This patch removes all dependencies on the swift driver from the migration code. This patch is smilar to https://review.openstack.org/#/c/24552/. Fixes bug: 1155749 Change-Id: Iffd800f62d61bf7608f7be5b23d76d702e6d4064 --- .../017_quote_encrypted_swift_credentials.py | 95 ++++++++++++------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py b/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py index 22fb690816..cffb58d28c 100644 --- a/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py +++ b/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py @@ -28,8 +28,8 @@ migration performs the following steps for every entry in the images table: Fixes bug #1081043 """ - import types +import urllib import urlparse from oslo.config import cfg @@ -112,15 +112,6 @@ def fix_uri_credentials(uri, to_quoted): """ if not uri: return - location = glance.store.swift.StoreLocation({}) - if to_quoted: - # The legacy parse_uri doesn't unquote credentials - location.parse_uri = types.MethodType(legacy_parse_uri, location) - else: - # The legacy _get_credstring doesn't quote credentials - location._get_credstring = types.MethodType(legacy__get_credstring, - location) - decrypted_uri = None try: decrypted_uri = decrypt_location(uri) #NOTE (ameade): If a uri is not encrypted or incorrectly encoded then we @@ -128,17 +119,10 @@ def fix_uri_credentials(uri, to_quoted): except (TypeError, ValueError) as e: raise exception.Invalid(str(e)) - location.parse_uri(decrypted_uri) - return encrypt_location(location.get_uri()) + return legacy_parse_uri(decrypted_uri, to_quoted) -def legacy__get_credstring(self): - if self.user: - return '%s:%s@' % (self.user, self.key) - return '' - - -def legacy_parse_uri(self, uri): +def legacy_parse_uri(uri, to_quote): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior @@ -146,6 +130,14 @@ def legacy_parse_uri(self, uri): Swift URIs have where a username can contain a ':', like so: swift://account:user:pass@authurl.com/container/obj + + If to_quoted is True, the uri is assumed to have credentials that + have not been quoted, and the resulting uri will contain quoted + credentials. + + If to_quoted is False, the uri is assumed to have credentials that + have been quoted, and the resulting uri will contain credentials + that have not been quoted. """ # Make sure that URIs that contain multiple schemes, such as: # swift://user:pass@http://authurl.com/v1/container/obj @@ -163,7 +155,7 @@ def legacy_parse_uri(self, uri): pieces = urlparse.urlparse(uri) assert pieces.scheme in ('swift', 'swift+http', 'swift+https') - self.scheme = pieces.scheme + scheme = pieces.scheme netloc = pieces.netloc path = pieces.path.lstrip('/') if netloc != '': @@ -187,29 +179,62 @@ def legacy_parse_uri(self, uri): # User can be account:user, in which case cred_parts[0:2] will be # the account and user. Combine them into a single username of # account:user - if len(cred_parts) == 1: - reason = (_("Badly formed credentials '%(creds)s' in Swift " - "URI") % locals()) - LOG.error(reason) - raise exception.BadStoreUri() - elif len(cred_parts) == 3: - user = ':'.join(cred_parts[0:2]) + if to_quote: + if len(cred_parts) == 1: + reason = (_("Badly formed credentials '%(creds)s' in Swift " + "URI") % locals()) + LOG.error(reason) + raise exception.BadStoreUri() + elif len(cred_parts) == 3: + user = ':'.join(cred_parts[0:2]) + else: + user = cred_parts[0] + key = cred_parts[-1] + user = user + key = key else: - user = cred_parts[0] - key = cred_parts[-1] - self.user = user - self.key = key + if len(cred_parts) != 2: + reason = (_("Badly formed credentials in Swift URI.")) + LOG.debug(reason) + raise exception.BadStoreUri() + user, key = cred_parts + user = urllib.unquote(user) + key = urllib.unquote(key) else: - self.user = None + user = None + key = None path_parts = path.split('/') try: - self.obj = path_parts.pop() - self.container = path_parts.pop() + obj = path_parts.pop() + container = path_parts.pop() if not netloc.startswith('http'): # push hostname back into the remaining to build full authurl path_parts.insert(0, netloc) - self.auth_or_store_url = '/'.join(path_parts) + auth_or_store_url = '/'.join(path_parts) except IndexError: reason = _("Badly formed S3 URI: %s") % uri LOG.error(message=reason) raise exception.BadStoreUri() + + if auth_or_store_url.startswith('http://'): + auth_or_store_url = auth_or_store_url[len('http://'):] + elif auth_or_store_url.startswith('https://'): + auth_or_store_url = auth_or_store_url[len('https://'):] + + credstring = '' + if user and key: + if to_quote: + quote_user = urllib.quote(user) + quote_key = urllib.quote(key) + else: + quote_user = user + quote_key = key + credstring = '%s:%s@' % (quote_user, quote_key) + + auth_or_store_url = auth_or_store_url.strip('/') + container = container.strip('/') + obj = obj.strip('/') + + uri = '%s://%s%s/%s/%s' % (scheme, credstring, auth_or_store_url, + container, obj) + return encrypt_location(uri)