From 7fa802ca7fd32c9385d476f0713191f6f2bc4153 Mon Sep 17 00:00:00 2001 From: gtema Date: Tue, 7 Nov 2023 11:06:33 +0100 Subject: [PATCH] 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 --- openstack/config/cloud_region.py | 8 ++++---- openstack/service_description.py | 30 +++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/openstack/config/cloud_region.py b/openstack/config/cloud_region.py index ee16dd612..4ba3daa57 100644 --- a/openstack/config/cloud_region.py +++ b/openstack/config/cloud_region.py @@ -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( diff --git a/openstack/service_description.py b/openstack/service_description.py index eab27a88f..efe1e783b 100644 --- a/openstack/service_description.py +++ b/openstack/service_description.py @@ -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])