Add OPENSTACK_KEYSTONE_ENDPOINT_TYPE config opt

The [1] changed the previous behavior of Horizon by
changing the hardcoded internal endpoint type to using
OPENSTACK_ENDPOINT_TYPE so it's no longer possible to use
internal endpoint type for Keystone but public for others.

This adds the OPENSTACK_KEYSTONE_ENDPOINT_TYPE config opt
to set the endpoint type for Keystone when grabbing it from
the service catalog.

[1] https://review.opendev.org/c/openstack/horizon/+/730781

Change-Id: I8438bedaf7cead452fc499e484d23690b48894d9
This commit is contained in:
Tobias Urdin 2022-06-03 11:36:56 +00:00 committed by Tobias Urdin
parent a2b6e6c9bd
commit b22a6d65f7
7 changed files with 55 additions and 7 deletions

View File

@ -595,6 +595,16 @@ Default: ``"publicURL"``
A string which specifies the endpoint type to use for the endpoints in the
Keystone service catalog.
OPENSTACK_KEYSTONE_ENDPOINT_TYPE
--------------------------------
.. versionadded:: 23.1.0(Antelope)
Default: ``"publicURL"``
A string which specifies the endpoint type to use for the Keystone (identity)
endpoint when looking it up in the service catalog.
OPENSTACK_HOST
--------------

View File

@ -171,7 +171,7 @@ class KeystoneBackend(object):
region_name = id_endpoint['region']
break
interface = settings.OPENSTACK_ENDPOINT_TYPE
interface = settings.OPENSTACK_KEYSTONE_ENDPOINT_TYPE
endpoint = scoped_auth_ref.service_catalog.url_for(
service_type='identity',

View File

@ -28,6 +28,7 @@ OPENSTACK_KEYSTONE_URL = "http://localhost/identity/v3"
# TODO(amotoki): The default value in openstack_dashboard is different:
# publicURL. It should be consistent.
OPENSTACK_ENDPOINT_TYPE = 'public'
OPENSTACK_KEYSTONE_ENDPOINT_TYPE = 'public'
OPENSTACK_SSL_NO_VERIFY = False
# TODO(amotoki): Is it correct?
OPENSTACK_SSL_CACERT = True

View File

@ -77,8 +77,11 @@ class Service(base.APIDictWrapper):
super().__init__(service, *args, **kwargs)
self.public_url = base.get_url_for_service(service, region,
'publicURL')
self.url = base.get_url_for_service(service, region,
settings.OPENSTACK_ENDPOINT_TYPE)
if (service and 'type' in service and service['type'] == 'identity'):
endpoint_type = settings.OPENSTACK_KEYSTONE_ENDPOINT_TYPE
else:
endpoint_type = settings.OPENSTACK_ENDPOINT_TYPE
self.url = base.get_url_for_service(service, region, endpoint_type)
if self.url:
self.host = parse.urlparse(self.url).hostname
else:
@ -159,7 +162,7 @@ def keystoneclient(request, admin=False):
if admin and not policy.check((("identity", "admin_required"),), request):
raise exceptions.NotAuthorized
endpoint_type = settings.OPENSTACK_ENDPOINT_TYPE
endpoint_type = settings.OPENSTACK_KEYSTONE_ENDPOINT_TYPE
# Take care of client connection caching/fetching a new client.
# Admin vs. non-admin clients are cached separately for token matching.
@ -463,7 +466,8 @@ def user_verify_admin_password(request, admin_password):
# verify if it's correct.
client = keystone_client_v3
try:
endpoint = _get_endpoint_url(request, 'publicURL')
endpoint = _get_endpoint_url(
request, settings.OPENSTACK_KEYSTONE_ENDPOINT_TYPE)
insecure = settings.OPENSTACK_SSL_NO_VERIFY
cacert = settings.OPENSTACK_SSL_CACERT
client.Client(

View File

@ -348,6 +348,11 @@ OPENSTACK_ENDPOINT_TYPE = 'publicURL'
# external to the OpenStack environment. The default is None. This
# value should differ from OPENSTACK_ENDPOINT_TYPE if used.
SECONDARY_ENDPOINT_TYPE = None
# OPENSTACK_KEYSTONE_ENDPOINT_TYPE specifies the endpoint type use from
# service catalog when looking up the Keystone (identity) endpoint. The
# default is 'publicURL' like OPENSTACK_ENDPOINT_TYPE to keep backward
# compatibility.
OPENSTACK_KEYSTONE_ENDPOINT_TYPE = 'publicURL'
# Set True to disable SSL certificate checks
# (useful for self-signed certificates):

View File

@ -92,8 +92,8 @@ class RoleAPITests(test.APIMockTestCase):
class ServiceAPITests(test.APIMockTestCase):
@override_settings(OPENSTACK_ENDPOINT_TYPE='internalURL')
def test_service_wrapper_for_internal_endpoint_type(self):
@override_settings(OPENSTACK_KEYSTONE_ENDPOINT_TYPE='internalURL')
def test_service_wrapper_for_keystone_endpoint_type(self):
catalog = self.service_catalog
identity_data = api.base.get_service_from_catalog(catalog, "identity")
# 'Service' class below requires 'id', so populate it here.
@ -106,6 +106,23 @@ class ServiceAPITests(test.APIMockTestCase):
self.assertEqual("http://public.keystone.example.com/identity/v3",
service.public_url)
self.assertEqual("int.keystone.example.com", service.host)
# Verify that the behavior of other services wanting public endpoint
self.test_service_wrapper_service_in_region_for_public_endpoint_type()
@override_settings(OPENSTACK_ENDPOINT_TYPE='internalURL')
def test_service_wrapper_for_internal_endpoint_type(self):
catalog = self.service_catalog
identity_data = api.base.get_service_from_catalog(catalog, "identity")
# 'Service' class below requires 'id', so populate it here.
identity_data['id'] = 1
service = api.keystone.Service(identity_data, "RegionOne")
self.assertEqual(u"identity (native backend)", str(service))
self.assertEqual("RegionOne", service.region)
self.assertEqual("http://public.keystone.example.com/identity/v3",
service.url)
self.assertEqual("http://public.keystone.example.com/identity/v3",
service.public_url)
self.assertEqual("public.keystone.example.com", service.host)
@override_settings(OPENSTACK_ENDPOINT_TYPE='publicURL')
def test_service_wrapper_for_public_endpoint_type(self):

View File

@ -0,0 +1,11 @@
---
features:
- |
Added new setting ``OPENSTACK_KEYSTONE_ENDPOINT_TYPE`` that can be used to
specify the endpoint type to use when talking to the identity API. The default
is set to the value of ``OPENSTACK_ENDPOINT_TYPE`` for backward compatibility.
upgrade:
- |
If you are setting ``OPENSTACK_ENDPOINT_TYPE`` to change the default endpoint type
for Keystone you must now set ``OPENSTACK_KEYSTONE_ENDPOINT_TYPE`` as the former
now only applies to other services.