Fix Swift endpoint conversion to determine info/caps url

This adds some robustness and flexibility converting the Swift endpoint
URL from the registry to the one exposing the info / capabilities.
Additionally some unit tests were added to ensure different use-cases
and URL patterns are covered.

Story: 2010898
Task: 48689
Related-Bug: #1712358

Change-Id: I321ae9375d16e21771ee9d9bce1c61f85627c879
This commit is contained in:
Christian Rohmann 2023-08-29 14:36:45 +02:00
parent 21aade2f9b
commit 58476dec0e
3 changed files with 71 additions and 9 deletions

View File

@ -11,10 +11,12 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import re
import urllib import urllib
from openstack import exceptions from openstack import exceptions
from openstack import resource from openstack import resource
from openstack import utils
class Info(resource.Resource): class Info(resource.Resource):
@ -32,6 +34,24 @@ class Info(resource.Resource):
staticweb = resource.Body("staticweb", type=dict) staticweb = resource.Body("staticweb", type=dict)
tempurl = resource.Body("tempurl", type=dict) tempurl = resource.Body("tempurl", type=dict)
# The endpoint in the catalog has version and project-id in it
# To get capabilities, we have to disassemble and reassemble the URL
# to append 'info'
# This logic is taken from swiftclient
def _get_info_url(self, url):
URI_PATTERN_VERSION = re.compile(r'\/v\d+\.?\d*(\/.*)?')
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(
url
)
if URI_PATTERN_VERSION.search(path):
path = URI_PATTERN_VERSION.sub('/info', path)
else:
path = utils.urljoin(path, 'info')
return urllib.parse.urlunparse(
(scheme, netloc, path, params, query, fragment)
)
def fetch( def fetch(
self, self,
session, session,
@ -60,18 +80,11 @@ class Info(resource.Resource):
if not self.allow_fetch: if not self.allow_fetch:
raise exceptions.MethodNotSupported(self, "fetch") raise exceptions.MethodNotSupported(self, "fetch")
# The endpoint in the catalog has version and project-id in it
# To get capabilities, we have to disassemble and reassemble the URL
# This logic is taken from swiftclient
session = self._get_session(session) session = self._get_session(session)
endpoint = urllib.parse.urlparse(session.get_endpoint()) info_url = self._get_info_url(session.get_endpoint())
url = "{scheme}://{netloc}/info".format(
scheme=endpoint.scheme, netloc=endpoint.netloc
)
microversion = self._get_microversion(session, action='fetch') microversion = self._get_microversion(session, action='fetch')
response = session.get(url, microversion=microversion) response = session.get(info_url, microversion=microversion)
kwargs = {} kwargs = {}
if error_message: if error_message:
kwargs['error_message'] = error_message kwargs['error_message'] = error_message

View File

@ -0,0 +1,44 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.object_store.v1 import info
from openstack.tests.unit import base
class TestInfo(base.TestCase):
def setUp(self):
super(TestInfo, self).setUp()
def test_get_info_url(self):
sot = info.Info()
test_urls = {
'http://object.cloud.example.com': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/v1': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/v1/': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/swift': 'http://object.cloud.example.com/swift/info',
'http://object.cloud.example.com/swift/': 'http://object.cloud.example.com/swift/info',
'http://object.cloud.example.com/v1.0': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/swift/v1.0': 'http://object.cloud.example.com/swift/info',
'http://object.cloud.example.com/v111': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/v111/test': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/v1/test': 'http://object.cloud.example.com/info',
'http://object.cloud.example.com/swift/v1.0/test': 'http://object.cloud.example.com/swift/info',
'http://object.cloud.example.com/v1.0/test': 'http://object.cloud.example.com/info',
'https://object.cloud.example.com/swift/v1/AUTH_%(tenant_id)s': 'https://object.cloud.example.com/swift/info',
'https://object.cloud.example.com/swift/v1/AUTH_%(project_id)s': 'https://object.cloud.example.com/swift/info',
'https://object.cloud.example.com/services/swift/v1/AUTH_%(project_id)s': 'https://object.cloud.example.com/services/swift/info',
'https://object.cloud.example.com/services/swift/v1/AUTH_%(project_id)s/': 'https://object.cloud.example.com/services/swift/info',
'https://object.cloud.example.com/info/v1/AUTH_%(project_id)s/': 'https://object.cloud.example.com/info/info',
}
for uri_k, uri_v in test_urls.items():
self.assertEqual(sot._get_info_url(uri_k), uri_v)

View File

@ -0,0 +1,5 @@
---
fixes:
- |
[`bug 2010898 <https://storyboard.openstack.org/#!/story/2010898>`_]
Fix Swift endpoint url handling to determine info/caps url