Enforce endpoint override for services without discovery

Services without version discovery implemented are tricky. When user is
not using endpoint_override for those there are sporadic and often
attempts to perform version discovery on every request sent [1]. It
could be prevented as much as possible on SDK side during proxy
initialization, but when a request is sent to the proxy this is still
happening inside the keystonauth library. Forcing endpoint_override for
those help avoiding that.

Touching cloud_region triggers mypy complain, so change urllib import to
keep it happy.

[1]
https://lists.openstack.org/archives/list/openstack-discuss@lists.openstack.org/thread/GBBHV2LN5S3HEUQHUQGZZ3UFEVRHQBOS/

Change-Id: I1956dfaac9ba8e3f9234cc98a36b20a330dc88f6
This commit is contained in:
gtema 2023-11-07 11:06:33 +01:00
parent 911cf7ddb1
commit 7fa802ca7f
2 changed files with 31 additions and 7 deletions

View File

@ -15,7 +15,7 @@
import copy
import os.path
import typing as ty
import urllib
from urllib import parse
import warnings
try:
@ -344,7 +344,7 @@ class CloudRegion:
def name(self):
if self._name is None:
try:
self._name = urllib.parse.urlparse(
self._name = parse.urlparse(
self.get_session().auth.auth_url
).hostname
except Exception:
@ -598,7 +598,7 @@ class CloudRegion:
interface=interface,
region_name=region_name,
)
except keystoneauth1.exceptions.catalog.EndpointNotFound:
except (keystoneauth1.exceptions.catalog.EndpointNotFound, ValueError):
return None
def get_connect_retries(self, service_type):
@ -813,7 +813,7 @@ class CloudRegion:
if not endpoint.rstrip().rsplit('/')[-1] == 'v2.0':
if not endpoint.endswith('/'):
endpoint += '/'
endpoint = urllib.parse.urljoin(endpoint, 'v2.0')
endpoint = parse.urljoin(endpoint, 'v2.0')
return endpoint
def get_session_client(

View File

@ -248,12 +248,36 @@ class ServiceDescription:
# Make an adapter to let discovery take over
version_kwargs = {}
supported_versions = sorted([int(f) for f in self.supported_versions])
if version_string:
version_kwargs['version'] = version_string
if getattr(
self.supported_versions[str(supported_versions[0])],
'skip_discovery',
False,
):
# Requested service does not support version discovery
# In this case it is more efficient to set the
# endpoint_override to the current catalog endpoint value,
# otherwise next request will try to perform discovery.
temp_adapter = config.get_session_client(self.service_type)
ep_override = temp_adapter.get_endpoint(skip_discovery=True)
ep_key = '{service_type}_endpoint_override'.format(
service_type=self.service_type.replace('-', '_')
)
config.config[ep_key] = ep_override
return config.get_session_client(
self.service_type,
allow_version_hack=True,
constructor=self.supported_versions[
str(supported_versions[0])
],
version=version_string,
)
else:
supported_versions = sorted(
[int(f) for f in self.supported_versions]
)
version_kwargs['min_version'] = str(supported_versions[0])
version_kwargs['max_version'] = '{version}.latest'.format(
version=str(supported_versions[-1])