Merge "Add dedicated auth endpoint config for servers"

This commit is contained in:
Zuul 2019-07-25 21:52:54 +00:00 committed by Gerrit Code Review
commit 54005a2a9f
7 changed files with 102 additions and 4 deletions

View File

@ -88,7 +88,14 @@ service_opts = [
cfg.IntOpt('num_engine_workers',
help=_('Number of heat-engine processes to fork and run. '
'Will default to either to 4 or number of CPUs on '
'the host, whichever is greater.'))]
'the host, whichever is greater.')),
cfg.StrOpt('server_keystone_endpoint_type',
choices=['', 'public', 'internal', 'admin'],
default='',
help=_('If set, is used to control which authentication '
'endpoint is used by user-controlled servers to make '
'calls back to Heat. '
'If unset www_authenticate_uri is used.'))]
engine_opts = [
cfg.ListOpt('plugin_dirs',

View File

@ -121,3 +121,6 @@ class FakeKeystoneClient(object):
def stack_domain_user_token(self, user_id, project_id, password):
return 'adomainusertoken'
def server_keystone_endpoint_url(self, fallback_endpoint):
return fallback_endpoint

View File

@ -563,6 +563,29 @@ class KsClientWrapper(object):
self._check_stack_domain_user(user_id, project_id, 'enable')
self.domain_admin_client.users.update(user=user_id, enabled=True)
def server_keystone_endpoint_url(self, fallback_endpoint):
ks_endpoint_type = cfg.CONF.server_keystone_endpoint_type
if ((ks_endpoint_type == 'public') or (
ks_endpoint_type == 'internal') or
(ks_endpoint_type == 'admin')):
if (hasattr(self.context, 'auth_plugin') and
hasattr(self.context.auth_plugin, 'get_access')):
try:
auth_ref = self.context.auth_plugin.get_access(
self.session)
if hasattr(auth_ref, "service_catalog"):
unversioned_sc_auth_uri = (
auth_ref.service_catalog.get_urls(
service_type='identity',
interface=ks_endpoint_type))
if len(unversioned_sc_auth_uri) > 0:
sc_auth_uri = (
unversioned_sc_auth_uri[0] + "/v3")
return sc_auth_uri
except ks_exception.Unauthorized:
LOG.error("Keystone client authentication failed")
return fallback_endpoint
class KeystoneClient(object):
"""Keystone Auth Client.

View File

@ -84,7 +84,8 @@ class BaseServer(stack_user.StackUser):
occ.update({'heat': {
'user_id': self._get_user_id(),
'password': self.password,
'auth_url': self.context.auth_url,
'auth_url': self.keystone().server_keystone_endpoint_url(
fallback_endpoint=self.context.auth_url),
'project_id': self.stack.stack_user_project_id,
'stack_id': self.stack.identifier().stack_path(),
'resource_name': self.name,
@ -96,7 +97,8 @@ class BaseServer(stack_user.StackUser):
occ.update({'zaqar': {
'user_id': self._get_user_id(),
'password': self.password,
'auth_url': self.context.auth_url,
'auth_url': self.keystone().server_keystone_endpoint_url(
fallback_endpoint=self.context.auth_url),
'project_id': self.stack.stack_user_project_id,
'queue_id': queue_id,
'region_name': region_name}})

View File

@ -103,7 +103,8 @@ class SignalResponder(stack_user.StackUser):
if self.password is None:
self.password = password_gen.generate_openstack_password()
self._create_user()
return {'auth_url': self.keystone().v3_endpoint,
return {'auth_url': self.keystone().server_keystone_endpoint_url(
fallback_endpoint=self.keystone().v3_endpoint),
'username': self.physical_resource_name(),
'user_id': self._get_user_id(),
'password': self.password,

View File

@ -1449,6 +1449,52 @@ class KeystoneClientTest(common.HeatTestCase):
self.assertIsNone(heat_ks_client.delete_stack_domain_project(
project_id='aprojectid'))
def test_server_keystone_endpoint_url_config(self):
"""Return non fallback url path."""
cfg.CONF.set_override('server_keystone_endpoint_type', 'public')
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
fallback_url = 'http://server.fallback.test:5000/v3'
auth_ref = heat_ks_client.context.auth_plugin.get_access(
heat_ks_client.session)
auth_ref.service_catalog.get_urls = mock.MagicMock()
auth_ref.service_catalog.get_urls.return_value = [
'http://server.public.test:5000']
self.assertEqual(
heat_ks_client.server_keystone_endpoint_url(fallback_url),
'http://server.public.test:5000/v3')
cfg.CONF.clear_override('server_keystone_endpoint_type')
def test_server_keystone_endpoint_url_no_config(self):
"""Return fallback as no config option specified."""
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
cfg.CONF.clear_override('server_keystone_endpoint_type')
fallback_url = 'http://server.fallback.test:5000/v3'
self.assertEqual(heat_ks_client.server_keystone_endpoint_url(
fallback_url), fallback_url)
def test_server_keystone_endpoint_url_auth_exception(self):
"""Authorization call fails, return fallback."""
cfg.CONF.set_override('server_keystone_endpoint_type', 'public')
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
auth_ref = heat_ks_client.context.auth_plugin.get_access(
heat_ks_client.session)
auth_ref.service_catalog.get_urls = mock.MagicMock()
auth_ref.service_catalog.get_urls.return_value = [
'http://server.public.test:5000']
heat_ks_client.context.auth_plugin.get_access = mock.MagicMock()
heat_ks_client.context.auth_plugin.get_access.side_effect = (
kc_exception.Unauthorized)
fallback_url = 'http://server.fallback.test:5000/v3'
self.assertEqual(heat_ks_client.server_keystone_endpoint_url(
fallback_url), fallback_url)
cfg.CONF.clear_override('server_keystone_endpoint_type')
class KeystoneClientTestDomainName(KeystoneClientTest):
def setUp(self):

View File

@ -0,0 +1,16 @@
---
features:
- |
Added a new config option server_keystone_endpoint_type to specify
the keystone authentication endpoint (public/internal/admin)
to pass into cloud-init data.
If left unset the original behavior should remain unchanged.
This feature allows the deployer to unambiguously specify the
keystone endpoint passed to user provisioned servers, and is particularly
useful where the deployment network architecture requires the heat
service to interact with the internal endpoint,
but user provisioned servers only have access to the external network.
For more information see
http://lists.openstack.org/pipermail/openstack-discuss/2019-February/002925.html