Record the discovered major api version
With the addition of input ranges for versions it's important for the user to be able to know what version was discovered. This is already in the EndpointData model as "api_version" - the value was just never populated. In cases where an Endpoint has been discovered and the user has an EndpointData that now correctly stores the api_version of the discovered endpoint, and where that user now wants to get microversion metadata, getting rid of api_version as an input to get_versoined_data made it awkward to fetch metadata about the already discovered endpoint. Add a method so that the user can say "please run discovery on this endpoint to fill in the data, don't look for different endpoints, and don't make me do the api-version -> min/max transformation myself". Change-Id: I3031d1eb0967eaa8b911e8e8a06ba722f9e69063
This commit is contained in:
parent
928dd259ea
commit
5268d00218
|
@ -376,6 +376,19 @@ def _combine_relative_url(discovery_url, version_url):
|
|||
return urllib.parse.urlparse(url).geturl()
|
||||
|
||||
|
||||
def _version_from_url(url):
|
||||
if not url:
|
||||
return url
|
||||
|
||||
url = urllib.parse.urlparse(url)
|
||||
for part in reversed(url.path.split('/')):
|
||||
try:
|
||||
return normalize_version_number(part)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
class Discover(object):
|
||||
|
||||
CURRENT_STATUSES = ('stable', 'current', 'supported')
|
||||
|
@ -686,7 +699,6 @@ class EndpointData(object):
|
|||
self.region_name = region_name
|
||||
self.endpoint_id = endpoint_id
|
||||
self.raw_endpoint = raw_endpoint
|
||||
self.api_version = api_version
|
||||
self.major_version = major_version
|
||||
self.min_microversion = min_microversion
|
||||
self.max_microversion = max_microversion
|
||||
|
@ -697,6 +709,8 @@ class EndpointData(object):
|
|||
self._catalog_matches_exactly = False
|
||||
self._disc = None
|
||||
|
||||
self.api_version = api_version or _version_from_url(self.url)
|
||||
|
||||
def __copy__(self):
|
||||
"""Return a new EndpointData based on this one."""
|
||||
new_data = EndpointData(
|
||||
|
@ -725,6 +739,41 @@ class EndpointData(object):
|
|||
def url(self):
|
||||
return self.service_url or self.catalog_url
|
||||
|
||||
@positional(3)
|
||||
def get_current_versioned_data(self, session, allow=None, cache=None,
|
||||
project_id=None):
|
||||
"""Run version discovery on the current endpoint.
|
||||
|
||||
A simplified version of get_versioned_data, get_current_versioned_data
|
||||
runs discovery but only on the endpoint that has been found already.
|
||||
|
||||
It can be useful in some workflows where the user wants version
|
||||
information about the endpoint they have.
|
||||
|
||||
:param session: A session object that can be used for communication.
|
||||
:type session: keystoneauth1.session.Session
|
||||
:param dict allow: Extra filters to pass when discovering API
|
||||
versions. (optional)
|
||||
:param dict cache: A dict to be used for caching results in
|
||||
addition to caching them on the Session.
|
||||
(optional)
|
||||
:param string project_id: ID of the currently scoped project. Used for
|
||||
removing project_id components of URLs from
|
||||
the catalog. (optional)
|
||||
|
||||
:returns: A new EndpointData with the requested versioned data.
|
||||
:rtype: :py:class:`keystoneauth1.discover.EndpointData`
|
||||
:raises keystoneauth1.exceptions.discovery.DiscoveryFailure: If the
|
||||
appropriate versioned data
|
||||
could not be discovered.
|
||||
"""
|
||||
min_version, max_version = _normalize_version_args(
|
||||
self.api_version, None, None)
|
||||
return self.get_versioned_data(
|
||||
session=session, allow=allow, cache=cache, allow_version_hack=True,
|
||||
discover_versions=True,
|
||||
min_version=min_version, max_version=max_version)
|
||||
|
||||
@positional(3)
|
||||
def get_versioned_data(self, session, allow=None, cache=None,
|
||||
allow_version_hack=True, project_id=None,
|
||||
|
@ -843,6 +892,7 @@ class EndpointData(object):
|
|||
self.max_microversion = discovered_data['max_microversion']
|
||||
self.next_min_version = discovered_data['next_min_version']
|
||||
self.not_before = discovered_data['not_before']
|
||||
self.api_version = discovered_data['version']
|
||||
|
||||
# TODO(mordred): these next two things should be done by Discover
|
||||
# in versioned_data_for.
|
||||
|
|
|
@ -499,6 +499,8 @@ class CommonIdentityTests(object):
|
|||
interface='admin')
|
||||
|
||||
self.assertEqual(self.TEST_COMPUTE_ADMIN + '/v3', data.url)
|
||||
# We should have gotten the version from the URL
|
||||
self.assertEqual((3, 0), data.api_version)
|
||||
|
||||
def test_endpoint_data_no_version_no_discovery(self):
|
||||
a = self.create_auth_plugin()
|
||||
|
@ -510,6 +512,22 @@ class CommonIdentityTests(object):
|
|||
discover_versions=False)
|
||||
|
||||
self.assertEqual(self.TEST_COMPUTE_ADMIN, data.url)
|
||||
# There's no version in the URL and no document - we have no idea
|
||||
self.assertEqual(None, data.api_version)
|
||||
|
||||
def test_endpoint_data_version_url_no_discovery(self):
|
||||
a = self.create_auth_plugin()
|
||||
s = session.Session(auth=a)
|
||||
|
||||
data = a.get_endpoint_data(session=s,
|
||||
service_type='volumev3',
|
||||
interface='admin',
|
||||
discover_versions=False)
|
||||
|
||||
self.assertEqual(
|
||||
self.TEST_VOLUME.versions['v3'].service.admin, data.url)
|
||||
# There's v3 in the URL
|
||||
self.assertEqual((3, 0), data.api_version)
|
||||
|
||||
def test_endpoint_no_version(self):
|
||||
a = self.create_auth_plugin()
|
||||
|
@ -589,6 +607,37 @@ class CommonIdentityTests(object):
|
|||
self.assertEqual(v3_compute, v3_data.service_url)
|
||||
self.assertEqual(self.TEST_COMPUTE_ADMIN, v3_data.catalog_url)
|
||||
|
||||
def test_get_current_versioned_data(self):
|
||||
v2_compute = self.TEST_COMPUTE_ADMIN + '/v2.0'
|
||||
v3_compute = self.TEST_COMPUTE_ADMIN + '/v3'
|
||||
|
||||
disc = fixture.DiscoveryList(v2=False, v3=False)
|
||||
disc.add_v2(v2_compute)
|
||||
disc.add_v3(v3_compute)
|
||||
|
||||
# Make sure that we don't do more than one discovery call
|
||||
# register responses such that if the discovery URL is hit more than
|
||||
# once then the response will be invalid and not point to COMPUTE_ADMIN
|
||||
resps = [{'json': disc}, {'status_code': 500}]
|
||||
self.requests_mock.get(self.TEST_COMPUTE_ADMIN, resps)
|
||||
|
||||
a = self.create_auth_plugin()
|
||||
s = session.Session(auth=a)
|
||||
|
||||
data = a.get_endpoint_data(session=s,
|
||||
service_type='compute',
|
||||
interface='admin')
|
||||
self.assertEqual(v3_compute, data.url)
|
||||
|
||||
v3_data = data.get_current_versioned_data(s)
|
||||
|
||||
self.assertEqual(v3_compute, v3_data.url)
|
||||
self.assertEqual(v3_compute, v3_data.service_url)
|
||||
self.assertEqual(self.TEST_COMPUTE_ADMIN, v3_data.catalog_url)
|
||||
self.assertEqual((3, 0), v3_data.api_version)
|
||||
self.assertEqual(None, v3_data.min_microversion)
|
||||
self.assertEqual(None, v3_data.max_microversion)
|
||||
|
||||
def test_interface_list(self):
|
||||
|
||||
a = self.create_auth_plugin()
|
||||
|
@ -932,8 +981,9 @@ class CommonIdentityTests(object):
|
|||
|
||||
data = sess.get_endpoint_data(service_type='network')
|
||||
|
||||
# Discovery ran and returned the URL
|
||||
# Discovery ran and returned the URL and its version
|
||||
self.assertEqual(url, data.url)
|
||||
self.assertEqual((2, 1), data.api_version)
|
||||
|
||||
# Run with a project_id to ensure that path is covered
|
||||
self.assertEqual(
|
||||
|
@ -1213,6 +1263,7 @@ class CatalogHackTests(utils.TestCase):
|
|||
self.assertEqual(self.OTHER_URL, data.url)
|
||||
self.assertEqual((2, 1), data.min_microversion)
|
||||
self.assertEqual((2, 35), data.max_microversion)
|
||||
self.assertEqual((2, 1), data.api_version)
|
||||
|
||||
def test_forcing_discovery(self):
|
||||
v2_disc = fixture.V2Discovery(self.V2_URL)
|
||||
|
@ -1260,6 +1311,7 @@ class CatalogHackTests(utils.TestCase):
|
|||
|
||||
# got v2 url
|
||||
self.assertEqual(self.V2_URL, data.url)
|
||||
self.assertEqual((2, 0), data.api_version)
|
||||
|
||||
def test_forcing_discovery_list_returns_url(self):
|
||||
common_disc = fixture.DiscoveryList(href=self.BASE_URL)
|
||||
|
@ -1304,6 +1356,7 @@ class CatalogHackTests(utils.TestCase):
|
|||
|
||||
# got v2 url
|
||||
self.assertEqual(self.V2_URL, data.url)
|
||||
self.assertEqual((2, 0), data.api_version)
|
||||
|
||||
def test_latest_version_gets_latest_version(self):
|
||||
common_disc = fixture.DiscoveryList(href=self.BASE_URL)
|
||||
|
@ -1489,6 +1542,7 @@ class CatalogHackTests(utils.TestCase):
|
|||
self.assertEqual(self.OTHER_URL, data.url)
|
||||
self.assertEqual((2, 1), data.min_microversion)
|
||||
self.assertEqual((2, 35), data.max_microversion)
|
||||
self.assertEqual((2, 1), data.api_version)
|
||||
|
||||
def test_get_endpoint_data_compute(self):
|
||||
common_disc = fixture.DiscoveryList(v2=False, v3=False)
|
||||
|
@ -1530,6 +1584,7 @@ class CatalogHackTests(utils.TestCase):
|
|||
self.assertEqual(self.OTHER_URL, data.url)
|
||||
self.assertEqual((2, 1), data.min_microversion)
|
||||
self.assertEqual((2, 35), data.max_microversion)
|
||||
self.assertEqual((2, 1), data.api_version)
|
||||
|
||||
def test_getting_endpoints_on_auth_interface(self):
|
||||
disc = fixture.DiscoveryList(href=self.BASE_URL)
|
||||
|
|
Loading…
Reference in New Issue