Files
nova/nova/api/openstack/identity.py
T
Sean Dague 4a2009a6fa Be more tolerant of keystone catalog configuration
The previous attempt at validating against keystone assumed that users
had an unversioned endpoint in their catalog. Most do not. This uses
the keystoneauth discovery magic to do the right thing whether or not
they have the versioned or unversioned endpoint, as long as they have
a working v3 installation.

It is also much more verbose on log messages when things go wrong.

Change-Id: I509d406ca1f1f7b064aaca88645ad17685827267
Related-Bug: #1667679
Closes-Bug: #1693228
2017-06-05 14:56:44 +00:00

78 lines
2.8 KiB
Python

# Copyright 2017 IBM
#
# 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 keystoneauth1 import exceptions as kse
from keystoneauth1 import session
from oslo_log import log as logging
import webob
from nova.i18n import _
LOG = logging.getLogger(__name__)
def verify_project_id(context, project_id):
"""verify that a project_id exists.
This attempts to verify that a project id exists. If it does not,
an HTTPBadRequest is emitted.
"""
sess = session.Session(auth=context.get_auth_plugin())
failure = webob.exc.HTTPBadRequest(
explanation=_("Project ID %s is not a valid project.") %
project_id)
try:
resp = sess.get('/projects/%s' % project_id,
endpoint_filter={
'service_type': 'identity',
'version': (3, 0)
},
raise_exc=False)
except kse.EndpointNotFound:
LOG.error(
"Keystone identity service version 3.0 was not found. This might "
"be because your endpoint points to the v2.0 versioned endpoint "
"which is not supported. Please fix this.")
raise failure
except kse.ClientException:
# something is wrong, like there isn't a keystone v3 endpoint,
# we'll take the pass and default to everything being ok.
LOG.exception("Unable to contact keystone to verify project_id")
return True
if resp:
# All is good with this 20x status
return True
elif resp.status_code == 404:
# we got access, and we know this project is not there
raise failure
elif resp.status_code == 403:
# we don't have enough permission to verify this, so default
# to "it's ok".
LOG.info(
"Insufficient permissions for user %(user)s to verify "
"existence of project_id %(pid)s",
{"user": context.user_id, "pid": project_id})
return True
else:
LOG.warning(
"Unexpected response from keystone trying to "
"verify project_id %(pid)s - resp: %(code)s %(content)s",
{"pid": project_id,
"code": resp.status_code,
"content": resp.content})
# realize we did something wrong, but move on with a warning
return True