deb-heat/heat/common/auth_url.py
Miguel Grinberg 487a211a8a Correctly determine keystone v3 endpoint
The auth_uri argument in the keystone_authtoken section of the
configuration can, depending on the authentication plugin in use,
specify the URL with or without a version. When a version is given,
it may be v2.0 or v3. And for some plugins this setting may not even be
used. To help reduce the coupling between heat and keystonemiddleware's
configuration, this change adds a new "auth_uri" setting in the
[clients_keystone] section of the configuration that can be used to define
the unversioned keystone endpoint that heat should use. The keystone
discovery service is used to obtain the v3 URL from this endpoint. If this
new configuration item isn't set, then the legacy behavior that derives
the v3 endpoint from the middleware's setting is used.

UpgradeImpact: heat.conf [clients_keystone] auth_uri should be set
               to the unversioned keystone endpoint for wait conditions
               and wait handles to continue working.
Change-Id: I57d9749bea0b5797a9fc786e8fe991bbc63301ef
Partial-Bug: #1446918
2015-08-12 21:00:04 +00:00

78 lines
2.7 KiB
Python

#
# Copyright 2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from keystoneclient import discover as ks_discover
from oslo_config import cfg
from oslo_utils import importutils
from webob import exc
from heat.common.i18n import _
from heat.common import wsgi
class AuthUrlFilter(wsgi.Middleware):
def __init__(self, app, conf):
super(AuthUrlFilter, self).__init__(app)
self.conf = conf
self.auth_url = self._get_auth_url()
def _get_auth_url(self):
if 'auth_uri' in self.conf:
return self.conf['auth_uri']
else:
# Look for the keystone auth_uri in the configuration. First we
# check the [clients_keystone] section, and if it is not set we
# look in [keystone_authtoken]
if cfg.CONF.clients_keystone.auth_uri:
discover = ks_discover.Discover(
auth_url=cfg.CONF.clients_keystone.auth_uri)
return discover.url_for('3.0')
else:
# Import auth_token to have keystone_authtoken settings setup.
auth_token_module = 'keystonemiddleware.auth_token'
importutils.import_module(auth_token_module)
return cfg.CONF.keystone_authtoken.auth_uri
def _validate_auth_url(self, auth_url):
"""Validate auth_url to ensure it can be used."""
if not auth_url:
raise exc.HTTPBadRequest(_('Request missing required header '
'X-Auth-Url'))
allowed = cfg.CONF.auth_password.allowed_auth_uris
if auth_url not in allowed:
raise exc.HTTPUnauthorized(_('Header X-Auth-Url "%s" not '
'an allowed endpoint') % auth_url)
return True
def process_request(self, req):
auth_url = self.auth_url
if cfg.CONF.auth_password.multi_cloud:
auth_url = req.headers.get('X-Auth-Url')
self._validate_auth_url(auth_url)
req.headers['X-Auth-Url'] = auth_url
return None
def filter_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
def auth_url_filter(app):
return AuthUrlFilter(app, conf)
return auth_url_filter