openstacksdk/openstack/service_filter.py

192 lines
6.0 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.
"""
The :class:`~openstack.service_filter.ServiceFilter` is the base class
for service identifiers and user service preferences. Each
:class:`~openstack.resource.Resource` has a service identifier to
associate the resource with a service. An example of a service identifier
would be ``openstack.compute.compute_service.ComputeService``.
The preferences are stored in the
:class:`~openstack.profile.Profile` object.
The service preference and the service identifier are joined to create a
filter to match a service.
Examples
--------
The :class:`~openstack.service_filter.ServiceFilter` class can be built
with a service type, interface, region, name, and version.
Create a service filter
~~~~~~~~~~~~~~~~~~~~~~~
Create a compute service and service preference. Join the services
and match::
from openstack import service_filter
from openstack.compute import compute_service
default = compute_service.ComputeService()
preference = service_filter.ServiceFilter('compute', version='v2')
result = preference.join(default)
matches = (result.match_service_type('compute') and
result.match_service_name('Hal9000') and
result.match_region('DiscoveryOne') and
result.match_interface('public'))
print(str(result))
print("matches=" + str(matches))
The resulting output from the code::
service_type=compute,interface=public,version=v2
matches=True
"""
class ValidVersion(object):
def __init__(self, module, path=None):
"""" Valid service version.
:param string module: Module associated with version.
:param string path: URL path version.
"""
self.module = module
self.path = path or module
class ServiceFilter(dict):
UNVERSIONED = ''
PUBLIC = 'public'
INTERNAL = 'internal'
ADMIN = 'admin'
valid_versions = []
def __init__(self, service_type, interface=PUBLIC, region=None,
service_name=None, version=None, api_version=None,
requires_project_id=False):
"""Create a service identifier.
:param string service_type: The desired type of service.
:param string interface: The exposure of the endpoint. Should be
`public` (default), `internal` or `admin`.
:param string region: The desired region (optional).
:param string service_name: Name of the service
:param string version: Version of service to use.
:param string api_version: Microversion of service supported.
:param bool requires_project_id: True if this service's endpoint
expects project id to be included.
"""
self['service_type'] = service_type.lower()
self['interface'] = interface
self['region_name'] = region
self['service_name'] = service_name
self['version'] = version
self['api_version'] = api_version
self['requires_project_id'] = requires_project_id
@property
def service_type(self):
return self['service_type']
@property
def interface(self):
return self['interface']
@interface.setter
def interface(self, value):
self['interface'] = value
@property
def region(self):
return self['region_name']
@region.setter
def region(self, value):
self['region_name'] = value
@property
def service_name(self):
return self['service_name']
@service_name.setter
def service_name(self, value):
self['service_name'] = value
@property
def version(self):
return self['version']
@version.setter
def version(self, value):
self['version'] = value
@property
def api_version(self):
return self['api_version']
@api_version.setter
def api_version(self, value):
self['api_version'] = value
@property
def requires_project_id(self):
return self['requires_project_id']
@requires_project_id.setter
def requires_project_id(self, value):
self['requires_project_id'] = value
@property
def path(self):
return self['path']
@path.setter
def path(self, value):
self['path'] = value
def get_path(self, version=None):
if not self.version:
self.version = version
return self.get('path', self._get_valid_version().path)
def get_filter(self):
filter = dict(self)
del filter['version']
return filter
def _get_valid_version(self):
if self.valid_versions:
if self.version:
for valid in self.valid_versions:
# NOTE(thowe): should support fuzzy match e.g: v2.1==v2
if self.version.startswith(valid.module):
return valid
return self.valid_versions[0]
return ValidVersion('')
def get_module(self):
"""Get the full module name associated with the service."""
module = self.__class__.__module__.split('.')
module = ".".join(module[:-1])
module = module + "." + self._get_valid_version().module
return module
def get_service_module(self):
"""Get the module version of the service name.
This would often be the same as the service type except in cases like
object store where the service type is `object-store` and the module
is `object_store`.
"""
return self.__class__.__module__.split('.')[-2]