Honor service-type aliases in config

The correct config names are based on the official service type, such as
block_storage_api_version or OS_BLOCK_STORAGE_API_VERSION. But, there
are folks who have been using volume_api_version or
OS_VOLUME_API_VERSION.

Support looking for config values based on service-type aliases. The
official type will win.

Change-Id: I13c77ad4fce14a491b6a82f4c7e332d284d14e0d
This commit is contained in:
Monty Taylor 2018-05-08 10:34:35 -05:00
parent 9c774d2959
commit dade89b51f
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
17 changed files with 88 additions and 27 deletions

View File

@ -18,6 +18,7 @@ import warnings
from keystoneauth1 import adapter
import keystoneauth1.exceptions.catalog
from keystoneauth1 import session as ks_session
import os_service_types
import requestsexceptions
from six.moves import urllib
@ -103,6 +104,8 @@ class CloudRegion(object):
self._cache_arguments = cache_arguments
self._password_callback = password_callback
self._service_type_manager = os_service_types.ServiceTypes()
def __getattr__(self, key):
"""Return arbitrary attributes."""
@ -188,33 +191,62 @@ class CloudRegion(object):
def get_auth_args(self):
return self.config.get('auth', {})
def _get_config(
self, key, service_type,
default=None,
fallback_to_unprefixed=False):
'''Get a config value for a service_type.
Finds the config value for a key, looking first for it prefixed by
the given service_type, then by any known aliases of that service_type.
Finally, if fallback_to_unprefixed is True, a value will be looked
for without a prefix to support the config values where a global
default makes sense.
For instance, ``_get_config('example', 'block-storage', True)`` would
first look for ``block_storage_example``, then ``volumev3_example``,
``volumev2_example`` and ``volume_example``. If no value was found, it
would look for ``example``.
If none of that works, it returns the value in ``default``.
'''
for st in self._service_type_manager.get_all_types(service_type):
value = self.config.get(_make_key(key, st))
if value is not None:
return value
if fallback_to_unprefixed:
return self.config.get(key)
return default
def get_interface(self, service_type=None):
key = _make_key('interface', service_type)
interface = self.config.get('interface')
return self.config.get(key, interface)
return self._get_config(
'interface', service_type, fallback_to_unprefixed=True)
def get_api_version(self, service_type):
key = _make_key('api_version', service_type)
return self.config.get(key, None)
return self._get_config('api_version', service_type)
def get_service_type(self, service_type):
# People requesting 'volume' are doing so because os-client-config
# let them. What they want is block-storage, not explicitly the
# v1 of cinder. If someone actually wants v1, they'll have api_version
# set to 1, in which case block-storage will still work properly.
if service_type == 'volume':
service_type = 'block-storage'
key = _make_key('service_type', service_type)
return self.config.get(key, service_type)
# Use service-types-manager to grab the official type name. _get_config
# will still look for config by alias, but starting with the official
# type will get us things in the right order.
if self._service_type_manager.is_known(service_type):
service_type = self._service_type_manager.get_service_type(
service_type)
return self._get_config(
'service_type', service_type, default=service_type)
def get_service_name(self, service_type):
key = _make_key('service_name', service_type)
return self.config.get(key, None)
return self._get_config('service_name', service_type)
def get_endpoint(self, service_type):
key = _make_key('endpoint_override', service_type)
old_key = _make_key('endpoint', service_type)
return self.config.get(key, self.config.get(old_key, None))
value = self._get_config('endpoint_override', service_type)
if not value:
value = self._get_config('endpoint', service_type)
return value
@property
def prefer_ipv6(self):

View File

@ -2,6 +2,7 @@
"application_catalog_api_version": "1",
"auth_type": "password",
"baremetal_api_version": "1",
"block_storage_api_version": "2",
"container_api_version": "1",
"container_infra_api_version": "1",
"compute_api_version": "2",

View File

@ -51,6 +51,12 @@
"default": "1",
"type": "string"
},
"block_storage_api_version": {
"name": "Block Storage API Version",
"description": "Block Storage API Version",
"default": "2",
"type": "string"
},
"compute_api_version": {
"name": "Compute API Version",
"description": "Compute API Version",
@ -103,6 +109,7 @@
"required": [
"auth_type",
"baremetal_api_version",
"block_storage_api_version",
"compute_api_version",
"database_api_version",
"disable_vendor_agent",
@ -115,7 +122,6 @@
"interface",
"network_api_version",
"object_store_api_version",
"secgroup_source",
"volume_api_version"
"secgroup_source"
]
}

View File

@ -168,6 +168,11 @@
"description": "Baremetal API Service Type",
"type": "string"
},
"block_storage_api_version": {
"name": "Block Storage API Version",
"description": "Block Storage API Version",
"type": "string"
},
"compute_api_version": {
"name": "Compute API Version",
"description": "Compute API Version",

View File

@ -9,6 +9,6 @@
],
"identity_api_version": "3",
"image_format": "raw",
"volume_api_version": "3"
"block_storage_api_version": "3"
}
}

View File

@ -1,7 +1,7 @@
{
"name": "bluebox",
"profile": {
"volume_api_version": "1",
"block_storage_api_version": "1",
"region_name": "RegionOne"
}
}

View File

@ -9,7 +9,7 @@
"nz_wlg_2"
],
"image_api_version": "1",
"volume_api_version": "1",
"block_storage_api_version": "1",
"image_format": "raw"
}
}

View File

@ -13,7 +13,7 @@
"Kna1"
],
"requires_floating_ip": true,
"volume_api_version": "1",
"block_storage_api_version": "1",
"identity_api_version": "3"
}
}

View File

@ -6,7 +6,7 @@
},
"identity_api_version": "3",
"image_api_version": "1",
"volume_api_version": "1",
"block_storage_api_version": "1",
"regions": [
"it-mil1",
"nl-ams1",

View File

@ -10,6 +10,6 @@
"cystack"
],
"identity_api_version": "3",
"volume_api_version": "3"
"block_storage_api_version": "3"
}
}

View File

@ -4,7 +4,7 @@
"auth": {
"auth_url": "https://identity.open.softlayer.com"
},
"volume_api_version": "2",
"block_storage_api_version": "2",
"identity_api_version": "3",
"regions": [
"london"

View File

@ -19,7 +19,7 @@
"floating_ip_source": "None",
"secgroup_source": "None",
"requires_floating_ip": false,
"volume_api_version": "1",
"block_storage_api_version": "1",
"disable_vendor_agent": {
"vm_mode": "hvm",
"xenapi_use_agent": false

View File

@ -8,7 +8,7 @@
"LS",
"ZH"
],
"volume_api_version": "1",
"block_storage_api_version": "1",
"image_api_use_tasks": true,
"image_format": "raw"
}

View File

@ -5,7 +5,7 @@
"auth_url": "https://console.ultimum-cloud.com:5000/"
},
"identity_api_version": "3",
"volume_api_version": "1",
"block_storage_api_version": "1",
"region-name": "RegionOne"
}
}

View File

@ -8,7 +8,7 @@
"bj1",
"gd1"
],
"volume_api_version": "1",
"block_storage_api_version": "1",
"identity_api_version": "3",
"image_format": "raw",
"floating_ip_source": "None"

View File

@ -150,6 +150,16 @@ class TestCloudRegion(base.TestCase):
self.assertIsNone(cc.get_service_name('compute'))
self.assertEqual('locks', cc.get_service_name('identity'))
def test_aliases(self):
services_dict = fake_services_dict.copy()
services_dict['volume_api_version'] = 12
services_dict['alarming_service_name'] = 'aodh'
cc = cloud_region.CloudRegion("test1", "region-al", services_dict)
self.assertEqual('12', cc.get_api_version('volume'))
self.assertEqual('12', cc.get_api_version('block-storage'))
self.assertEqual('aodh', cc.get_service_name('alarm'))
self.assertEqual('aodh', cc.get_service_name('alarming'))
def test_no_override(self):
"""Test no override happens when defaults are not configured"""
cc = cloud_region.CloudRegion("test1", "region-al", fake_services_dict)

View File

@ -0,0 +1,7 @@
---
features:
- |
Config values now support service-type aliases. The correct config names
are based on the official service type, such as
``block_storage_api_version``, but with this change, legacy aliases such
as ``volume_api_version`` are also supported.