Add ability to filter version data by service-type

The get_all_version_data method is useful for getting a full listing of
what's going on with version discovery on a cloud. Sometimes though
people just want to see the versions for a specific service. Add a
filter to allow skipping making the version discovery call in the first
place, instead of needing to do that as a post-filtering step.

Change-Id: Ia3ca4be2976d1a5e7914fa8f2adbf7297e8cb1e1
This commit is contained in:
Monty Taylor 2018-07-23 15:35:35 -05:00
parent 51bfa030b1
commit 83be7453fa
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
5 changed files with 199 additions and 8 deletions

View File

@ -267,6 +267,29 @@ class Adapter(object):
return self.session.get_endpoint_data(auth or self.auth, **kwargs) return self.session.get_endpoint_data(auth or self.auth, **kwargs)
def get_all_version_data(
self,
interface='public',
region_name=None):
"""Get data about all versions of a service.
:param interface:
Type of endpoint to get version data for. Can be a single value
or a list of values. A value of None indicates that all interfaces
should be queried. (optional, defaults to public)
:param string region_name:
Region of endpoints to get version data for. A valueof None
indicates that all regions should be queried. (optional, defaults
to None)
:returns: A dictionary keyed by region_name with values containing
dictionaries keyed by interface with values being a list of
:class:`~keystoneauth1.discover.VersionData`.
"""
return self.session.get_all_version_data(
interface=interface,
region_name=region_name,
service_type=self.service_type)
def get_api_major_version(self, auth=None, **kwargs): def get_api_major_version(self, auth=None, **kwargs):
"""Get the major API version as provided by the auth plugin. """Get the major API version as provided by the auth plugin.

View File

@ -509,7 +509,8 @@ class BaseIdentityPlugin(plugin.BaseAuthPlugin):
return data.api_version return data.api_version
def get_all_version_data(self, session, interface='public', def get_all_version_data(self, session, interface='public',
region_name=None, **kwargs): region_name=None, service_type=None,
**kwargs):
"""Get version data for all services in the catalog. """Get version data for all services in the catalog.
:param session: A session object that can be used for communication. :param session: A session object that can be used for communication.
@ -522,6 +523,9 @@ class BaseIdentityPlugin(plugin.BaseAuthPlugin):
Region of endpoints to get version data for. A valueof None Region of endpoints to get version data for. A valueof None
indicates that all regions should be queried. (optional, defaults indicates that all regions should be queried. (optional, defaults
to None) to None)
:param string service_type:
Limit the version data to a single service. (optional, defaults
to None)
:returns: A dictionary keyed by region_name with values containing :returns: A dictionary keyed by region_name with values containing
dictionaries keyed by interface with values being a list of dictionaries keyed by interface with values being a list of
:class:`~keystoneauth1.discover.VersionData`. :class:`~keystoneauth1.discover.VersionData`.
@ -530,11 +534,16 @@ class BaseIdentityPlugin(plugin.BaseAuthPlugin):
catalog = self.get_access(session).service_catalog catalog = self.get_access(session).service_catalog
version_data = {} version_data = {}
endpoints_data = catalog.get_endpoints_data( endpoints_data = catalog.get_endpoints_data(
interface=interface, region_name=region_name) interface=interface,
region_name=region_name,
service_type=service_type,
)
for endpoint_service_type, services in endpoints_data.items():
if service_types.is_known(endpoint_service_type):
endpoint_service_type = service_types.get_service_type(
endpoint_service_type)
for service_type, services in endpoints_data.items():
if service_types.is_known(service_type):
service_type = service_types.get_service_type(service_type)
for service in services: for service in services:
versions = service.get_all_version_string_data( versions = service.get_all_version_string_data(
session=session, session=session,
@ -548,7 +557,7 @@ class BaseIdentityPlugin(plugin.BaseAuthPlugin):
interface = service.interface.rstrip('URL') interface = service.interface.rstrip('URL')
if interface not in regions: if interface not in regions:
regions[interface] = {} regions[interface] = {}
regions[interface][service_type] = versions regions[interface][endpoint_service_type] = versions
return version_data return version_data

View File

@ -1146,7 +1146,8 @@ class Session(object):
return auth.get_api_major_version(self, **kwargs) return auth.get_api_major_version(self, **kwargs)
def get_all_version_data(self, auth=None, interface='public', def get_all_version_data(self, auth=None, interface='public',
region_name=None, **kwargs): region_name=None, service_type=None,
**kwargs):
"""Get version data for all services in the catalog. """Get version data for all services in the catalog.
:param auth: :param auth:
@ -1161,13 +1162,20 @@ class Session(object):
Region of endpoints to get version data for. A valueof None Region of endpoints to get version data for. A valueof None
indicates that all regions should be queried. (optional, defaults indicates that all regions should be queried. (optional, defaults
to None) to None)
:param string service_type:
Limit the version data to a single service. (optional, defaults
to None)
:returns: A dictionary keyed by region_name with values containing :returns: A dictionary keyed by region_name with values containing
dictionaries keyed by interface with values being a list of dictionaries keyed by interface with values being a list of
`~keystoneauth1.discover.VersionData`. `~keystoneauth1.discover.VersionData`.
""" """
auth = self._auth_required(auth, 'determine endpoint URL') auth = self._auth_required(auth, 'determine endpoint URL')
return auth.get_all_version_data( return auth.get_all_version_data(
self, interface=interface, region_name=region_name, **kwargs) self,
interface=interface,
region_name=region_name,
service_type=service_type,
**kwargs)
def get_auth_connection_params(self, auth=None, **kwargs): def get_auth_connection_params(self, auth=None, **kwargs):
"""Return auth connection params as provided by the auth plugin. """Return auth connection params as provided by the auth plugin.

View File

@ -19,6 +19,7 @@ from six.moves import urllib
from keystoneauth1 import _utils from keystoneauth1 import _utils
from keystoneauth1 import access from keystoneauth1 import access
from keystoneauth1 import adapter
from keystoneauth1 import discover from keystoneauth1 import discover
from keystoneauth1 import exceptions from keystoneauth1 import exceptions
from keystoneauth1 import fixture from keystoneauth1 import fixture
@ -865,6 +866,148 @@ class CommonIdentityTests(object):
} }
}, data) }, data)
def test_get_all_version_data_by_service_type(self):
nova_disc = fixture.DiscoveryList(v2=False, v3=False)
nova_disc.add_microversion(
href=self.TEST_COMPUTE_PUBLIC, id='v2')
nova_disc.add_microversion(
href=self.TEST_COMPUTE_PUBLIC, id='v2.1',
min_version='2.1', max_version='2.35')
self.stub_url(
'GET', [], base_url=self.TEST_COMPUTE_PUBLIC, json=nova_disc)
a = self.create_auth_plugin()
s = session.Session(auth=a)
data = s.get_all_version_data(
interface='public',
service_type='compute')
self.assertEqual({
'RegionOne': {
'public': {
'compute': [{
'collection': None,
'max_microversion': None,
'min_microversion': None,
'next_min_version': None,
'not_before': None,
'raw_status': 'stable',
'status': 'CURRENT',
'url': 'https://compute.example.com/nova/public',
'version': '2.0'
}, {
'collection': None,
'max_microversion': '2.35',
'min_microversion': '2.1',
'next_min_version': None,
'not_before': None,
'raw_status': 'stable',
'status': 'CURRENT',
'url': 'https://compute.example.com/nova/public',
'version': '2.1'
}],
}
}
}, data)
def test_get_all_version_data_adapter(self):
nova_disc = fixture.DiscoveryList(v2=False, v3=False)
nova_disc.add_microversion(
href=self.TEST_COMPUTE_PUBLIC, id='v2')
nova_disc.add_microversion(
href=self.TEST_COMPUTE_PUBLIC, id='v2.1',
min_version='2.1', max_version='2.35')
self.stub_url(
'GET', [], base_url=self.TEST_COMPUTE_PUBLIC, json=nova_disc)
s = session.Session(auth=self.create_auth_plugin())
a = adapter.Adapter(session=s, service_type='compute')
data = a.get_all_version_data()
self.assertEqual({
'RegionOne': {
'public': {
'compute': [{
'collection': None,
'max_microversion': None,
'min_microversion': None,
'next_min_version': None,
'not_before': None,
'raw_status': 'stable',
'status': 'CURRENT',
'url': 'https://compute.example.com/nova/public',
'version': '2.0'
}, {
'collection': None,
'max_microversion': '2.35',
'min_microversion': '2.1',
'next_min_version': None,
'not_before': None,
'raw_status': 'stable',
'status': 'CURRENT',
'url': 'https://compute.example.com/nova/public',
'version': '2.1'
}],
}
}
}, data)
def test_get_all_version_data_service_alias(self):
cinder_disc = fixture.DiscoveryList(v2=False, v3=False)
# The version discovery dict will not have a project_id
cinder_disc.add_nova_microversion(
href=self.TEST_VOLUME.versions['v3'].discovery.public,
id='v3.0', status='CURRENT',
min_version='3.0', version='3.20')
# Adding a v2 version to a service named volumev3 is not
# an error. The service itself is cinder and has more than
# one major version.
cinder_disc.add_nova_microversion(
href=self.TEST_VOLUME.versions['v2'].discovery.public,
id='v2.0', status='SUPPORTED')
self.stub_url(
'GET', [],
base_url=self.TEST_VOLUME.unversioned.public + '/',
json=cinder_disc)
a = self.create_auth_plugin()
s = session.Session(auth=a)
data = s.get_all_version_data(
interface='public',
service_type='block-store')
self.assertEqual({
'RegionOne': {
'public': {
'block-storage': [{
'collection': None,
'max_microversion': None,
'min_microversion': None,
'next_min_version': None,
'not_before': None,
'raw_status': 'SUPPORTED',
'status': 'SUPPORTED',
'url': 'https://block-storage.example.com/public/v2',
'version': '2.0'
}, {
'collection': None,
'max_microversion': '3.20',
'min_microversion': '3.0',
'next_min_version': None,
'not_before': None,
'raw_status': 'CURRENT',
'status': 'CURRENT',
'url': 'https://block-storage.example.com/public/v3',
'version': '3.0'
}],
}
}
}, data)
def test_endpoint_data_no_version_no_discovery(self): def test_endpoint_data_no_version_no_discovery(self):
a = self.create_auth_plugin() a = self.create_auth_plugin()
s = session.Session(auth=a) s = session.Session(auth=a)

View File

@ -0,0 +1,8 @@
---
features:
- |
Added ability to filter the results of ``get_all_version_data`` by
service-type.
- |
Added ``get_all_version_data`` to ``adapter.Adapter`` that uses the
adapter's ``service_type`` to filter the version data fetched.