Use discovery instead of config to create proxies

Since the dawn of time we've labored under the crippling burden of
needing to explicitly request a version via configuration in order to
get a usable handle to the cloud. This is despite the hilarity of the
existence of a system for discovering available versions since basically
the beginning of the entire OpenStack project.

Today we shall be liberated from the tyranny of terrible past life
decisions on the part of our forefathers and shall usher forth the
shining freedom of actually using the discovery system.

Change-Id: I11c16d37d3ab3d77bed3a0bcbd98f1fa33b9555f
This commit is contained in:
Monty Taylor 2018-08-25 10:57:46 +09:00
parent 9d72be5ac9
commit 071e567b32
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
318 changed files with 421 additions and 1441 deletions

View File

@ -34,7 +34,7 @@ already. For reference, those are:
servers = conn.list_servers() # High-level resource interface from shade
servers = conn.compute.servers() # SDK Service/Object Interface
response = conn.compute.get('/servers') # REST passthrough
* Removed ServiceFilter and the various Service objects in favor of discovery.
Next steps
==========
@ -44,8 +44,6 @@ Next steps
mean anything to people.
* Migrate unit tests to requests-mock instead of mocking python calls to
session.
* Investigate removing ServiceFilter and the various Service objects if an
acceptable plan can be found for using discovery.
* Replace _prepare_request with requests.Session.prepare_request.
shade integration

View File

@ -1,6 +1,5 @@
# Apache 2 header omitted for brevity
from openstack.fake import fake_service
from openstack import resource
@ -8,7 +7,6 @@ class Fake(resource.Resource):
resource_key = "resource"
resources_key = "resources"
base_path = "/fake"
service = fake_service.FakeService()
allow_create = True
allow_fetch = True

View File

@ -1,13 +1,12 @@
# Apache 2 header omitted for brevity
from openstack import service_filter
from openstack import service_description
from openstack.fake.v2 import _proxy as _proxy_v2
class FakeService(service_filter.ServiceFilter):
class FakeService(service_description.ServiceDescription):
"""The fake service."""
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self, version=None):
"""Create a fake service."""
super(FakeService, self).__init__(service_type='fake', version=version)
supported_versions = {
'2': _proxy_v2.Proxy,
}

View File

@ -148,7 +148,7 @@ can be customized.
:maxdepth: 1
resource
service_filter
service_description
utils
Presentations

View File

@ -0,0 +1,10 @@
ServiceDescription
==================
.. automodule:: openstack.service_description
ServiceDescription object
-------------------------
.. autoclass:: openstack.service_description.ServiceDescription
:members:

View File

@ -1,10 +0,0 @@
ServiceFilter
=============
.. automodule:: openstack.service_filter
ServiceFilter object
--------------------
.. autoclass:: openstack.service_filter.ServiceFilter
:members:

View File

@ -14,7 +14,7 @@ jmespath==0.9.0
jsonpatch==1.16
jsonpointer==1.13
jsonschema==2.6.0
keystoneauth1==3.8.0
keystoneauth1==3.11.0
linecache2==1.0.0
mock==2.0.0
mox3==0.20.0

View File

@ -18,7 +18,6 @@ import warnings
import os_service_types
from openstack import _log
from openstack import proxy
from openstack import service_description
_logger = _log.setup_logging('openstack')
@ -43,28 +42,28 @@ class ConnectionMeta(type):
# from openstacksdk. The credentials API calls are all calls
# on identity endpoints.
continue
desc_class = service_description.ServiceDescription
service_filter_class = _find_service_filter_class(service_type)
desc_class = _find_service_description_class(service_type)
descriptor_args = {'service_type': service_type}
if service_filter_class:
desc_class = service_description.OpenStackServiceDescription
descriptor_args['service_filter_class'] = service_filter_class
class_names = service_filter_class._get_proxy_class_names()
if len(class_names) == 1:
doc = _DOC_TEMPLATE.format(
class_name="{service_type} Proxy <{name}>".format(
service_type=service_type, name=class_names[0]),
**service)
else:
class_doc_strings = "\n".join([
":class:`{class_name}`".format(class_name=class_name)
for class_name in class_names])
doc = _PROXY_TEMPLATE.format(
class_doc_strings=class_doc_strings, **service)
else:
descriptor_args['proxy_class'] = proxy.Proxy
if not desc_class.supported_versions:
doc = _DOC_TEMPLATE.format(
class_name='~openstack.proxy.Proxy', **service)
class_name="{service_type} Proxy".format(
service_type=service_type),
**service)
elif len(desc_class.supported_versions) == 1:
supported_version = list(
desc_class.supported_versions.keys())[0]
doc = _DOC_TEMPLATE.format(
class_name="{service_type} Proxy <{name}>".format(
service_type=service_type, name=supported_version),
**service)
else:
class_doc_strings = "\n".join([
":class:`{class_name}`".format(
class_name=proxy_class.__name__)
for proxy_class in desc_class.supported_versions.values()])
doc = _PROXY_TEMPLATE.format(
class_doc_strings=class_doc_strings, **service)
descriptor = desc_class(**descriptor_args)
descriptor.__doc__ = doc
st = service_type.replace('-', '_')
@ -103,7 +102,7 @@ def _get_aliases(service_type, aliases=None):
return all_types
def _find_service_filter_class(service_type):
def _find_service_description_class(service_type):
package_name = 'openstack.{service_type}'.format(
service_type=service_type).replace('-', '_')
module_name = service_type.replace('-', '_') + '_service'
@ -111,17 +110,17 @@ def _find_service_filter_class(service_type):
[part.capitalize() for part in module_name.split('_')])
try:
import_name = '.'.join([package_name, module_name])
service_filter_module = importlib.import_module(import_name)
service_description_module = importlib.import_module(import_name)
except ImportError as e:
# ImportWarning is ignored by default. This warning is here
# as an opt-in for people trying to figure out why something
# didn't work.
warnings.warn(
"Could not import {service_type} service filter: {e}".format(
"Could not import {service_type} service description: {e}".format(
service_type=service_type, e=str(e)),
ImportWarning)
return None
return service_description.ServiceDescription
# There are no cases in which we should have a module but not the class
# inside it.
service_filter_class = getattr(service_filter_module, class_name)
return service_filter_class
service_description_class = getattr(service_description_module, class_name)
return service_description_class

View File

@ -10,15 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack import service_filter
from openstack import service_description
from openstack.baremetal.v1 import _proxy
class BaremetalService(service_filter.ServiceFilter):
class BaremetalService(service_description.ServiceDescription):
"""The bare metal service."""
valid_versions = [service_filter.ValidVersion('v1')]
def __init__(self, version=None):
"""Create a bare metal service."""
super(BaremetalService, self).__init__(service_type='baremetal',
version=version)
supported_versions = {
'1': _proxy.Proxy,
}

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.baremetal import baremetal_service
from openstack import resource
@ -18,7 +17,6 @@ class Chassis(resource.Resource):
resources_key = 'chassis'
base_path = '/chassis'
service = baremetal_service.BaremetalService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.baremetal import baremetal_service
from openstack import resource
@ -18,7 +17,6 @@ class Driver(resource.Resource):
resources_key = 'drivers'
base_path = '/drivers'
service = baremetal_service.BaremetalService()
# capabilities
allow_create = False

View File

@ -11,7 +11,6 @@
# under the License.
from openstack import _log
from openstack.baremetal import baremetal_service
from openstack.baremetal.v1 import _common
from openstack import exceptions
from openstack import resource
@ -39,7 +38,6 @@ class Node(resource.Resource):
resources_key = 'nodes'
base_path = '/nodes'
service = baremetal_service.BaremetalService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.baremetal import baremetal_service
from openstack import resource
@ -18,7 +17,6 @@ class Port(resource.Resource):
resources_key = 'ports'
base_path = '/ports'
service = baremetal_service.BaremetalService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.baremetal import baremetal_service
from openstack import resource
@ -18,7 +17,6 @@ class PortGroup(resource.Resource):
resources_key = 'portgroups'
base_path = '/portgroups'
service = baremetal_service.BaremetalService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.baremetal import baremetal_service
from openstack import resource
@ -18,9 +17,6 @@ class Version(resource.Resource):
resource_key = 'version'
resources_key = 'versions'
base_path = '/'
service = baremetal_service.BaremetalService(
version=baremetal_service.BaremetalService.UNVERSIONED
)
# Capabilities
allow_list = True

View File

@ -10,16 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack import service_filter
from openstack.block_storage.v2 import _proxy
from openstack import service_description
class BlockStorageService(service_filter.ServiceFilter):
class BlockStorageService(service_description.ServiceDescription):
"""The block storage service."""
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self, version=None):
"""Create a block storage service."""
super(BlockStorageService, self).__init__(
service_type='block-storage',
version=version, requires_project_id=True)
supported_versions = {
'2': _proxy.Proxy,
}

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.block_storage import block_storage_service
from openstack import format
from openstack import resource
@ -19,7 +18,6 @@ class Snapshot(resource.Resource):
resource_key = "snapshot"
resources_key = "snapshots"
base_path = "/snapshots"
service = block_storage_service.BlockStorageService()
_query_mapping = resource.QueryParameters(
'all_tenants', 'name', 'status', 'volume_id')

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.block_storage import block_storage_service
from openstack import resource
@ -18,7 +17,6 @@ class Pools(resource.Resource):
resource_key = "pool"
resources_key = "pools"
base_path = "/scheduler-stats/get_pools?detail=True"
service = block_storage_service.BlockStorageService()
# capabilities
allow_fetch = False

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.block_storage import block_storage_service
from openstack import resource
@ -18,7 +17,6 @@ class Type(resource.Resource):
resource_key = "volume_type"
resources_key = "volume_types"
base_path = "/types"
service = block_storage_service.BlockStorageService()
# capabilities
allow_fetch = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.block_storage import block_storage_service
from openstack import format
from openstack import resource
@ -19,7 +18,6 @@ class Volume(resource.Resource):
resource_key = "volume"
resources_key = "volumes"
base_path = "/volumes"
service = block_storage_service.BlockStorageService()
_query_mapping = resource.QueryParameters(
'all_tenants', 'name', 'status', 'project_id')

View File

@ -10,18 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack import service_filter
from openstack.clustering.v1 import _proxy
from openstack import service_description
class ClusteringService(service_filter.ServiceFilter):
class ClusteringService(service_description.ServiceDescription):
"""The clustering service."""
valid_versions = [service_filter.ValidVersion('v1')]
UNVERSIONED = None
def __init__(self, version=None):
"""Create a clustering service."""
super(ClusteringService, self).__init__(
service_type='clustering',
version=version
)
supported_versions = {
'1': _proxy.Proxy,
}

View File

@ -11,7 +11,6 @@
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -19,7 +18,6 @@ class Action(resource.Resource):
resource_key = 'action'
resources_key = 'actions'
base_path = '/actions'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -10,14 +10,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
class BuildInfo(resource.Resource):
base_path = '/build-info'
resource_key = 'build_info'
service = clustering_service.ClusteringService()
# Capabilities
allow_fetch = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
from openstack import utils
@ -19,7 +18,6 @@ class Cluster(resource.Resource):
resource_key = 'cluster'
resources_key = 'clusters'
base_path = '/clusters'
service = clustering_service.ClusteringService()
# capabilities
allow_create = True

View File

@ -10,14 +10,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
class ClusterAttr(resource.Resource):
resources_key = 'cluster_attributes'
base_path = '/clusters/%(cluster_id)s/attrs/%(path)s'
service = clustering_service.ClusteringService()
# capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -18,7 +17,6 @@ class ClusterPolicy(resource.Resource):
resource_key = 'cluster_policy'
resources_key = 'cluster_policies'
base_path = '/clusters/%(cluster_id)s/policies'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -11,7 +11,6 @@
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -19,7 +18,6 @@ class Event(resource.Resource):
resource_key = 'event'
resources_key = 'events'
base_path = '/events'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
from openstack import utils
@ -19,7 +18,6 @@ class Node(resource.Resource):
resource_key = 'node'
resources_key = 'nodes'
base_path = '/nodes'
service = clustering_service.ClusteringService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -18,7 +17,6 @@ class Policy(resource.Resource):
resource_key = 'policy'
resources_key = 'policies'
base_path = '/policies'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -18,7 +17,6 @@ class PolicyType(resource.Resource):
resource_key = 'policy_type'
resources_key = 'policy_types'
base_path = '/policy-types'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -18,7 +17,6 @@ class Profile(resource.Resource):
resource_key = 'profile'
resources_key = 'profiles'
base_path = '/profiles'
service = clustering_service.ClusteringService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
from openstack import utils
@ -19,7 +18,6 @@ class ProfileType(resource.Resource):
resource_key = 'profile_type'
resources_key = 'profile_types'
base_path = '/profile-types'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -18,7 +17,6 @@ class Receiver(resource.Resource):
resource_key = 'receiver'
resources_key = 'receivers'
base_path = '/receivers'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -18,7 +17,6 @@ class Service(resource.Resource):
resource_key = 'service'
resources_key = 'services'
base_path = '/services'
service = clustering_service.ClusteringService()
# Capabilities
allow_list = True

View File

@ -11,7 +11,6 @@
# under the License.
from openstack.clustering import clustering_service
from openstack import resource
@ -19,9 +18,6 @@ class Version(resource.Resource):
resource_key = 'version'
resources_key = 'versions'
base_path = '/'
service = clustering_service.ClusteringService(
version=clustering_service.ClusteringService.UNVERSIONED
)
# capabilities
allow_list = True

View File

@ -10,15 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack import service_filter
from openstack import service_description
from openstack.compute.v2 import _proxy
class ComputeService(service_filter.ServiceFilter):
class ComputeService(service_description.ServiceDescription):
"""The compute service."""
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self, version=None):
"""Create a compute service."""
super(ComputeService, self).__init__(service_type='compute',
version=version)
supported_versions = {
'2': _proxy.Proxy
}

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,8 +17,6 @@ class AvailabilityZone(resource.Resource):
resources_key = 'availabilityZoneInfo'
base_path = '/os-availability-zone'
service = compute_service.ComputeService()
# capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,7 +17,6 @@ class Extension(resource.Resource):
resource_key = 'extension'
resources_key = 'extensions'
base_path = '/extensions'
service = compute_service.ComputeService()
id_attribute = "alias"
# capabilities

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,7 +17,6 @@ class Flavor(resource.Resource):
resource_key = 'flavor'
resources_key = 'flavors'
base_path = '/flavors'
service = compute_service.ComputeService()
# capabilities
allow_create = True

View File

@ -11,7 +11,6 @@
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -20,8 +19,6 @@ class Hypervisor(resource.Resource):
resources_key = 'hypervisors'
base_path = '/os-hypervisors'
service = compute_service.ComputeService()
# capabilities
allow_fetch = True
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack.compute.v2 import metadata
from openstack import resource
@ -19,7 +18,6 @@ class Image(resource.Resource, metadata.MetadataMixin):
resource_key = 'image'
resources_key = 'images'
base_path = '/images'
service = compute_service.ComputeService()
# capabilities
allow_fetch = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,7 +17,6 @@ class Keypair(resource.Resource):
resource_key = 'keypair'
resources_key = 'keypairs'
base_path = '/os-keypairs'
service = compute_service.ComputeService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -71,7 +70,6 @@ class RateLimit(resource.Resource):
class Limits(resource.Resource):
base_path = "/limits"
resource_key = "limits"
service = compute_service.ComputeService()
allow_fetch = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack.compute.v2 import metadata
from openstack import resource
from openstack import utils
@ -20,7 +19,6 @@ class Server(resource.Resource, metadata.MetadataMixin):
resource_key = 'server'
resources_key = 'servers'
base_path = '/servers'
service = compute_service.ComputeService()
# capabilities
allow_create = True
@ -189,7 +187,7 @@ class Server(resource.Resource, metadata.MetadataMixin):
def get_password(self, session):
"""Get the encrypted administrator password."""
url = utils.urljoin(Server.base_path, self.id, 'os-server-password')
return session.get(url, endpoint_filter=self.service)
return session.get(url)
def reboot(self, session, reboot_type):
"""Reboot server where reboot_type might be 'SOFT' or 'HARD'."""

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,7 +17,6 @@ class ServerGroup(resource.Resource):
resource_key = 'server_group'
resources_key = 'server_groups'
base_path = '/os-server-groups'
service = compute_service.ComputeService()
_query_mapping = resource.QueryParameters("all_projects")

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,7 +17,6 @@ class ServerInterface(resource.Resource):
resource_key = 'interfaceAttachment'
resources_key = 'interfaceAttachments'
base_path = '/servers/%(server_id)s/os-interface'
service = compute_service.ComputeService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
from openstack import utils
@ -18,7 +17,6 @@ from openstack import utils
class ServerIP(resource.Resource):
resources_key = 'addresses'
base_path = '/servers/%(server_id)s/ips'
service = compute_service.ComputeService()
# capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
from openstack import utils
@ -20,8 +19,6 @@ class Service(resource.Resource):
resources_key = 'services'
base_path = '/os-services'
service = compute_service.ComputeService()
# capabilities
allow_list = True
allow_commit = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,7 +17,6 @@ class VolumeAttachment(resource.Resource):
resource_key = 'volumeAttachment'
resources_key = 'volumeAttachments'
base_path = '/servers/%(server_id)s/os-volume_attachments'
service = compute_service.ComputeService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
@ -18,9 +17,6 @@ class Version(resource.Resource):
resource_key = 'version'
resources_key = 'versions'
base_path = '/'
service = compute_service.ComputeService(
version=compute_service.ComputeService.UNVERSIONED
)
# capabilities
allow_list = True

View File

@ -252,7 +252,13 @@ class CloudRegion(object):
'interface', service_type, fallback_to_unprefixed=True)
def get_api_version(self, service_type):
return self._get_config('api_version', service_type)
version = self._get_config('api_version', service_type)
if version:
try:
float(version)
except ValueError:
return None
return version
def get_default_microversion(self, service_type):
return self._get_config('default_microversion', service_type)
@ -412,6 +418,20 @@ class CloudRegion(object):
return version_request
def get_all_version_data(self, service_type):
# Seriously. Don't think about the existential crisis
# that is the next line. You'll wind up in cthulhu's lair.
service_type = self.get_service_type(service_type)
versions = self.get_session().get_all_version_data(
service_type=service_type,
interface=self.get_interface(service_type),
region_name=self.region_name,
)
region_versions = versions.get(self.region_name, {})
interface_versions = region_versions.get(
self.get_interface(service_type), {})
return interface_versions.get(service_type, [])
def get_session_client(
self, service_type, version=None, constructor=adapter.Adapter,
**kwargs):
@ -436,8 +456,10 @@ class CloudRegion(object):
self.get_status_code_retries(service_type))
endpoint_override = self.get_endpoint(service_type)
version = version_request.version
min_api_version = version_request.min_api_version
max_api_version = version_request.max_api_version
min_api_version = (
kwargs.pop('min_version', None) or version_request.min_api_version)
max_api_version = (
kwargs.pop('max_version', None) or version_request.max_api_version)
# Older neutron has inaccessible discovery document. Nobody noticed
# because neutronclient hard-codes an append of v2.0. YAY!
if service_type == 'network':

View File

@ -10,15 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack import service_filter
from openstack.database.v1 import _proxy
from openstack import service_description
class DatabaseService(service_filter.ServiceFilter):
class DatabaseService(service_description.ServiceDescription):
"""The database service."""
valid_versions = [service_filter.ValidVersion('v1')]
def __init__(self, version=None):
"""Create a database service."""
super(DatabaseService, self).__init__(service_type='database',
version=version)
supported_versions = {
'1': _proxy.Proxy,
}

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.database import database_service
from openstack import resource
@ -18,7 +17,6 @@ class Database(resource.Resource):
resource_key = 'database'
resources_key = 'databases'
base_path = '/instances/%(instance_id)s/databases'
service = database_service.DatabaseService()
# capabilities
allow_create = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.database import database_service
from openstack import resource
@ -18,7 +17,6 @@ class Flavor(resource.Resource):
resource_key = 'flavor'
resources_key = 'flavors'
base_path = '/flavors'
service = database_service.DatabaseService()
# capabilities
allow_list = True

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.database import database_service
from openstack import resource
from openstack import utils
@ -19,7 +18,6 @@ class Instance(resource.Resource):
resource_key = 'instance'
resources_key = 'instances'
base_path = '/instances'
service = database_service.DatabaseService()
# capabilities
allow_create = True

2