Merge "Rework DEFAULT_SERVICE_REGIONS"
This commit is contained in:
commit
6340e80465
|
@ -1145,6 +1145,18 @@ Example:
|
||||||
OPENSTACK_KEYSTONE_URL: 'RegionOne'
|
OPENSTACK_KEYSTONE_URL: 'RegionOne'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
As of Rocky you can optionally you can set ``'*'`` as the key, and if no
|
||||||
|
matching endpoint is found this will be treated as a global default.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
DEFAULT_SERVICE_REGIONS = {
|
||||||
|
'*': 'RegionOne',
|
||||||
|
OPENSTACK_KEYSTONE_URL: 'RegionTwo'
|
||||||
|
}
|
||||||
|
|
||||||
ENABLE_CLIENT_TOKEN
|
ENABLE_CLIENT_TOKEN
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,26 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django import http
|
from django import http
|
||||||
from django import test
|
from django import test
|
||||||
|
from django.test import client
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
from openstack_auth import utils
|
from openstack_auth import utils
|
||||||
|
|
||||||
|
|
||||||
|
FAKE_CATALOG = [
|
||||||
|
{
|
||||||
|
'name': 'fake_service',
|
||||||
|
'type': "not-identity",
|
||||||
|
'endpoints': [
|
||||||
|
{'region': 'RegionOne'},
|
||||||
|
{'region': 'RegionTwo'},
|
||||||
|
{'region': 'RegionThree'},
|
||||||
|
{'region': 'RegionFour'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class RoleTestCaseAdmin(test.TestCase):
|
class RoleTestCaseAdmin(test.TestCase):
|
||||||
|
|
||||||
def test_get_admin_roles_with_default_value(self):
|
def test_get_admin_roles_with_default_value(self):
|
||||||
|
@ -75,6 +90,33 @@ class UtilsTestCase(test.TestCase):
|
||||||
for src, expected in test_urls:
|
for src, expected in test_urls:
|
||||||
self.assertEqual(expected, utils.fix_auth_url_version_prefix(src))
|
self.assertEqual(expected, utils.fix_auth_url_version_prefix(src))
|
||||||
|
|
||||||
|
@override_settings(DEFAULT_SERVICE_REGIONS={
|
||||||
|
'http://example.com': 'RegionThree', '*': 'RegionFour'})
|
||||||
|
def test_default_services_region_precedence(self):
|
||||||
|
request = client.RequestFactory().get('fake')
|
||||||
|
|
||||||
|
# Cookie is valid, so should be region source
|
||||||
|
request.COOKIES['services_region'] = "RegionTwo"
|
||||||
|
default_region = utils.default_services_region(
|
||||||
|
FAKE_CATALOG, request=request, ks_endpoint='http://example.com')
|
||||||
|
self.assertEqual("RegionTwo", default_region)
|
||||||
|
|
||||||
|
# Cookie is invalid, so ks_endpoint is source
|
||||||
|
request.COOKIES['services_region'] = "Not_valid_region"
|
||||||
|
default_region = utils.default_services_region(
|
||||||
|
FAKE_CATALOG, request=request, ks_endpoint='http://example.com')
|
||||||
|
self.assertEqual("RegionThree", default_region)
|
||||||
|
|
||||||
|
# endpoint and cookie are invalid, so source is "*" key
|
||||||
|
default_region = utils.default_services_region(
|
||||||
|
FAKE_CATALOG, request=request, ks_endpoint='not_a_match')
|
||||||
|
self.assertEqual("RegionFour", default_region)
|
||||||
|
|
||||||
|
def test_default_services_region_fallback(self):
|
||||||
|
# Test that first region found in catalog is returned
|
||||||
|
default_region = utils.default_services_region(FAKE_CATALOG)
|
||||||
|
self.assertEqual("RegionOne", default_region)
|
||||||
|
|
||||||
|
|
||||||
class BehindProxyTestCase(test.TestCase):
|
class BehindProxyTestCase(test.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,8 @@ def set_session_from_user(request, user):
|
||||||
|
|
||||||
def create_user_from_token(request, token, endpoint, services_region=None):
|
def create_user_from_token(request, token, endpoint, services_region=None):
|
||||||
# if the region is provided, use that, otherwise use the preferred region
|
# if the region is provided, use that, otherwise use the preferred region
|
||||||
default_service_regions = getattr(settings, 'DEFAULT_SERVICE_REGIONS', {})
|
|
||||||
default_service_region = default_service_regions.get(endpoint)
|
|
||||||
svc_region = services_region or \
|
svc_region = services_region or \
|
||||||
utils.default_services_region(token.serviceCatalog, request,
|
utils.default_services_region(token.serviceCatalog, request, endpoint)
|
||||||
selected_region=default_service_region)
|
|
||||||
return User(id=token.user['id'],
|
return User(id=token.user['id'],
|
||||||
token=token,
|
token=token,
|
||||||
user=token.user['name'],
|
user=token.user['name'],
|
||||||
|
|
|
@ -343,10 +343,17 @@ def get_project_list(*args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def default_services_region(service_catalog, request=None,
|
def default_services_region(service_catalog, request=None,
|
||||||
selected_region=None):
|
ks_endpoint=None):
|
||||||
"""Returns the first endpoint region for first non-identity service.
|
"""Return the default service region.
|
||||||
|
|
||||||
Extracted from the service catalog.
|
Order of precedence:
|
||||||
|
1. 'services_region' cookie value
|
||||||
|
2. Matching endpoint in DEFAULT_SERVICE_REGIONS
|
||||||
|
3. '*' key in DEFAULT_SERVICE_REGIONS
|
||||||
|
4. First valid region from catalog
|
||||||
|
|
||||||
|
In each case the value must also be present in available_regions or
|
||||||
|
we move to the next level of precedence.
|
||||||
"""
|
"""
|
||||||
if service_catalog:
|
if service_catalog:
|
||||||
available_regions = [get_endpoint_region(endpoint) for service
|
available_regions = [get_endpoint_region(endpoint) for service
|
||||||
|
@ -367,12 +374,20 @@ def default_services_region(service_catalog, request=None,
|
||||||
LOG.error('No regions can be found in the service catalog.')
|
LOG.error('No regions can be found in the service catalog.')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if request and selected_region is None:
|
region_options = []
|
||||||
selected_region = request.COOKIES.get('services_region',
|
if request:
|
||||||
available_regions[0])
|
region_options.append(request.COOKIES.get('services_region'))
|
||||||
if selected_region not in available_regions:
|
if ks_endpoint:
|
||||||
selected_region = available_regions[0]
|
default_service_regions = getattr(
|
||||||
return selected_region
|
settings, 'DEFAULT_SERVICE_REGIONS', {})
|
||||||
|
region_options.append(default_service_regions.get(ks_endpoint))
|
||||||
|
region_options.append(
|
||||||
|
getattr(settings, 'DEFAULT_SERVICE_REGIONS', {}).get('*'))
|
||||||
|
|
||||||
|
for region in region_options:
|
||||||
|
if region in available_regions:
|
||||||
|
return region
|
||||||
|
return available_regions[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -190,8 +190,10 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"
|
||||||
# For setting the default service region on a per-endpoint basis. Note that the
|
# For setting the default service region on a per-endpoint basis. Note that the
|
||||||
# default value for this setting is {}, and below is just an example of how it
|
# default value for this setting is {}, and below is just an example of how it
|
||||||
# should be specified.
|
# should be specified.
|
||||||
|
# A key of '*' is an optional global default if no other key matches.
|
||||||
#DEFAULT_SERVICE_REGIONS = {
|
#DEFAULT_SERVICE_REGIONS = {
|
||||||
# OPENSTACK_KEYSTONE_URL: 'RegionOne'
|
# '*': 'RegionOne'
|
||||||
|
# OPENSTACK_KEYSTONE_URL: 'RegionTwo'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
# Enables keystone web single-sign-on if set to True.
|
# Enables keystone web single-sign-on if set to True.
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
DEFAULT_SERVICE_REGIONS can now take '*' as a key which serves either as a
|
||||||
|
fallback service region, or the default region if no other keys are set.
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
[:bug:`1772345`]
|
||||||
|
``DEFAULT_SERVICE_REGIONS`` no longer overrides the cookie value from
|
||||||
|
``services_region``. This fixes the UX where a user controlled value
|
||||||
|
keeps being overridden by a setting and changes ``DEFAULT_SERVICE_REGIONS``
|
||||||
|
to act as a default (as the name implies) per endpoint if the cookie is not
|
||||||
|
set rather than an override. The cookie will still be overridden when
|
||||||
|
it is for a region not present in the user's current catalog, so this will
|
||||||
|
still handle the original multi-keystone case that requried the
|
||||||
|
introduction of ``DEFAULT_SERVICE_REGIONS``.
|
Loading…
Reference in New Issue