d5149c9df0
While investigating an issue with us improperly determining the Identity endpoints between v2 and v3, it was mentioned several times that we should really be getting endpoints directly from the services, not from the service catalog. Part of this was a forward looking mention, as eventually services will be unversioned in the catalog. It's also a current issue as Identity themselves do not provide a v3 endpoint in the service catalog--only v2. This change introduces an implementation of Session.get_endpoint that uses the service catalog to get started, taking only the root of a service's endpoint, and then making a GET call to that root to find the versions and endpoints it is configured for. Once we've received the supported versions, we use somewhat of a fuzzy match to determine the exact endpoint. When a profile specifies v2 for a service, we'll look for the latest v2 offered, which could be v2.2 while it also offers v2.0 and v2.1. When a user asks specifically for v2.1, they will get exactly that. The one place we don't fuzzily match is across major versions, so if a user asks for a v3 but the service is only providing v2 at the moment, an exception will be raised. This adds an additional field to the ServiceFilter, requires_project_id, because there are some services that require a project id in their URI and some don't. We were apparently getting that straight from the service catalog before, but now we need services to tell us when they need it. Now for the special cases: * object_store doesn't help us with any of this. It still comes straight out of the service catalog. * some services only provide version fragments, not full URIs, so we need to reconstruct them to prepend the root. * identity nests the versions within another dictionary of "values" For any given combination of service_type and interface, a request to determine the versions is only made once. The endpoints are cached in a dictionary that is per-Connection instance. Change-Id: I0958ce5d7477da106890dc7770ac013d5b9098f6
42 lines
1.6 KiB
Python
42 lines
1.6 KiB
Python
# 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.
|
|
|
|
import testtools
|
|
|
|
from openstack.identity import identity_service
|
|
from openstack import service_filter
|
|
|
|
|
|
class TestValidVersion(testtools.TestCase):
|
|
def test_constructor(self):
|
|
sot = service_filter.ValidVersion('v1.0', 'v1')
|
|
self.assertEqual('v1.0', sot.module)
|
|
self.assertEqual('v1', sot.path)
|
|
|
|
|
|
class TestServiceFilter(testtools.TestCase):
|
|
def test_init(self):
|
|
sot = service_filter.ServiceFilter(
|
|
'ServiceType', region='REGION1', service_name='ServiceName',
|
|
version='1', api_version='1.23', requires_project_id=True)
|
|
self.assertEqual('servicetype', sot.service_type)
|
|
self.assertEqual('REGION1', sot.region)
|
|
self.assertEqual('ServiceName', sot.service_name)
|
|
self.assertEqual('1', sot.version)
|
|
self.assertEqual('1.23', sot.api_version)
|
|
self.assertTrue(sot.requires_project_id)
|
|
|
|
def test_get_module(self):
|
|
sot = identity_service.IdentityService()
|
|
self.assertEqual('openstack.identity.v3', sot.get_module())
|
|
self.assertEqual('identity', sot.get_service_module())
|